Skip to content

Commit 04b77d9

Browse files
committed
extracted TryConvertArguments from MethodBinder.Bind
1 parent 0bb5a45 commit 04b77d9

File tree

1 file changed

+67
-53
lines changed

1 file changed

+67
-53
lines changed

src/runtime/methodbinder.cs

+67-53
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
280280
// loop to find match, return invoker w/ or /wo error
281281
MethodBase[] _methods = null;
282282
var pynargs = (int)Runtime.PyTuple_Size(args);
283-
object arg;
284283
var isGeneric = false;
285284
if (info != null)
286285
{
@@ -301,59 +300,15 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
301300
}
302301
ParameterInfo[] pi = mi.GetParameters();
303302
ArrayList defaultArgList;
304-
int arrayStart;
303+
bool paramsArray;
305304

306-
if (!MatchesArgumentCount(pynargs, pi, out arrayStart, out defaultArgList)) {
305+
if (!MatchesArgumentCount(pynargs, pi, out paramsArray, out defaultArgList)) {
307306
continue;
308307
}
309308
var outs = 0;
310-
var margs = new object[pi.Length];
311-
312-
for (int paramIndex = 0; paramIndex < pi.Length; paramIndex++)
313-
{
314-
if (paramIndex >= pynargs)
315-
{
316-
if (defaultArgList != null)
317-
{
318-
margs[paramIndex] = defaultArgList[paramIndex - pynargs];
319-
}
320-
321-
continue;
322-
}
323-
324-
IntPtr op = (arrayStart == paramIndex)
325-
// map remaining Python arguments to a tuple since
326-
// the managed function accepts it - hopefully :]
327-
? Runtime.PyTuple_GetSlice(args, arrayStart, pynargs)
328-
: Runtime.PyTuple_GetItem(args, paramIndex);
329-
330-
var parameter = pi[paramIndex];
331-
332-
var clrtype = TryComputeClrArgumentType(parameter.ParameterType, op, needsResolution: _methods.Length > 1);
333-
if (clrtype == null) {
334-
margs = null;
335-
break;
336-
}
337-
338-
if (parameter.IsOut || clrtype.IsByRef)
339-
{
340-
outs++;
341-
}
342-
343-
if (!Converter.ToManaged(op, clrtype, out arg, false))
344-
{
345-
Exceptions.Clear();
346-
margs = null;
347-
break;
348-
}
349-
if (arrayStart == paramIndex)
350-
{
351-
// GetSlice() creates a new reference but GetItem()
352-
// returns only a borrow reference.
353-
Runtime.XDecref(op);
354-
}
355-
margs[paramIndex] = arg;
356-
}
309+
var margs = TryConvertArguments(pi, paramsArray, args, pynargs, defaultArgList,
310+
needsResolution: _methods.Length > 1,
311+
outs: out outs);
357312

358313
if (margs == null)
359314
{
@@ -394,6 +349,65 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
394349
return null;
395350
}
396351

352+
static object[] TryConvertArguments(ParameterInfo[] pi, bool paramsArray,
353+
IntPtr args, int pyArgCount,
354+
ArrayList defaultArgList,
355+
bool needsResolution,
356+
out int outs)
357+
{
358+
outs = 0;
359+
var margs = new object[pi.Length];
360+
int arrayStart = paramsArray ? pi.Length - 1 : -1;
361+
362+
for (int paramIndex = 0; paramIndex < pi.Length; paramIndex++)
363+
{
364+
if (paramIndex >= pyArgCount)
365+
{
366+
if (defaultArgList != null)
367+
{
368+
margs[paramIndex] = defaultArgList[paramIndex - pyArgCount];
369+
}
370+
371+
continue;
372+
}
373+
374+
IntPtr op = (arrayStart == paramIndex)
375+
// map remaining Python arguments to a tuple since
376+
// the managed function accepts it - hopefully :]
377+
? Runtime.PyTuple_GetSlice(args, arrayStart, pyArgCount)
378+
: Runtime.PyTuple_GetItem(args, paramIndex);
379+
380+
var parameter = pi[paramIndex];
381+
382+
var clrtype = TryComputeClrArgumentType(parameter.ParameterType, op, needsResolution: needsResolution);
383+
if (clrtype == null)
384+
{
385+
return null;
386+
}
387+
388+
if (parameter.IsOut || clrtype.IsByRef)
389+
{
390+
outs++;
391+
}
392+
393+
object arg;
394+
if (!Converter.ToManaged(op, clrtype, out arg, false))
395+
{
396+
Exceptions.Clear();
397+
return null;
398+
}
399+
if (arrayStart == paramIndex)
400+
{
401+
// GetSlice() creates a new reference but GetItem()
402+
// returns only a borrow reference.
403+
Runtime.XDecref(op);
404+
}
405+
margs[paramIndex] = arg;
406+
}
407+
408+
return margs;
409+
}
410+
397411
static Type TryComputeClrArgumentType(Type parameterType, IntPtr argument, bool needsResolution)
398412
{
399413
// this logic below handles cases when multiple overloading methods
@@ -465,12 +479,12 @@ static Type TryComputeClrArgumentType(Type parameterType, IntPtr argument, bool
465479
}
466480

467481
static bool MatchesArgumentCount(int argumentCount, ParameterInfo[] parameters,
468-
out int paramsArrayStart,
482+
out bool paramsArray,
469483
out ArrayList defaultArgList)
470484
{
471485
defaultArgList = null;
472486
var match = false;
473-
paramsArrayStart = -1;
487+
paramsArray = false;
474488

475489
if (argumentCount == parameters.Length)
476490
{
@@ -491,7 +505,7 @@ static bool MatchesArgumentCount(int argumentCount, ParameterInfo[] parameters,
491505
{
492506
// This is a `foo(params object[] bar)` style method
493507
match = true;
494-
paramsArrayStart = parameters.Length - 1;
508+
paramsArray = true;
495509
}
496510

497511
return match;

0 commit comments

Comments
 (0)