In situations where A calls B and B tail-calls C, and C produces some arbitrary number of return values, I would like to be able to generate code for B without having to care how many values A expects, how many C produces, or even whether these numbers are fixed at compile-time. I can sort of do this now via tail-call optimization, e.g.:
.sub _B non_prototyped .param pmc function .local pmc argv argv = foldup 1 print "[doing _B]\n" $I33 = defined function if $I33 goto doit bad_func: printerr "_B: Bad function.\n" die doit: .pcc_begin prototyped .flatten_arg argv .pcc_call function .pcc_end .pcc_begin_return .pcc_end_return .end This works, but I have to jump through numerous hoops: 1. I must resort to this lame idiom that appears to accept and return no values. 2. The code must be compiled with "-Oc", or that is in fact what it does. 3. I must live with the fact that I won't ever see B in a backtrace; I get tail-merging semantics whether I like it or not. 4. The return must be just before .end; it doesn't work if I invert the sense of the test and swap the "bad_func" and "doit" blocks. (Is this a bug in tail-call optimization?) The number of hoops is surprising, given that perl5 has this "call and return all values" semantics. (But perl6 seems to return everything in an array, so that was no help. Whatever.) The key problem is that this code works only if compiled with tail-merging (tail-call optimization) enabled, which strikes me as wrong; correct code should not have to depend on an optimization, certainly not a non-default one. So I would like to be able to tell IMCC explicitly that I am doing a tail call which should pass all returned values back to my caller. This should be regardless of whether tail-merging is enabled, but should definitely be tail-merged if so. I thought I might be able to do this via .pcc_call with an explicit continuation, but I don't see how to get to the continuation that returncc would use. Is this possible? Better still would be an explicit way to say "call and return all values." Here's one possible syntax for the example above: doit: .pcc_begin prototyped .flatten_arg argv .pcc_tail_call function .pcc_end .end The ".pcc_tail_call function" would be an alternative to the "pcc_call opt_label pcc_results" sequence in the "pcc_sub_call" production. It seems to me that this could generate a normal call followed by returncc (without changing I0-4) if tail-call optimization is off. But then, I'm pretty wet behind the ears when it comes to hacking Parrot, so I couldn't produce a patch without help, or at least some direction. Not to mention the possibility that there may be something I've missed . . . TIA, -- Bob Rogers http://rgrjr.dyndns.org/