pperl 0.6.14#

2026-08-18 to 2026-08-21, 45 commits.

  • Recursive subroutines compile to machine code. A subroutine that takes one argument ($_[0], my ($n) = @_ or shift), returns a number and calls itself, such as fib or check_tree in the Benchmarks Game’s binary-trees, runs compiled, its recursive calls included. Its body may branch, return through return EXPR or a conditional expression, and test ref $_[0]; a loop that calls it calls the compiled code directly.

  • binary-trees: a call whose argument is another call, as in $check += check_tree(bottomup_tree($d)), reaches the compiled check_tree while bottomup_tree still runs in the interpreter. At depth 16 binary-trees takes 2.76 s instead of 4.07 s, 1.5 times as fast as perl5, where it ran at parity before.

  • Subroutine calls in compiled loops: a loop that calls an ordinary subroutine, one with a real @_ that may write package variables, compiles together with the called body, with the call frame perl5 would build. Arguments may be computed expressions such as tally($i % 97), the sub’s return value can be used, and several call sites of one sub in a loop all compile. A sub that was redefined or re-aliased, a call resolved through AUTOLOAD, and a call into a sub that is already running take the regular call path.

  • Subroutine call overhead in compiled loops is lower: compiled code sets up and removes the sub’s frame itself, without pushing the argument mark or the sub onto the stack. Temporary arguments are not copied when the sub cannot alias or capture them, and a scalar return value is not copied when the sub has nothing to clean up on return. A loop calling sub tally { $SUM += $_[0]; $CNT += 1 } two million times runs 1.84 times as fast as on perl5, and a loop adding up the return value of a sub without my variables 1.74 times as fast.

  • wantarray and caller compile in a sub called from a compiled loop when they are used as a truth value, as in wantarray ? 2 : 1 or run() unless caller.

  • Array references in compiled loops: $m[$i][$j], $_[0][0], $x->[$i], $$y[$i], $#$x, pop @$x and slices such as my ($a, $b, $c) = @$x[-3..-1] compile, as do unshift and blocks that open their own scope. Negative indexes such as $x->[-1] no longer leave compiled code on every iteration. In the Benchmarks Game’s pidigits, the inner loop of Math::BigInt::Calc’s arithmetic now compiles in full.

  • push in compiled loops: $n = push @a, $x; assigns the array’s new length on every iteration. $n kept the value it had when the loop was compiled, so after 200,000 pushes it read 64.