Skip to content

Commit 522e21a

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 522e21a

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

src/runtime/Types/ClassDerived.cs

Lines changed: 10 additions & 8 deletions
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
{
@@ -698,7 +699,7 @@ public class PythonDerivedType
698699
/// class) it calls it, otherwise it calls the base method.
699700
/// </summary>
700701
public static T? InvokeMethod<T>(IPythonDerivedType obj, string methodName, string origMethodName,
701-
object[] args, RuntimeMethodHandle methodHandle)
702+
object[] args, RuntimeMethodHandle methodHandle, RuntimeTypeHandle declaringTypeHandle)
702703
{
703704
var self = GetPyObj(obj);
704705

@@ -724,7 +725,8 @@ public class PythonDerivedType
724725
}
725726

726727
PyObject py_result = method.Invoke(pyargs);
727-
PyTuple? result_tuple = MarshalByRefsBack(args, methodHandle, py_result, outsOffset: 1);
728+
var clrMethod = MethodBase.GetMethodFromHandle(methodHandle, declaringTypeHandle);
729+
PyTuple? result_tuple = MarshalByRefsBack(args, clrMethod, py_result, outsOffset: 1);
728730
return result_tuple is not null
729731
? result_tuple[0].As<T>()
730732
: py_result.As<T>();
@@ -754,7 +756,7 @@ public class PythonDerivedType
754756
}
755757

756758
public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, string origMethodName,
757-
object?[] args, RuntimeMethodHandle methodHandle)
759+
object?[] args, RuntimeMethodHandle methodHandle, RuntimeTypeHandle declaringTypeHandle)
758760
{
759761
var self = GetPyObj(obj);
760762
if (null != self.Ref)
@@ -779,7 +781,8 @@ public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, s
779781
}
780782

781783
PyObject py_result = method.Invoke(pyargs);
782-
MarshalByRefsBack(args, methodHandle, py_result, outsOffset: 0);
784+
var clrMethod = MethodBase.GetMethodFromHandle(methodHandle, declaringTypeHandle);
785+
MarshalByRefsBack(args, clrMethod, py_result, outsOffset: 0);
783786
return;
784787
}
785788
}
@@ -811,12 +814,11 @@ public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, s
811814
/// as a tuple of new values for those arguments, and updates corresponding
812815
/// elements of <paramref name="args"/> array.
813816
/// </summary>
814-
private static PyTuple? MarshalByRefsBack(object?[] args, RuntimeMethodHandle methodHandle, PyObject pyResult, int outsOffset)
817+
private static PyTuple? MarshalByRefsBack(object?[] args, MethodBase? method, PyObject pyResult, int outsOffset)
815818
{
816-
if (methodHandle == default) return null;
819+
if (method is null) return null;
817820

818-
var originalMethod = MethodBase.GetMethodFromHandle(methodHandle);
819-
var parameters = originalMethod.GetParameters();
821+
var parameters = method.GetParameters();
820822
PyTuple? outs = null;
821823
int byrefIndex = 0;
822824
for (int i = 0; i < parameters.Length; ++i)

0 commit comments

Comments
 (0)