xref: /openbsd-src/gnu/usr.bin/perl/ext/XS-APItest/t/clone-with-stack.t (revision eac174f2741a08d8deb8aae59a7f778ef9b5d770)
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