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

or
   I5 = $P0[5]               # 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 backtraces too.


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 ...

Comments welcome,
leo



Reply via email to