I was going to submit this as a patch, but I ended up with a conflict, and Dan threatened he wouldn't apply it anyway, so I'll just post it here for comment. Feel free to apply any or all of it. I would be very happy to hear of a better way to answer the first question. =-)
---
=head2 How do I generate a sub call with a variable-length parameter list in PIR?
This is currently not trivial. Since there are no PIR or PASM syntax aids
for this, the only method for doing this at the moment is to dynamically create a C<.sub> that takes a fixed number of arguments, and have that sub manage the details of your variable arguments.
As an example, let's say you want to call a method with three arguments, but that method could take any number of arguments normally. To keep it simple, let's assume that all the PMCs are stringlike. You'd create a string containing a sub definition (be sure to escape quotes and newlines properly) like:
.sub _disposable
$P1 = new PerlString
$P1 = "..."
$P2 = new PerlString
$P2 = "..."
$P3 = new PerlString
$P3 = "..."
Where you'd replace C<...> with a C<Data::Escape::String>'d version of the string to be safe. (For complex PMCs, you'd have to C<freeze> the PMC, then C<thaw> the escaped version in your generated PIR code. Alternatively, if these PMCs are already available in a global or lexical scope, you could skip the freeze/thaw step and merely pull them using C<find_global> or C<find_lex>.
Since you're generating this C<_disposable> sub on the fly, you now generate the dynamic call yourself.
($I0,$S0) = _sub($P1,$P2,$P3)
You can, of course, replace the invocation to use a Sub-like PMC instead of a label.
Finally, pass along the return values to your caller.
.pcc_begin_return return $I0 return $S0 .pcc_end_return .end
Then, you need to invoke the PIR compiler to compile this disposable sub,
.local pmc pir_compiler pir_compiler = compreg "PIR" $P1 = compile pir_compiler, pir_code
Now, you can run your code.
$P1 = find_global "_disposable" ($I0,$S0) = $P1()
This process may be streamlined in the future.
=head2 How do I retrieve the contents of a variable-length parameter list being passed to me?
The easiest way to do this is to use the C<foldup> opcode to take a variable number of PMC arguments and wrap them in an C<Array> PMC. I<Note>: C<foldup> I<only> works for PMC arguments.
.sub _mysub .local pmc argv .local int argc argv = foldup argc = argv ...
If you have a few fixed parameters, you can use a variant of C<foldup> to capture variable arguments from that position on.
.sub _mysub .param pmc arg0 .param pmc arg1 .local pmc varargs .local int num_varargs varargs = foldup, 2 num_varargs = varargs ...