diff --git a/src/runtime/methodbinder.cs b/src/runtime/methodbinder.cs index d63f53f1e..8760ad26f 100644 --- a/src/runtime/methodbinder.cs +++ b/src/runtime/methodbinder.cs @@ -50,7 +50,10 @@ internal void AddMethod(MethodBase m) { //==================================================================== internal static MethodInfo MatchSignature(MethodInfo[] mi, Type[] tp) { - int count = tp.Length; + if (tp == null) { + return null; + } + int count = tp.Length; for (int i = 0; i < mi.Length; i++) { ParameterInfo[] pi = mi[i].GetParameters(); if (pi.Length != count) { @@ -92,51 +95,54 @@ internal static MethodInfo MatchParameters(MethodInfo[] mi, Type[] tp) { } - //==================================================================== - // Given a sequence of MethodInfo and two sequences of type parameters, - // return the MethodInfo that matches the signature and the closed generic. - //==================================================================== - - internal static MethodInfo MatchSignatureAndParameters(MethodInfo[] mi, Type[] genericTp, Type[] sigTp) - { - int genericCount = genericTp.Length; - int signatureCount = sigTp.Length; - for (int i = 0; i < mi.Length; i++) - { - if (!mi[i].IsGenericMethodDefinition) - { - continue; - } - Type[] genericArgs = mi[i].GetGenericArguments(); - if (genericArgs.Length != genericCount) - { - continue; - } - ParameterInfo[] pi = mi[i].GetParameters(); - if (pi.Length != signatureCount) - { - continue; - } - for (int n = 0; n < pi.Length; n++) - { - if (sigTp[n] != pi[n].ParameterType) - { - break; - } - if (n == (pi.Length - 1)) - { - MethodInfo match = mi[i]; - if (match.IsGenericMethodDefinition) - { - Type[] typeArgs = match.GetGenericArguments(); - return match.MakeGenericMethod(genericTp); - } - return match; - } - } - } - return null; - } + //==================================================================== + // Given a sequence of MethodInfo and two sequences of type parameters, + // return the MethodInfo that matches the signature and the closed generic. + //==================================================================== + + internal static MethodInfo MatchSignatureAndParameters(MethodInfo[] mi, Type[] genericTp, Type[] sigTp) + { + if ((genericTp == null) || (sigTp == null)) { + return null; + } + int genericCount = genericTp.Length; + int signatureCount = sigTp.Length; + for (int i = 0; i < mi.Length; i++) + { + if (!mi[i].IsGenericMethodDefinition) + { + continue; + } + Type[] genericArgs = mi[i].GetGenericArguments(); + if (genericArgs.Length != genericCount) + { + continue; + } + ParameterInfo[] pi = mi[i].GetParameters(); + if (pi.Length != signatureCount) + { + continue; + } + for (int n = 0; n < pi.Length; n++) + { + if (sigTp[n] != pi[n].ParameterType) + { + break; + } + if (n == (pi.Length - 1)) + { + MethodInfo match = mi[i]; + if (match.IsGenericMethodDefinition) + { + Type[] typeArgs = match.GetGenericArguments(); + return match.MakeGenericMethod(genericTp); + } + return match; + } + } + } + return null; + } //==================================================================== @@ -239,9 +245,10 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, else { _methods = GetMethods(); } - + Type type; for (int i = 0; i < _methods.Length; i++) { MethodBase mi = _methods[i]; + if (mi.IsGenericMethod) { isGeneric = true; } ParameterInfo[] pi = mi.GetParameters(); int clrnargs = pi.Length; @@ -275,19 +282,41 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, for (int n = 0; n < clrnargs; n++) { IntPtr op; - if (n < pynargs) - { - if (arrayStart == n) - { + if (n < pynargs) { + if (arrayStart == n) { // map remaining Python arguments to a tuple since // the managed function accepts it - hopefully :] op = Runtime.PyTuple_GetSlice(args, arrayStart, pynargs); } - else - { + else { op = Runtime.PyTuple_GetItem(args, n); } - Type type = pi[n].ParameterType; + + // this logic below handles cases when multiple overloading methods + // are ambiguous, hence comparison between Python and CLR types + // is necessary + type = null; + + if (_methods.Length>1) { + IntPtr pyoptype = IntPtr.Zero; + pyoptype = Runtime.PyObject_Type(op); + Exceptions.Clear(); + if (pyoptype != IntPtr.Zero) { } + type = Converter.GetTypeByAlias(pyoptype); + Runtime.Decref(pyoptype); + } + + + if (type != null) { + if (pi[n].ParameterType != type) { + margs = null; + break; + } + } + else { + type = pi[n].ParameterType; + } + if (pi[n].IsOut || type.IsByRef) { outs++; @@ -348,7 +377,7 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodInfo mi = MethodBinder.MatchParameters(methodinfo, types); return Bind(inst, args, kw, mi, null); } - return null; + return null; } internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) {