@@ -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