Piers Cawley wrote: > > Benjamin Goldberg <[EMAIL PROTECTED]> writes: > > > Piers Cawley wrote: > > [snip] > >> Um... no. tail call optimization implies being able to replace *any* > >> tail call, not just a recursive one with a simple goto. > > [snip] > > > > In perl5, doing a tail call optimization can be done with just a simple > > goto... well, 'goto &subname', anyway. (Well, first you'd assign > > something to @_, then goto &subname). > > Ah... this discussion has been done in p5p and elsewhere; whilst goto > &sub could, in theory, do tail call optimization, in practice it seems > to be as slow as any other function call.
Really? I did not know that. However, even if it's not significantly faster, at least it saves memory, by discarding a level of saved stack information. > > Since (supposedly) there's going to be a perl5->parrot compiler, there > > needs to be support for perl5's goto &subname. ISTM that once we have > > figured out an efficient way of implementing that, we'll also have an > > efficient way of doing native tail call optimization. > > > > As a wild-ass-guess, an optimized tail call will look something like: > > > > .sub _foo # sub foo(int a, int b) > > saveall > > .param int a # a = pop @_ > > .param int b # b = pop @_ > > ... > > > > .arg int x # push @_, x > > .arg int u # push @_, u > > .arg int q # push @_, q > > restoreall > > jnsr _bar # goto &_bar > > .end > > > > .sub _bar # sub bar(int q, int u, int x) { > > saveall > > .param int q # q = pop @_ > > .param int u # u = pop @_ > > .param int x # x = pop @_ > > ... > > > > .return int pl # push @_, pl > > .return int ml # push @_, ml > > restoreall > > ret > > .end > > > > The 'jnsr' opcode (JumpNoSaveReturn) might be spelled as 'j' or as > > 'goto', or something else entirely, depending on what's least confusing, > > and most aesthetically pleasing. > > The problem here is that you've pushed two loads of registers onto the > register stack, and the return is only going to pop one set off. I think you're overlooking the "restoreall" done just before the jump-no-save-returnaddress operation... I see two "saveall"s and two "restoreall"s. At the point that 'jnsr _bar' is called, all the stacks should look exactly as if the code which called _foo had called _bar instead. (The "ret" doesn't pop a set of registers, just an address to goto.) > And it'll be the wrong set at that. And you can't add an extra > 'restoreall' to _bar because _bar could easily be called normally as > well as via a tailcall. I would not have suggested such a thing. Tail call optomization in parrot should be about the same logical semantics as perl5's goto &subname (except maybe being faster). -- $;=qq qJ,krleahciPhueerarsintoitq;sub __{0 && my$__;s ee substr$;,$,&&++$__%$,--,1,qq;;;ee; $__>2&&&__}$,=22+$;=~y yiy y;__ while$;;print