@@ -358,11 +358,14 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
358
358
// /////////////////////////////
359
359
// Now do all the rewriting
360
360
361
+ // Note: we're not allowed to modify the contents of the `Box** args` arguments array.
362
+ // If we need to make modifications, we have to copy it first.
363
+
361
364
// Right now we don't handle either of these
362
365
if (argspec.has_kwargs || argspec.num_keywords )
363
366
return ;
364
367
365
- if (argspec.has_starargs && !paramspec.num_defaults && !paramspec. takes_kwargs ) {
368
+ if (argspec.has_starargs && !paramspec.num_defaults ) {
366
369
assert (!argspec.has_kwargs );
367
370
assert (!argspec.num_keywords );
368
371
// We just dispatch to a helper function to copy the args and call pyElements
@@ -395,7 +398,7 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
395
398
} else {
396
399
if (argspec.num_args <= 3 ) {
397
400
assert (paramspec.num_args >= argspec.num_args );
398
- int bufSize = paramspec.num_args - argspec.num_args + (paramspec.takes_varargs ? 1 : 0 );
401
+ int bufSize = paramspec.num_args - argspec.num_args + (paramspec.takes_varargs ? 1 : 0 ) + (paramspec. takes_kwargs ? 1 : 0 ) ;
399
402
RewriterVar* r_buf_ptr = bufSize > 0 ? rewrite_args->rewriter ->allocate (bufSize)
400
403
: rewrite_args->rewriter ->loadConst (0 );
401
404
rewrite_args->rewriter ->call (true /* has side effects */ ,
@@ -405,7 +408,7 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
405
408
rewrite_args->rewriter ->loadConst (argspec.asInt ()),
406
409
rewrite_args->rewriter ->loadConst (paramspec.asInt ()),
407
410
rewrite_args->rewriter ->loadConst ((int64_t )func_name));
408
- for (int i = argspec.num_args ; i < (paramspec.num_args + (paramspec.takes_varargs ? 1 : 0 )); i++) {
411
+ for (int i = argspec.num_args ; i < (paramspec.num_args + (paramspec.takes_varargs ? 1 : 0 ) + (paramspec. takes_kwargs ? 1 : 0 ) ); i++) {
409
412
int buf_offset = sizeof (Box*) * (i - argspec.num_args );
410
413
if (i == 0 )
411
414
rewrite_args->arg1 = r_buf_ptr->getAttr (buf_offset);
@@ -424,7 +427,7 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
424
427
assert (paramspec.num_args + (paramspec.takes_varargs ? 1 : 0 ) >= 3 );
425
428
RewriterVar* r_buf_ptr = rewrite_args->rewriter ->allocateAndCopy (
426
429
rewrite_args->args , argspec.num_args - 3 ,
427
- paramspec.num_args + (paramspec.takes_varargs ? 1 : 0 ) - 3 );
430
+ paramspec.num_args + (paramspec.takes_varargs ? 1 : 0 ) + (paramspec. takes_kwargs ? 1 : 0 ) - 3 );
428
431
429
432
RewriterVar* r_buf_ptr_for_varargs
430
433
= rewrite_args->rewriter ->add (r_buf_ptr, (argspec.num_args - 3 ) * sizeof (Box*), assembler::RDI);
@@ -441,6 +444,23 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
441
444
}
442
445
}
443
446
447
+ if (paramspec.takes_kwargs ) {
448
+ assert (!argspec.num_keywords && !argspec.has_kwargs );
449
+
450
+ int kwargs_idx = paramspec.num_args + (paramspec.takes_varargs ? 1 : 0 );
451
+ RewriterVar* r_kwargs = rewrite_args->rewriter ->call (true , (void *)createDict);
452
+
453
+ if (kwargs_idx == 0 )
454
+ rewrite_args->arg1 = r_kwargs;
455
+ if (kwargs_idx == 1 )
456
+ rewrite_args->arg2 = r_kwargs;
457
+ if (kwargs_idx == 2 )
458
+ rewrite_args->arg3 = r_kwargs;
459
+ if (kwargs_idx >= 3 ) {
460
+ rewrite_args->args ->setAttr ((kwargs_idx - 3 ) * sizeof (Box*), r_kwargs);
461
+ }
462
+ }
463
+
444
464
rewrite_success = true ;
445
465
return ;
446
466
}
0 commit comments