Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5c1e02f

Browse files
committed
fixed resolution of generic methods in Python implementations
since RuntimeMethodHandle does not encode generic arguments, I had to supply RuntimeTypeHandle of the declaring type to be able to get fully specified method
1 parent 461c9c7 commit 5c1e02f

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

src/runtime/Types/ClassDerived.cs

+20-8
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ private static void AddVirtualMethod(MethodInfo method, Type baseType, TypeBuild
436436
il.Emit(OpCodes.Ldloc_0);
437437

438438
il.Emit(OpCodes.Ldtoken, method);
439+
il.Emit(OpCodes.Ldtoken, method.DeclaringType);
439440
#pragma warning disable CS0618 // PythonDerivedType is for internal use only
440441
if (method.ReturnType == typeof(void))
441442
{
@@ -505,6 +506,7 @@ private static void AddPythonMethod(string methodName, PyObject func, TypeBuilde
505506

506507
il.DeclareLocal(typeof(object[]));
507508
il.DeclareLocal(typeof(RuntimeMethodHandle));
509+
il.DeclareLocal(typeof(RuntimeTypeHandle));
508510

509511
// this
510512
il.Emit(OpCodes.Ldarg_0);
@@ -546,6 +548,11 @@ private static void AddPythonMethod(string methodName, PyObject func, TypeBuilde
546548
il.Emit(OpCodes.Ldloca_S, 1);
547549
il.Emit(OpCodes.Initobj, typeof(RuntimeMethodHandle));
548550
il.Emit(OpCodes.Ldloc_1);
551+
552+
// type handle is also not required
553+
il.Emit(OpCodes.Ldloca_S, 2);
554+
il.Emit(OpCodes.Initobj, typeof(RuntimeTypeHandle));
555+
il.Emit(OpCodes.Ldloc_2);
549556
#pragma warning disable CS0618 // PythonDerivedType is for internal use only
550557

551558
// invoke the method
@@ -698,7 +705,7 @@ public class PythonDerivedType
698705
/// class) it calls it, otherwise it calls the base method.
699706
/// </summary>
700707
public static T? InvokeMethod<T>(IPythonDerivedType obj, string methodName, string origMethodName,
701-
object[] args, RuntimeMethodHandle methodHandle)
708+
object[] args, RuntimeMethodHandle methodHandle, RuntimeTypeHandle declaringTypeHandle)
702709
{
703710
var self = GetPyObj(obj);
704711

@@ -724,7 +731,10 @@ public class PythonDerivedType
724731
}
725732

726733
PyObject py_result = method.Invoke(pyargs);
727-
PyTuple? result_tuple = MarshalByRefsBack(args, methodHandle, py_result, outsOffset: 1);
734+
var clrMethod = methodHandle != default
735+
? MethodBase.GetMethodFromHandle(methodHandle, declaringTypeHandle)
736+
: null;
737+
PyTuple? result_tuple = MarshalByRefsBack(args, clrMethod, py_result, outsOffset: 1);
728738
return result_tuple is not null
729739
? result_tuple[0].As<T>()
730740
: py_result.As<T>();
@@ -754,7 +764,7 @@ public class PythonDerivedType
754764
}
755765

756766
public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, string origMethodName,
757-
object?[] args, RuntimeMethodHandle methodHandle)
767+
object?[] args, RuntimeMethodHandle methodHandle, RuntimeTypeHandle declaringTypeHandle)
758768
{
759769
var self = GetPyObj(obj);
760770
if (null != self.Ref)
@@ -779,7 +789,10 @@ public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, s
779789
}
780790

781791
PyObject py_result = method.Invoke(pyargs);
782-
MarshalByRefsBack(args, methodHandle, py_result, outsOffset: 0);
792+
var clrMethod = methodHandle != default
793+
? MethodBase.GetMethodFromHandle(methodHandle, declaringTypeHandle)
794+
: null;
795+
MarshalByRefsBack(args, clrMethod, py_result, outsOffset: 0);
783796
return;
784797
}
785798
}
@@ -811,12 +824,11 @@ public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, s
811824
/// as a tuple of new values for those arguments, and updates corresponding
812825
/// elements of <paramref name="args"/> array.
813826
/// </summary>
814-
private static PyTuple? MarshalByRefsBack(object?[] args, RuntimeMethodHandle methodHandle, PyObject pyResult, int outsOffset)
827+
private static PyTuple? MarshalByRefsBack(object?[] args, MethodBase? method, PyObject pyResult, int outsOffset)
815828
{
816-
if (methodHandle == default) return null;
829+
if (method is null) return null;
817830

818-
var originalMethod = MethodBase.GetMethodFromHandle(methodHandle);
819-
var parameters = originalMethod.GetParameters();
831+
var parameters = method.GetParameters();
820832
PyTuple? outs = null;
821833
int byrefIndex = 0;
822834
for (int i = 0; i < parameters.Length; ++i)

0 commit comments

Comments
 (0)