Skip to content

Update methodbinder.cs #137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 84 additions & 55 deletions src/runtime/methodbinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
//====================================================================
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume nothing's actually changed here? Just whitespace? It's easier to manage white space changes in their own PR (just for future reference, don't worry about changing it back)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I installed VS Power Tools in between these commits, that's why whitespace/tab fixes.

// 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;
}


//====================================================================
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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++;
Expand Down Expand Up @@ -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) {
Expand Down