11using System ;
2- using System . Collections ;
32using System . Collections . Generic ;
43using System . Diagnostics ;
4+ using System . Linq ;
55using System . Runtime . InteropServices ;
6+ using Python . Runtime . Reflection ;
67using System . Reflection ;
7- using System . Text ;
88
99namespace Python . Runtime
1010{
@@ -120,110 +120,38 @@ public enum TypeFlags: int
120120
121121 internal class Interop
122122 {
123- private static Hashtable pmap ;
123+ static readonly Dictionary < MethodInfo , Type > delegateTypes = new ( ) ;
124124
125- static Interop ( )
125+ internal static Type GetPrototype ( MethodInfo method )
126126 {
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 ;
129129
130- Type [ ] items = typeof ( Interop ) . GetNestedTypes ( ) ;
131- Hashtable p = new Hashtable ( ) ;
130+ var parameters = method . GetParameters ( ) . Select ( p => new ParameterHelper ( p ) ) . ToArray ( ) ;
132131
133- for ( int i = 0 ; i < items . Length ; i ++ )
132+ foreach ( var candidate in typeof ( Interop ) . GetNestedTypes ( ) )
134133 {
135- Type item = items [ i ] ;
136- p [ item . Name ] = item ;
137- }
134+ if ( ! typeof ( Delegate ) . IsAssignableFrom ( candidate ) )
135+ continue ;
138136
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 ;
223141
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 ( ) ) ;
227155 }
228156
229157
@@ -235,7 +163,7 @@ internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null)
235163 if ( funcType != null )
236164 dt = typeof ( Interop ) . GetNestedType ( funcType ) as Type ;
237165 else
238- dt = GetPrototype ( method . Name ) ;
166+ dt = GetPrototype ( method ) ;
239167
240168 if ( dt == null )
241169 {
@@ -252,53 +180,38 @@ internal static ThunkInfo GetThunk(Delegate @delegate)
252180 return info ;
253181 }
254182
255-
256- [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
257- public delegate IntPtr UnaryFunc ( IntPtr ob ) ;
258-
259183 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
260- public delegate IntPtr BinaryFunc ( IntPtr ob , IntPtr arg ) ;
184+ public delegate NewReference B_N ( BorrowedReference ob ) ;
261185
262186 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
263- public delegate IntPtr TernaryFunc ( IntPtr ob , IntPtr a1 , IntPtr a2 ) ;
187+ public delegate NewReference BB_N ( BorrowedReference ob , BorrowedReference a ) ;
264188
265189 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
266190 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 ) ;
275191
276192 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
277- public delegate IntPtr IntIntArgFunc ( IntPtr ob , int a1 , int a2 ) ;
193+ public delegate int B_I32 ( BorrowedReference ob ) ;
278194
279195 [ 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 ) ;
284197
285198 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
286- public delegate int ObjObjArgFunc ( IntPtr o , IntPtr a , IntPtr b ) ;
199+ public delegate int BP_I32 ( BorrowedReference ob , IntPtr arg ) ;
287200
288201 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
289- public delegate int ObjObjFunc ( IntPtr ob , IntPtr arg ) ;
202+ public delegate IntPtr B_P ( BorrowedReference ob ) ;
290203
291204 [ 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 ) ;
293206
294207 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
295- public delegate void DestructorFunc ( IntPtr ob ) ;
208+ public delegate NewReference BP_N ( BorrowedReference ob , IntPtr arg ) ;
296209
297210 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
298- public delegate int PrintFunc ( IntPtr ob , IntPtr a , int b ) ;
211+ public delegate void N_V ( NewReference ob ) ;
299212
300213 [ 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 ) ;
302215 }
303216
304217
0 commit comments