Open irh opened 2 years ago
I looked at this a bit today with @alisomay and here are some notes from our discussion:
TailCall
instruction can be added which performs a tail call, reusing the current frame's registers.
0
, and then the tail call frame base would be register 1
, with result register also 1
. The op can then be executed following the tail call before the function exits.0
. How this would work exactly isn't clear (it would effectively be saying to the op that the LHS is in register -1
), but it would still be a win to cache in register 0
so I think this doesn't have to be figured out to move forward.TailCall
instruction, the compiler could pass an 'allow tail call' flag around while compiling nodes. This flag would be set to true when compiling a return expression, and then set to false when a tail call should be explicitly disallowed (e.g. when compiling the LHS of a binary op).
Some groundwork for this was done in #290. I didn't go any further because I'd like to understand more about how debugging might one day work before making any guarantees regarding tail calls.
Currently no effort is made in Koto to optimize tail calls, making it easy to run into stack overflows when implementing recursive functions.
e.g. The following script takes a huge amount of memory to execute:
The idea would be that if a terminating expression (i.e.
throw
orreturn
(implicit returns for the last expression in a function included)) in a function is a call, then instead of creating a new frame, the current function's execution frame can be reused.