|
There is opportunity to optimize tail calls in puppet. Now when we do not do this, we have issues with recursive functions running out of stack since each call level is expensive.
We can implement this by:
-
adding a boolean flag to the AST call instructions.
-
in the rewrite step in the parser (where it detects parenthesized function calls), we detect if a call is a "tail-call", and we flip the "tail-call" bit in the AST
-
when performing the call, instead of adding yet another stack level, we throw a TailCall, which contains the information needed to proceed.
Tail-calls are all calls where the result of the call is also the result of the expression the call is part of. If we had a return it would be wherever there is a construct like return func().
Here is an example, where some potential tail calls can be detected.
function foo($x) {
|
case $x {
|
1 : { tail_call() }
|
2: { not_tail_call(); tail_call() }
|
}
|
if cond {
|
tail_call()
|
}
|
not_tail_call()
|
tail_call()
|
}
|
|