Acme-Parataxis
view release on metacpan or search on metacpan
t/024_stack_growth.t view on Meta::CPAN
use v5.40;
use blib;
use Acme::Parataxis qw[async yield fiber];
use Test2::V1 -ipP;
$|++;
#
no warnings 'recursion';
subtest 'Deep plain recursion grows the Perl control stacks' => sub {
async {
my $f = fiber {
my $recur;
$recur = sub {
my ($n) = @_;
return 0 if $n <= 1;
return 1 + $recur->( $n - 1 );
};
$recur->(20000);
};
my $r = $f->await();
is $r, 19999, 'depth-20000 recursion returned the expected result';
};
};
subtest 'Nested sort comparators recurse through C' => sub {
# Each nested sort re-enters perl from C (S_sortcv -> CALLRUNOPS), which
# consumes real C stack; this used to corrupt the heap in DEBUGGING perls
# because the fiber did not own PL_scopestack_name.
async {
my $f = fiber {
my $recur;
$recur = sub {
my ($n) = @_;
return 0 if $n <= 1;
my @out = sort { my $x = $recur->( $n - 1 ) } ( 0, 1 );
return $out[0];
};
$recur->(500);
};
my $r = $f->await();
is $r, 0, 'depth-500 sort-comparator recursion completed';
};
};
subtest 'Recursion interleaved with yields' => sub {
my @log;
async {
my $f = fiber {
my $recur;
$recur = sub {
my ($n) = @_;
return 0 if $n <= 1;
push @log, "d$n";
yield;
return 1 + $recur->( $n - 1 );
};
$recur->(50);
};
yield;
my $r = $f->await();
is $r, 49, 'recursing fiber that yields still completes';
};
ok @log >= 49, 'fiber yielded during recursion';
};
done_testing();
( run in 0.418 second using v1.01-cache-2.11-cpan-eca53f54451 )