Skip to content

Commit 8386aa0

Browse files
denfromufatonyroberts
denfromufa
authored andcommitted
Fix bug where the wrong overload is selected.
Fixes #131.
1 parent 53bca1a commit 8386aa0

File tree

1 file changed

+84
-55
lines changed

1 file changed

+84
-55
lines changed

src/runtime/methodbinder.cs

Lines changed: 84 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ internal void AddMethod(MethodBase m) {
5050
//====================================================================
5151

5252
internal static MethodInfo MatchSignature(MethodInfo[] mi, Type[] tp) {
53-
int count = tp.Length;
53+
if (tp == null) {
54+
return null;
55+
}
56+
int count = tp.Length;
5457
for (int i = 0; i < mi.Length; i++) {
5558
ParameterInfo[] pi = mi[i].GetParameters();
5659
if (pi.Length != count) {
@@ -92,51 +95,54 @@ internal static MethodInfo MatchParameters(MethodInfo[] mi, Type[] tp) {
9295
}
9396

9497

95-
//====================================================================
96-
// Given a sequence of MethodInfo and two sequences of type parameters,
97-
// return the MethodInfo that matches the signature and the closed generic.
98-
//====================================================================
99-
100-
internal static MethodInfo MatchSignatureAndParameters(MethodInfo[] mi, Type[] genericTp, Type[] sigTp)
101-
{
102-
int genericCount = genericTp.Length;
103-
int signatureCount = sigTp.Length;
104-
for (int i = 0; i < mi.Length; i++)
105-
{
106-
if (!mi[i].IsGenericMethodDefinition)
107-
{
108-
continue;
109-
}
110-
Type[] genericArgs = mi[i].GetGenericArguments();
111-
if (genericArgs.Length != genericCount)
112-
{
113-
continue;
114-
}
115-
ParameterInfo[] pi = mi[i].GetParameters();
116-
if (pi.Length != signatureCount)
117-
{
118-
continue;
119-
}
120-
for (int n = 0; n < pi.Length; n++)
121-
{
122-
if (sigTp[n] != pi[n].ParameterType)
123-
{
124-
break;
125-
}
126-
if (n == (pi.Length - 1))
127-
{
128-
MethodInfo match = mi[i];
129-
if (match.IsGenericMethodDefinition)
130-
{
131-
Type[] typeArgs = match.GetGenericArguments();
132-
return match.MakeGenericMethod(genericTp);
133-
}
134-
return match;
135-
}
136-
}
137-
}
138-
return null;
139-
}
98+
//====================================================================
99+
// Given a sequence of MethodInfo and two sequences of type parameters,
100+
// return the MethodInfo that matches the signature and the closed generic.
101+
//====================================================================
102+
103+
internal static MethodInfo MatchSignatureAndParameters(MethodInfo[] mi, Type[] genericTp, Type[] sigTp)
104+
{
105+
if ((genericTp == null) || (sigTp == null)) {
106+
return null;
107+
}
108+
int genericCount = genericTp.Length;
109+
int signatureCount = sigTp.Length;
110+
for (int i = 0; i < mi.Length; i++)
111+
{
112+
if (!mi[i].IsGenericMethodDefinition)
113+
{
114+
continue;
115+
}
116+
Type[] genericArgs = mi[i].GetGenericArguments();
117+
if (genericArgs.Length != genericCount)
118+
{
119+
continue;
120+
}
121+
ParameterInfo[] pi = mi[i].GetParameters();
122+
if (pi.Length != signatureCount)
123+
{
124+
continue;
125+
}
126+
for (int n = 0; n < pi.Length; n++)
127+
{
128+
if (sigTp[n] != pi[n].ParameterType)
129+
{
130+
break;
131+
}
132+
if (n == (pi.Length - 1))
133+
{
134+
MethodInfo match = mi[i];
135+
if (match.IsGenericMethodDefinition)
136+
{
137+
Type[] typeArgs = match.GetGenericArguments();
138+
return match.MakeGenericMethod(genericTp);
139+
}
140+
return match;
141+
}
142+
}
143+
}
144+
return null;
145+
}
140146

141147

142148
//====================================================================
@@ -239,9 +245,10 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw,
239245
else {
240246
_methods = GetMethods();
241247
}
242-
248+
Type type;
243249
for (int i = 0; i < _methods.Length; i++) {
244250
MethodBase mi = _methods[i];
251+
245252
if (mi.IsGenericMethod) { isGeneric = true; }
246253
ParameterInfo[] pi = mi.GetParameters();
247254
int clrnargs = pi.Length;
@@ -275,19 +282,41 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw,
275282

276283
for (int n = 0; n < clrnargs; n++) {
277284
IntPtr op;
278-
if (n < pynargs)
279-
{
280-
if (arrayStart == n)
281-
{
285+
if (n < pynargs) {
286+
if (arrayStart == n) {
282287
// map remaining Python arguments to a tuple since
283288
// the managed function accepts it - hopefully :]
284289
op = Runtime.PyTuple_GetSlice(args, arrayStart, pynargs);
285290
}
286-
else
287-
{
291+
else {
288292
op = Runtime.PyTuple_GetItem(args, n);
289293
}
290-
Type type = pi[n].ParameterType;
294+
295+
// this logic below handles cases when multiple overloading methods
296+
// are ambiguous, hence comparison between Python and CLR types
297+
// is necessary
298+
type = null;
299+
300+
if (_methods.Length>1) {
301+
IntPtr pyoptype = IntPtr.Zero;
302+
pyoptype = Runtime.PyObject_Type(op);
303+
Exceptions.Clear();
304+
if (pyoptype != IntPtr.Zero) { }
305+
type = Converter.GetTypeByAlias(pyoptype);
306+
Runtime.Decref(pyoptype);
307+
}
308+
309+
310+
if (type != null) {
311+
if (pi[n].ParameterType != type) {
312+
margs = null;
313+
break;
314+
}
315+
}
316+
else {
317+
type = pi[n].ParameterType;
318+
}
319+
291320
if (pi[n].IsOut || type.IsByRef)
292321
{
293322
outs++;
@@ -348,7 +377,7 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw,
348377
MethodInfo mi = MethodBinder.MatchParameters(methodinfo, types);
349378
return Bind(inst, args, kw, mi, null);
350379
}
351-
return null;
380+
return null;
352381
}
353382

354383
internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) {

0 commit comments

Comments
 (0)