1898184e3Ssthen#!perl 2898184e3Ssthen 3898184e3Ssthenuse strict; 4898184e3Ssthenuse warnings; 5898184e3Ssthen 6898184e3Ssthenrequire "../../t/test.pl"; 7898184e3Ssthen 8898184e3Ssthenuse XS::APItest; 9898184e3Ssthen 10898184e3Ssthen# clone_with_stack creates a clone of the perl interpreter including 11898184e3Ssthen# the stack, then destroys the original interpreter and runs the 12898184e3Ssthen# remaining code using the new one. 13*eac174f2Safresh1# This is like doing a pseudo-fork and exiting the parent. 14898184e3Ssthen 15898184e3Ssthenuse Config; 16898184e3Ssthenif (not $Config{'useithreads'}) { 17898184e3Ssthen skip_all("clone_with_stack requires threads"); 18898184e3Ssthen} 19898184e3Ssthen 20b8851fccSafresh1plan(8); 21898184e3Ssthen 22898184e3Ssthenfresh_perl_is( <<'----', <<'====', undef, "minimal clone_with_stack" ); 23898184e3Ssthenuse XS::APItest; 24898184e3Ssthenclone_with_stack(); 25898184e3Ssthenprint "ok\n"; 26898184e3Ssthen---- 27898184e3Ssthenok 28898184e3Ssthen==== 29898184e3Ssthen 30898184e3Ssthenfresh_perl_is( <<'----', <<'====', undef, "inside a subroutine" ); 31898184e3Ssthenuse XS::APItest; 32898184e3Ssthensub f { 33898184e3Ssthen clone_with_stack(); 34898184e3Ssthen} 35898184e3Ssthenf(); 36898184e3Ssthenprint "ok\n"; 37898184e3Ssthen---- 38898184e3Ssthenok 39898184e3Ssthen==== 40898184e3Ssthen 41898184e3Ssthen{ 42898184e3Ssthen local our $TODO = "clone_with_stack inside a begin block"; 43898184e3Ssthen fresh_perl_is( <<'----', <<'====', undef, "inside a BEGIN block" ); 44898184e3Ssthenuse XS::APItest; 45898184e3SsthenBEGIN { 46898184e3Ssthen clone_with_stack(); 47898184e3Ssthen} 48898184e3Ssthenprint "ok\n"; 49898184e3Ssthen---- 50898184e3Ssthenok 51898184e3Ssthen==== 52898184e3Ssthen 53898184e3Ssthen} 5491f110e0Safresh1 5591f110e0Safresh1{ 5691f110e0Safresh1 fresh_perl_is( <<'----', <<'====', undef, "clone stack" ); 5791f110e0Safresh1use XS::APItest; 5891f110e0Safresh1sub f { 5991f110e0Safresh1 clone_with_stack(); 6091f110e0Safresh1 0..4; 6191f110e0Safresh1} 6291f110e0Safresh1print 'X-', 'Y-', join(':', f()), "-Z\n"; 6391f110e0Safresh1---- 6491f110e0Safresh1X-Y-0:1:2:3:4-Z 6591f110e0Safresh1==== 6691f110e0Safresh1 6791f110e0Safresh1} 6852736614Safresh1 6952736614Safresh1{ 70b8851fccSafresh1 fresh_perl_is( <<'----', <<'====', undef, "with a lexical sub" ); 71b8851fccSafresh1use XS::APItest; 72b8851fccSafresh1use experimental lexical_subs=>; 73b8851fccSafresh1my sub f { print "42\n" } 74b8851fccSafresh1clone_with_stack(); 75b8851fccSafresh1f(); 76b8851fccSafresh1---- 77b8851fccSafresh142 78b8851fccSafresh1==== 79b8851fccSafresh1 80b8851fccSafresh1} 81b8851fccSafresh1 82b8851fccSafresh1{ 8352736614Safresh1 fresh_perl_is( <<'----', <<'====', undef, "with localised stuff" ); 8452736614Safresh1use XS::APItest; 8552736614Safresh1$s = "outer"; 8652736614Safresh1$a[0] = "anterior"; 8752736614Safresh1$h{k} = "hale"; 8852736614Safresh1{ 8952736614Safresh1 local $s = "inner"; 9052736614Safresh1 local $a[0] = 'posterior'; 9152736614Safresh1 local $h{k} = "halt"; 9252736614Safresh1 clone_with_stack(); 9352736614Safresh1} 9452736614Safresh1print "scl: $s\n"; 9552736614Safresh1print "ary: $a[0]\n"; 9652736614Safresh1print "hsh: $h{k}\n"; 9752736614Safresh1---- 9852736614Safresh1scl: outer 9952736614Safresh1ary: anterior 10052736614Safresh1hsh: hale 10152736614Safresh1==== 10252736614Safresh1 10352736614Safresh1} 104b8851fccSafresh1 105b8851fccSafresh1{ 106b8851fccSafresh1 fresh_perl_is( <<'----', <<'====', undef, "inside a loop inside a fn" ); 107b8851fccSafresh1use XS::APItest; 108b8851fccSafresh1my $a = 'aa'; 109b8851fccSafresh1sub f { 110b8851fccSafresh1 my $b = 'bb'; 111b8851fccSafresh1 my @c; 112b8851fccSafresh1 my $d = 'dd'; 113b8851fccSafresh1 for my $d (0..4) { 114b8851fccSafresh1 clone_with_stack() if $d == 2; 115b8851fccSafresh1 push @c, $d; 116b8851fccSafresh1 } 117b8851fccSafresh1 return @c, $d; 118b8851fccSafresh1} 119b8851fccSafresh1print "X-$a-", join(':', f()), "-Z\n"; 120b8851fccSafresh1---- 121b8851fccSafresh1X-aa-0:1:2:3:4:dd-Z 122b8851fccSafresh1==== 123b8851fccSafresh1 124b8851fccSafresh1} 125b8851fccSafresh1 126b8851fccSafresh1{ 127b8851fccSafresh1 fresh_perl_is( <<'----', <<'====', undef, "inside fn inside a loop inside a fn" ); 128b8851fccSafresh1use XS::APItest; 129b8851fccSafresh1my $a = 'aa'; 130b8851fccSafresh1 131b8851fccSafresh1sub g { 132b8851fccSafresh1 my $e = 'ee'; 133b8851fccSafresh1 my $f = 'ff'; 134b8851fccSafresh1 clone_with_stack(); 135b8851fccSafresh1} 136b8851fccSafresh1 137b8851fccSafresh1sub f { 138b8851fccSafresh1 my $b = 'bb'; 139b8851fccSafresh1 my @c; 140b8851fccSafresh1 my $d = 'dd'; 141b8851fccSafresh1 for my $d (0..4) { 142b8851fccSafresh1 g() if $d == 2; 143b8851fccSafresh1 push @c, $d; 144b8851fccSafresh1 } 145b8851fccSafresh1 return @c, $d; 146b8851fccSafresh1} 147b8851fccSafresh1print "X-$a-", join(':', f()), "-Z\n"; 148b8851fccSafresh1---- 149b8851fccSafresh1X-aa-0:1:2:3:4:dd-Z 150b8851fccSafresh1==== 151b8851fccSafresh1 152b8851fccSafresh1} 153