On Thursday 15 November 2001 07:53 am, Ken Fox wrote: > Shlomi Fish wrote: > > For instance, we can have a "ret-with-call" opcode. However, isn't it > > exactly the same as a jump instruction ? > > No. The current scope must be destroyed, lexicals destroyed, localized > globals restored, etc. It's basically the clean-up of a return, but the > control flow logic of a sub call.
I think this was the point though. In much RISC hardware, the stack frame is theoretically constant throughout a function call (barring further function calls). The compiler usually preallocates space on the stack for any nested scopes. Thus jumping to the head not only avoids augmenting the stack, but also avoids any tearing down as well. The only problem is if any locals assume newly allocated values are zero, but that would be a problem anyway. I know it's dangerous to compare hardware to a VM, but the required equivalent would be to not tear down ANY scoping, and additionally, the definition of a subroutine would have to preallocate ALL scopes before-hand. In the current incarnation of our parrot core, we have a problem though, since it's possible that more than we're limited to 32 by m registers in a given scope. It's possible that nested scopes will require pushing a register stack within the same function (especially for extra-long main functions). I have beefs with the current system anyway (liking a variation Knuth's register set for VMs), but this alone conflicts with end-tail-recursion optimizations. It's still possible for the compiler to determine that a function doesn't need to modify it's call-stack, and at that point insert the appropriate jump instructions (don't see a need for new op-codes). Aside from messing with the caller() info, I don't see a problem with this. It's just not going to be generally applicable to all parrot subroutines that apply recursion. -Michael