Before going the big step of implementing the indirect register frame,
I'd like to clarify argument passing for calls and returns.
Now we are placing arguments or return values in registers according to
PDD03 and the other end has immediately access to the placed values,
because the register file is in the interpreter.
With the indirect addressing of the register frame, this argument
passing is probably the most costly part of function calls and returns,
because we have to copy the values. One way to reduce this copying cost
could be to make argument passing more explicit. E.g.
$P0 = get_caller 1 # 1)
copy_args_from $P0 # 2)
copy_args_from_caller -1 # all in one
I5 = $P0 # 3)
P5 = $P0[-5]
ad 1) As call and returns are basically the same, this is usable for
both directions. The integer argument holds the level - positive is up
the call chain, -1 is the last called sub for return value access.
During startup a dummy sub is created for the command-line args access.
Such an opcode or functionality is needed for introspection and
ad 2) The all in one would be the usual emitted opcode. But, and that's
the import thing, functions returning values in *void context* could
just omit this opcode and avoid the copying.
ad 3) Could be useful to access arguments, only when needed to reduce
register allocation stress, or to access only parts of arguments.
Finally, making argument passing more explicit could be needed anyway.
Python is AFAIK passing a value tuple at least in the general case for
star_args. Converting values in registers to and from tuples could be
done by a python-specific version of such an opcode. And there are still
named arguments, which we don't really cover ...