Skip to content

Commit fd0c77b

Browse files
committed
support kwargs parameter with varargs (but only if there are no **kwargs args or keyword args)
1 parent f9e4fc5 commit fd0c77b

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

src/runtime/rearrange_arguments.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,11 +358,14 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
358358
///////////////////////////////
359359
// Now do all the rewriting
360360

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+
361364
// Right now we don't handle either of these
362365
if (argspec.has_kwargs || argspec.num_keywords)
363366
return;
364367

365-
if (argspec.has_starargs && !paramspec.num_defaults && !paramspec.takes_kwargs) {
368+
if (argspec.has_starargs && !paramspec.num_defaults) {
366369
assert(!argspec.has_kwargs);
367370
assert(!argspec.num_keywords);
368371
// 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
395398
} else {
396399
if (argspec.num_args <= 3) {
397400
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);
399402
RewriterVar* r_buf_ptr = bufSize > 0 ? rewrite_args->rewriter->allocate(bufSize)
400403
: rewrite_args->rewriter->loadConst(0);
401404
rewrite_args->rewriter->call(true /* has side effects */,
@@ -405,7 +408,7 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
405408
rewrite_args->rewriter->loadConst(argspec.asInt()),
406409
rewrite_args->rewriter->loadConst(paramspec.asInt()),
407410
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++) {
409412
int buf_offset = sizeof(Box*) * (i - argspec.num_args);
410413
if (i == 0)
411414
rewrite_args->arg1 = r_buf_ptr->getAttr(buf_offset);
@@ -424,7 +427,7 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
424427
assert(paramspec.num_args + (paramspec.takes_varargs ? 1 : 0) >= 3);
425428
RewriterVar* r_buf_ptr = rewrite_args->rewriter->allocateAndCopy(
426429
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);
428431

429432
RewriterVar* r_buf_ptr_for_varargs
430433
= 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
441444
}
442445
}
443446

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+
444464
rewrite_success = true;
445465
return;
446466
}

0 commit comments

Comments
 (0)