1#!perl
2# Copyright (C) 2001-2014, Parrot Foundation.
3
4use strict;
5use warnings;
6use lib qw( . lib ../lib ../../lib );
7
8use Test::More;
9use Parrot::Test tests => 5;
10
11pir_output_is( <<'CODE', <<'OUT', "bug #32996" );
12
13.namespace ["Foo"]
14
15.sub __biginit :main
16        $S0 = "Foo"
17        newclass $P0, $S0
18        $P1 = new $S0
19        $P1.'method1'()
20        $P1.'method2'()
21
22        $P2 = new $S0
23        $P2.'method1'()
24        $P2.'method2'()
25
26        $P3 = new $S0
27        $P3.'method1'()
28        $P3.'method2'()
29
30        $P4 = new $S0
31        $P4.'method1'()
32        $P4.'method2'()
33
34        $P5 = new $S0
35        $P5.'method1'()
36        $P5.'method2'()
37
38        $P6 = new $S0
39        $P6.'method1'()
40        $P6.'method2'()
41
42        $P7 = new $S0
43        $P7.'method1'()
44        $P7.'method2'()
45
46        $P8 = new $S0
47        $P8.'method1'()
48        $P8.'method2'()
49
50        $P9 = new $S0
51        $P9.'method1'()
52        $P9.'method2'()
53
54        $P10 = new $S0
55        $P10.'method1'()
56        $P10.'method2'()
57
58        $P11 = new $S0
59        $P11.'method1'()
60        $P11.'method2'()
61
62        $P12 = new $S0
63        $P12.'method1'()
64        $P12.'method2'()
65
66        $P13 = new $S0
67        $P13.'method1'()
68        $P13.'method2'()
69
70        $P14 = new $S0
71        $P14.'method1'()
72        $P14.'method2'()
73
74        $P15 = new $S0
75        $P15.'method1'()
76        $P15.'method2'()
77
78        $P1.'method1'()
79        $P1.'method2'()
80        $P2.'method1'()
81        $P2.'method2'()
82        $P3.'method1'()
83        $P3.'method2'()
84        $P4.'method1'()
85        $P4.'method2'()
86        $P5.'method1'()
87        $P5.'method2'()
88        $P6.'method1'()
89        $P6.'method2'()
90        $P7.'method1'()
91        $P7.'method2'()
92        $P8.'method1'()
93        $P8.'method2'()
94        $P9.'method1'()
95        $P9.'method2'()
96        $P10.'method1'()
97        $P10.'method2'()
98        $P11.'method1'()
99        $P11.'method2'()
100        $P12.'method1'()
101        $P12.'method2'()
102        $P13.'method1'()
103        $P13.'method2'()
104        $P14.'method1'()
105        $P14.'method2'()
106        $P15.'method1'()
107        $P15.'method2'()
108
109        end
110.end
111
112.sub method1 :method
113        print "In method 1\n"
114        .begin_return
115        .end_return
116.end
117
118.sub method2 :method
119        print "In method 2\n"
120        .begin_return
121        .end_return
122.end
123CODE
124In method 1
125In method 2
126In method 1
127In method 2
128In method 1
129In method 2
130In method 1
131In method 2
132In method 1
133In method 2
134In method 1
135In method 2
136In method 1
137In method 2
138In method 1
139In method 2
140In method 1
141In method 2
142In method 1
143In method 2
144In method 1
145In method 2
146In method 1
147In method 2
148In method 1
149In method 2
150In method 1
151In method 2
152In method 1
153In method 2
154In method 1
155In method 2
156In method 1
157In method 2
158In method 1
159In method 2
160In method 1
161In method 2
162In method 1
163In method 2
164In method 1
165In method 2
166In method 1
167In method 2
168In method 1
169In method 2
170In method 1
171In method 2
172In method 1
173In method 2
174In method 1
175In method 2
176In method 1
177In method 2
178In method 1
179In method 2
180In method 1
181In method 2
182In method 1
183In method 2
184OUT
185
186sub repeat {
187    my ( $template, $count, %substs ) = @_;
188    my ( $code, $n, $start );
189    foreach ( split( /\n/, $template ) ) {
190        $n     = $count;
191        $start = 0;
192        if (/^(.*)=(\w+)=(.*)/) {
193            my ( $pre, $key, $post ) = ( $1, $2, $3 );
194            if ( $key eq 'ARGS' ) {
195                my @params;
196                for my $i ( 0 .. $n - 1 ) {
197                    ( my $new = $substs{$key} ) =~ s/\<index\>/$i/g;
198                    push @params, $new;
199                }
200                $code .= $pre . join( ',', @params ) . "$post\n";
201                next;
202            }
203            $start = $n / 2 if ( $key eq 'TESTS2' );
204            for my $i ( $start .. $n - 1 ) {
205                ( my $new = $substs{$key} ) =~ s/\<index\>/$i/g;
206                $code .= "$pre$new$post\n";
207            }
208        }
209        else {
210            $code .= "$_\n";
211        }
212    }
213
214    return $code;
215}
216my $template2 = <<'TEMPLATE';
217.sub _main :main
218    =LOCALS=
219    =INITS=
220    _sub(=ARGS=)
221    =TESTS2=
222    end
223fail:
224    print "failed\n"
225    end
226.end
227.sub _sub
228    =PARAMS=
229    =TESTS=
230    print "all params ok\n"
231    .return()
232fail:
233    print "failed\n"
234    end
235.end
236TEMPLATE
237
238my $code = repeat(
239    $template2, 18,
240    LOCALS => ".local pmc a<index>\n\ta<index> = new 'Integer'",
241    INITS  => 'a<index> = <index>',
242    ARGS   => 'a<index>',
243    PARAMS => '.param pmc a<index>',
244    TESTS  => "set \$I0, a<index>\nne \$I0, <index>, fail",
245    TESTS2 => "set \$I0, a<index>\nne \$I0, <index>, fail"
246);
247
248pir_output_is( $code, <<'OUT', "overflow pmcs 18 spill" );
249all params ok
250OUT
251
252$code = repeat(
253    $template2, 22,
254    LOCALS => ".local pmc a<index>\n\ta<index> = new 'Integer'",
255    INITS  => 'a<index> = <index>',
256    ARGS   => 'a<index>',
257    PARAMS => '.param pmc a<index>',
258    TESTS  => "set \$I0, a<index>\nne \$I0, <index>, fail",
259    TESTS2 => "set \$I0, a<index>\nne \$I0, <index>, fail"
260);
261
262pir_output_is( $code, <<'OUT', "overflow pmcs 22 spill" );
263all params ok
264OUT
265
266$code = repeat(
267    $template2, 40,
268    LOCALS => ".local pmc a<index>\n\ta<index> = new 'Integer'",
269    INITS  => 'a<index> = <index>',
270    ARGS   => 'a<index>',
271    PARAMS => '.param pmc a<index>',
272    TESTS  => "set \$I0, a<index>\nne \$I0, <index>, fail",
273    TESTS2 => "set \$I0, a<index>\nne \$I0, <index>, fail"
274);
275
276pir_output_is( $code, <<'OUT', "overflow pmcs 40 spill" );
277all params ok
278OUT
279
280$code = repeat(
281    $template2, 60,
282    LOCALS => ".local pmc a<index>\n\ta<index> = new 'Integer'",
283    INITS  => 'a<index> = <index>',
284    ARGS   => 'a<index>',
285    PARAMS => '.param pmc a<index>',
286    TESTS  => "set \$I0, a<index>\nne \$I0, <index>, fail",
287    TESTS2 => "set \$I0, a<index>\nne \$I0, <index>, fail"
288);
289
290pir_output_is( $code, <<'OUT', "overflow pmcs 60 spill" );
291all params ok
292OUT
293
294# Local Variables:
295#   mode: cperl
296#   cperl-indent-level: 4
297#   fill-column: 100
298# End:
299# vim: expandtab shiftwidth=4:
300