1+ #nullable enable
12using System ;
23using System . Collections . Generic ;
34using System . Linq ;
45using System . Reflection ;
56using System . Reflection . Emit ;
67using System . Text ;
78
9+ using Python . Runtime . Native ;
10+
811namespace Python . Runtime
912{
1013 /// <summary>
@@ -18,7 +21,7 @@ internal class DelegateManager
1821 private readonly Type arrayType = typeof ( object [ ] ) ;
1922 private readonly Type voidtype = typeof ( void ) ;
2023 private readonly Type typetype = typeof ( Type ) ;
21- private readonly Type ptrtype = typeof ( IntPtr ) ;
24+ private readonly Type pyobjType = typeof ( PyObject ) ;
2225 private readonly CodeGenerator codeGenerator = new CodeGenerator ( ) ;
2326 private readonly ConstructorInfo arrayCtor ;
2427 private readonly MethodInfo dispatch ;
@@ -59,7 +62,7 @@ private Type GetDispatcher(Type dtype)
5962 MethodAttributes . SpecialName |
6063 MethodAttributes . RTSpecialName ;
6164 var cc = CallingConventions . Standard ;
62- Type [ ] args = { ptrtype , typetype } ;
65+ Type [ ] args = { pyobjType , typetype } ;
6366 ConstructorBuilder cb = tb . DefineConstructor ( ma , cc , args ) ;
6467 ConstructorInfo ci = basetype . GetConstructor ( BindingFlags . Instance | BindingFlags . NonPublic , null , args , null ) ;
6568 ILGenerator il = cb . GetILGenerator ( ) ;
@@ -178,7 +181,7 @@ private Type GetDispatcher(Type dtype)
178181 /// returns an instance of the delegate type. The delegate instance
179182 /// returned will dispatch calls to the given Python object.
180183 /// </summary>
181- internal Delegate GetDelegate ( Type dtype , IntPtr callable )
184+ internal Delegate GetDelegate ( Type dtype , PyObject callable )
182185 {
183186 Type dispatcher = GetDispatcher ( dtype ) ;
184187 object [ ] args = { callable , dtype } ;
@@ -212,64 +215,58 @@ public class Dispatcher
212215 readonly PyObject target ;
213216 readonly Type dtype ;
214217
215- protected Dispatcher ( IntPtr target , Type dtype )
218+ protected Dispatcher ( PyObject target , Type dtype )
216219 {
217- this . target = new PyObject ( new BorrowedReference ( target ) ) ;
220+ this . target = target ;
218221 this . dtype = dtype ;
219222 }
220223
221- public object Dispatch ( object [ ] args )
224+ public object ? Dispatch ( object ? [ ] args )
222225 {
223- IntPtr gs = PythonEngine . AcquireLock ( ) ;
224- object ob ;
226+ PyGILState gs = PythonEngine . AcquireLock ( ) ;
225227
226228 try
227229 {
228- ob = TrueDispatch ( args ) ;
230+ return TrueDispatch ( args ) ;
229231 }
230232 finally
231233 {
232234 PythonEngine . ReleaseLock ( gs ) ;
233235 }
234-
235- return ob ;
236236 }
237237
238- private object TrueDispatch ( object [ ] args )
238+ private object ? TrueDispatch ( object ? [ ] args )
239239 {
240240 MethodInfo method = dtype . GetMethod ( "Invoke" ) ;
241241 ParameterInfo [ ] pi = method . GetParameters ( ) ;
242242 Type rtype = method . ReturnType ;
243243
244- NewReference op ;
245- using ( var pyargs = NewReference . DangerousFromPointer ( Runtime . PyTuple_New ( pi . Length ) ) )
244+ NewReference callResult ;
245+ using ( var pyargs = Runtime . PyTuple_New ( pi . Length ) )
246246 {
247247 for ( var i = 0 ; i < pi . Length ; i ++ )
248248 {
249249 // Here we own the reference to the Python value, and we
250250 // give the ownership to the arg tuple.
251- var arg = Converter . ToPython ( args [ i ] , pi [ i ] . ParameterType ) ;
252- if ( arg . IsNull ( ) )
253- {
254- throw PythonException . ThrowLastAsClrException ( ) ;
255- }
256- int res = Runtime . PyTuple_SetItem ( pyargs , i , arg . Steal ( ) ) ;
251+ using var arg = Converter . ToPython ( args [ i ] , pi [ i ] . ParameterType ) ;
252+ int res = Runtime . PyTuple_SetItem ( pyargs . Borrow ( ) , i , arg . StealOrThrow ( ) ) ;
257253 if ( res != 0 )
258254 {
259255 throw PythonException . ThrowLastAsClrException ( ) ;
260256 }
261257 }
262258
263- op = Runtime . PyObject_Call ( target . Reference , pyargs , BorrowedReference . Null ) ;
259+ callResult = Runtime . PyObject_Call ( target , pyargs . Borrow ( ) , null ) ;
264260 }
265261
266- if ( op . IsNull ( ) )
262+ if ( callResult . IsNull ( ) )
267263 {
268264 throw PythonException . ThrowLastAsClrException ( ) ;
269265 }
270266
271- using ( op )
267+ using ( callResult )
272268 {
269+ BorrowedReference op = callResult . Borrow ( ) ;
273270 int byRefCount = pi . Count ( parameterInfo => parameterInfo . ParameterType . IsByRef ) ;
274271 if ( byRefCount > 0 )
275272 {
@@ -289,12 +286,11 @@ private object TrueDispatch(object[] args)
289286 Type t = pi [ i ] . ParameterType ;
290287 if ( t . IsByRef )
291288 {
292- if ( ! Converter . ToManaged ( op , t , out object newArg , true ) )
289+ if ( ! Converter . ToManaged ( op , t , out args [ i ] , true ) )
293290 {
294291 Exceptions . RaiseTypeError ( $ "The Python function did not return { t . GetElementType ( ) } (the out parameter type)") ;
295292 throw PythonException . ThrowLastAsClrException ( ) ;
296293 }
297- args [ i ] = newArg ;
298294 break ;
299295 }
300296 }
@@ -309,20 +305,19 @@ private object TrueDispatch(object[] args)
309305 if ( t . IsByRef )
310306 {
311307 BorrowedReference item = Runtime . PyTuple_GetItem ( op , index ++ ) ;
312- if ( ! Converter . ToManaged ( item , t , out object newArg , true ) )
308+ if ( ! Converter . ToManaged ( item , t , out args [ i ] , true ) )
313309 {
314310 Exceptions . RaiseTypeError ( $ "The Python function returned a tuple where element { i } was not { t . GetElementType ( ) } (the out parameter type)") ;
315311 throw PythonException . ThrowLastAsClrException ( ) ;
316312 }
317- args [ i ] = newArg ;
318313 }
319314 }
320315 if ( isVoid )
321316 {
322317 return null ;
323318 }
324319 BorrowedReference item0 = Runtime . PyTuple_GetItem ( op , 0 ) ;
325- if ( ! Converter . ToManaged ( item0 , rtype , out object result0 , true ) )
320+ if ( ! Converter . ToManaged ( item0 , rtype , out object ? result0 , true ) )
326321 {
327322 Exceptions . RaiseTypeError ( $ "The Python function returned a tuple where element 0 was not { rtype } (the return type)") ;
328323 throw PythonException . ThrowLastAsClrException ( ) ;
@@ -358,8 +353,7 @@ private object TrueDispatch(object[] args)
358353 return null ;
359354 }
360355
361- object result ;
362- if ( ! Converter . ToManaged ( op , rtype , out result , true ) )
356+ if ( ! Converter . ToManaged ( op , rtype , out object ? result , true ) )
363357 {
364358 throw PythonException . ThrowLastAsClrException ( ) ;
365359 }
0 commit comments