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

Skip to content

Commit 108eacf

Browse files
committed
Deal with operator binding
1 parent 44e089a commit 108eacf

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

src/runtime/methodbinder.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Linq;
45
using System.Reflection;
56
using System.Text;
67

@@ -325,6 +326,28 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
325326
{
326327
isGeneric = true;
327328
}
329+
330+
bool isOperator = OperatorMethod.IsOperatorMethod(mi);
331+
// Binary operator methods will have 2 CLR args but only one Python arg
332+
// (unary operators will have 1 less each), since Python operator methods are bound.
333+
isOperator = isOperator && pynargs == pi.Length - 1;
334+
bool isReverse = isOperator && OperatorMethod.IsReverse((MethodInfo)mi); // Only cast if isOperator.
335+
if (isReverse && OperatorMethod.IsComparisonOp((MethodInfo)mi))
336+
continue; // Comparison operators in Python have no reverse mode.
337+
// Preprocessing pi to remove either the first or second argument.
338+
if (isOperator && !isReverse)
339+
{
340+
// The first Python arg is the right operand, while the bound instance is the left.
341+
// We need to skip the first (left operand) CLR argument.
342+
pi = pi.Skip(1).ToArray();
343+
}
344+
else if (isOperator && isReverse)
345+
{
346+
// The first Python arg is the left operand.
347+
// We need to take the first CLR argument.
348+
pi = pi.Take(1).ToArray();
349+
}
350+
328351
int clrnargs = pi.Length;
329352
int arrayStart;
330353

@@ -564,6 +587,30 @@ static object[] TryConvertArguments(ParameterInfo[] pi, bool paramsArray,
564587
continue;
565588
}
566589

590+
if (isOperator)
591+
{
592+
if (inst != IntPtr.Zero)
593+
{
594+
if (ManagedType.GetManagedObject(inst) is CLRObject co)
595+
{
596+
bool isUnary = pynargs == 0;
597+
// Postprocessing to extend margs.
598+
var margsTemp = isUnary ? new object[1] : new object[2];
599+
// If reverse, the bound instance is the right operand.
600+
int boundOperandIndex = isReverse ? 1 : 0;
601+
// If reverse, the passed instance is the left operand.
602+
int passedOperandIndex = isReverse ? 0 : 1;
603+
margsTemp[boundOperandIndex] = co.inst;
604+
if (!isUnary)
605+
{
606+
margsTemp[passedOperandIndex] = margs[0];
607+
}
608+
margs = margsTemp;
609+
}
610+
else continue;
611+
}
612+
}
613+
567614
object target = null;
568615
if (!mi.IsStatic && inst != IntPtr.Zero)
569616
{

0 commit comments

Comments
 (0)