1
1
using System ;
2
- using System . Collections ;
3
2
using System . Collections . Generic ;
4
3
using System . Diagnostics ;
4
+ using System . Linq ;
5
5
using System . Runtime . InteropServices ;
6
+ using Python . Runtime . Reflection ;
6
7
using System . Reflection ;
7
- using System . Text ;
8
8
9
9
namespace Python . Runtime
10
10
{
@@ -120,110 +120,38 @@ public enum TypeFlags: int
120
120
121
121
internal class Interop
122
122
{
123
- private static Hashtable pmap ;
123
+ static readonly Dictionary < MethodInfo , Type > delegateTypes = new ( ) ;
124
124
125
- static Interop ( )
125
+ internal static Type GetPrototype ( MethodInfo method )
126
126
{
127
- // Here we build a mapping of PyTypeObject slot names to the
128
- // appropriate prototype (delegate) type to use for the slot.
127
+ if ( delegateTypes . TryGetValue ( method , out var delegateType ) )
128
+ return delegateType ;
129
129
130
- Type [ ] items = typeof ( Interop ) . GetNestedTypes ( ) ;
131
- Hashtable p = new Hashtable ( ) ;
130
+ var parameters = method . GetParameters ( ) . Select ( p => new ParameterHelper ( p ) ) . ToArray ( ) ;
132
131
133
- for ( int i = 0 ; i < items . Length ; i ++ )
132
+ foreach ( var candidate in typeof ( Interop ) . GetNestedTypes ( ) )
134
133
{
135
- Type item = items [ i ] ;
136
- p [ item . Name ] = item ;
137
- }
134
+ if ( ! typeof ( Delegate ) . IsAssignableFrom ( candidate ) )
135
+ continue ;
138
136
139
- pmap = new Hashtable ( ) ;
140
-
141
- pmap [ "tp_dealloc" ] = p [ "DestructorFunc" ] ;
142
- pmap [ "tp_print" ] = p [ "PrintFunc" ] ;
143
- pmap [ "tp_getattr" ] = p [ "BinaryFunc" ] ;
144
- pmap [ "tp_setattr" ] = p [ "ObjObjArgFunc" ] ;
145
- pmap [ "tp_compare" ] = p [ "ObjObjFunc" ] ;
146
- pmap [ "tp_repr" ] = p [ "UnaryFunc" ] ;
147
- pmap [ "tp_hash" ] = p [ "UnaryFunc" ] ;
148
- pmap [ "tp_call" ] = p [ "TernaryFunc" ] ;
149
- pmap [ "tp_str" ] = p [ "UnaryFunc" ] ;
150
- pmap [ "tp_getattro" ] = p [ "BinaryFunc" ] ;
151
- pmap [ "tp_setattro" ] = p [ "ObjObjArgFunc" ] ;
152
- pmap [ "tp_traverse" ] = p [ "ObjObjArgFunc" ] ;
153
- pmap [ "tp_clear" ] = p [ "InquiryFunc" ] ;
154
- pmap [ "tp_richcompare" ] = p [ "RichCmpFunc" ] ;
155
- pmap [ "tp_iter" ] = p [ "UnaryFunc" ] ;
156
- pmap [ "tp_iternext" ] = p [ "UnaryFunc" ] ;
157
- pmap [ "tp_descr_get" ] = p [ "TernaryFunc" ] ;
158
- pmap [ "tp_descr_set" ] = p [ "ObjObjArgFunc" ] ;
159
- pmap [ "tp_init" ] = p [ "ObjObjArgFunc" ] ;
160
- pmap [ "tp_alloc" ] = p [ "IntArgFunc" ] ;
161
- pmap [ "tp_new" ] = p [ "TernaryFunc" ] ;
162
- pmap [ "tp_free" ] = p [ "DestructorFunc" ] ;
163
- pmap [ "tp_is_gc" ] = p [ "InquiryFunc" ] ;
164
-
165
- pmap [ "nb_add" ] = p [ "BinaryFunc" ] ;
166
- pmap [ "nb_subtract" ] = p [ "BinaryFunc" ] ;
167
- pmap [ "nb_multiply" ] = p [ "BinaryFunc" ] ;
168
- pmap [ "nb_remainder" ] = p [ "BinaryFunc" ] ;
169
- pmap [ "nb_divmod" ] = p [ "BinaryFunc" ] ;
170
- pmap [ "nb_power" ] = p [ "TernaryFunc" ] ;
171
- pmap [ "nb_negative" ] = p [ "UnaryFunc" ] ;
172
- pmap [ "nb_positive" ] = p [ "UnaryFunc" ] ;
173
- pmap [ "nb_absolute" ] = p [ "UnaryFunc" ] ;
174
- pmap [ "nb_nonzero" ] = p [ "InquiryFunc" ] ;
175
- pmap [ "nb_invert" ] = p [ "UnaryFunc" ] ;
176
- pmap [ "nb_lshift" ] = p [ "BinaryFunc" ] ;
177
- pmap [ "nb_rshift" ] = p [ "BinaryFunc" ] ;
178
- pmap [ "nb_and" ] = p [ "BinaryFunc" ] ;
179
- pmap [ "nb_xor" ] = p [ "BinaryFunc" ] ;
180
- pmap [ "nb_or" ] = p [ "BinaryFunc" ] ;
181
- pmap [ "nb_coerce" ] = p [ "ObjObjFunc" ] ;
182
- pmap [ "nb_int" ] = p [ "UnaryFunc" ] ;
183
- pmap [ "nb_long" ] = p [ "UnaryFunc" ] ;
184
- pmap [ "nb_float" ] = p [ "UnaryFunc" ] ;
185
- pmap [ "nb_oct" ] = p [ "UnaryFunc" ] ;
186
- pmap [ "nb_hex" ] = p [ "UnaryFunc" ] ;
187
- pmap [ "nb_inplace_add" ] = p [ "BinaryFunc" ] ;
188
- pmap [ "nb_inplace_subtract" ] = p [ "BinaryFunc" ] ;
189
- pmap [ "nb_inplace_multiply" ] = p [ "BinaryFunc" ] ;
190
- pmap [ "nb_inplace_remainder" ] = p [ "BinaryFunc" ] ;
191
- pmap [ "nb_inplace_power" ] = p [ "TernaryFunc" ] ;
192
- pmap [ "nb_inplace_lshift" ] = p [ "BinaryFunc" ] ;
193
- pmap [ "nb_inplace_rshift" ] = p [ "BinaryFunc" ] ;
194
- pmap [ "nb_inplace_and" ] = p [ "BinaryFunc" ] ;
195
- pmap [ "nb_inplace_xor" ] = p [ "BinaryFunc" ] ;
196
- pmap [ "nb_inplace_or" ] = p [ "BinaryFunc" ] ;
197
- pmap [ "nb_floor_divide" ] = p [ "BinaryFunc" ] ;
198
- pmap [ "nb_true_divide" ] = p [ "BinaryFunc" ] ;
199
- pmap [ "nb_inplace_floor_divide" ] = p [ "BinaryFunc" ] ;
200
- pmap [ "nb_inplace_true_divide" ] = p [ "BinaryFunc" ] ;
201
- pmap [ "nb_index" ] = p [ "UnaryFunc" ] ;
202
-
203
- pmap [ "sq_length" ] = p [ "InquiryFunc" ] ;
204
- pmap [ "sq_concat" ] = p [ "BinaryFunc" ] ;
205
- pmap [ "sq_repeat" ] = p [ "IntArgFunc" ] ;
206
- pmap [ "sq_item" ] = p [ "IntArgFunc" ] ;
207
- pmap [ "sq_slice" ] = p [ "IntIntArgFunc" ] ;
208
- pmap [ "sq_ass_item" ] = p [ "IntObjArgFunc" ] ;
209
- pmap [ "sq_ass_slice" ] = p [ "IntIntObjArgFunc" ] ;
210
- pmap [ "sq_contains" ] = p [ "ObjObjFunc" ] ;
211
- pmap [ "sq_inplace_concat" ] = p [ "BinaryFunc" ] ;
212
- pmap [ "sq_inplace_repeat" ] = p [ "IntArgFunc" ] ;
213
-
214
- pmap [ "mp_length" ] = p [ "InquiryFunc" ] ;
215
- pmap [ "mp_subscript" ] = p [ "BinaryFunc" ] ;
216
- pmap [ "mp_ass_subscript" ] = p [ "ObjObjArgFunc" ] ;
217
-
218
- pmap [ "bf_getreadbuffer" ] = p [ "IntObjArgFunc" ] ;
219
- pmap [ "bf_getwritebuffer" ] = p [ "IntObjArgFunc" ] ;
220
- pmap [ "bf_getsegcount" ] = p [ "ObjObjFunc" ] ;
221
- pmap [ "bf_getcharbuffer" ] = p [ "IntObjArgFunc" ] ;
222
- }
137
+ MethodInfo invoke = candidate . GetMethod ( "Invoke" ) ;
138
+ var candiateParameters = invoke . GetParameters ( ) ;
139
+ if ( candiateParameters . Length != parameters . Length )
140
+ continue ;
223
141
224
- internal static Type GetPrototype ( string name )
225
- {
226
- return pmap [ name ] as Type ;
142
+ var parametersMatch = parameters . Zip ( candiateParameters ,
143
+ ( expected , actual ) => expected . Matches ( actual ) )
144
+ . All ( matches => matches ) ;
145
+
146
+ if ( ! parametersMatch ) continue ;
147
+
148
+ if ( invoke . ReturnType != method . ReturnType ) continue ;
149
+
150
+ delegateTypes . Add ( method , candidate ) ;
151
+ return candidate ;
152
+ }
153
+
154
+ throw new NotImplementedException ( method . ToString ( ) ) ;
227
155
}
228
156
229
157
@@ -235,7 +163,7 @@ internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null)
235
163
if ( funcType != null )
236
164
dt = typeof ( Interop ) . GetNestedType ( funcType ) as Type ;
237
165
else
238
- dt = GetPrototype ( method . Name ) ;
166
+ dt = GetPrototype ( method ) ;
239
167
240
168
if ( dt == null )
241
169
{
@@ -252,53 +180,38 @@ internal static ThunkInfo GetThunk(Delegate @delegate)
252
180
return info ;
253
181
}
254
182
255
-
256
- [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
257
- public delegate IntPtr UnaryFunc ( IntPtr ob ) ;
258
-
259
183
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
260
- public delegate IntPtr BinaryFunc ( IntPtr ob , IntPtr arg ) ;
184
+ public delegate NewReference B_N ( BorrowedReference ob ) ;
261
185
262
186
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
263
- public delegate IntPtr TernaryFunc ( IntPtr ob , IntPtr a1 , IntPtr a2 ) ;
187
+ public delegate NewReference BB_N ( BorrowedReference ob , BorrowedReference a ) ;
264
188
265
189
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
266
190
public delegate NewReference BBB_N ( BorrowedReference ob , BorrowedReference a1 , BorrowedReference a2 ) ;
267
- [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
268
- public delegate int BBB_I32 ( BorrowedReference ob , BorrowedReference a1 , BorrowedReference a2 ) ;
269
-
270
- [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
271
- public delegate int InquiryFunc ( IntPtr ob ) ;
272
-
273
- [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
274
- public delegate IntPtr IntArgFunc ( IntPtr ob , int arg ) ;
275
191
276
192
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
277
- public delegate IntPtr IntIntArgFunc ( IntPtr ob , int a1 , int a2 ) ;
193
+ public delegate int B_I32 ( BorrowedReference ob ) ;
278
194
279
195
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
280
- public delegate int IntObjArgFunc ( IntPtr ob , int a1 , IntPtr a2 ) ;
281
-
282
- [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
283
- public delegate int IntIntObjArgFunc ( IntPtr o , int a , int b , IntPtr c ) ;
196
+ public delegate int BBB_I32 ( BorrowedReference ob , BorrowedReference a1 , BorrowedReference a2 ) ;
284
197
285
198
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
286
- public delegate int ObjObjArgFunc ( IntPtr o , IntPtr a , IntPtr b ) ;
199
+ public delegate int BP_I32 ( BorrowedReference ob , IntPtr arg ) ;
287
200
288
201
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
289
- public delegate int ObjObjFunc ( IntPtr ob , IntPtr arg ) ;
202
+ public delegate IntPtr B_P ( BorrowedReference ob ) ;
290
203
291
204
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
292
- public delegate int BP_I32 ( BorrowedReference ob , IntPtr arg ) ;
205
+ public delegate NewReference BBI32_N ( BorrowedReference ob , BorrowedReference a1 , int a2 ) ;
293
206
294
207
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
295
- public delegate void DestructorFunc ( IntPtr ob ) ;
208
+ public delegate NewReference BP_N ( BorrowedReference ob , IntPtr arg ) ;
296
209
297
210
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
298
- public delegate int PrintFunc ( IntPtr ob , IntPtr a , int b ) ;
211
+ public delegate void N_V ( NewReference ob ) ;
299
212
300
213
[ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
301
- public delegate IntPtr RichCmpFunc ( IntPtr ob , IntPtr a , int b ) ;
214
+ public delegate int BPP_I32 ( BorrowedReference ob , IntPtr a1 , IntPtr a2 ) ;
302
215
}
303
216
304
217
0 commit comments