6 if (($Config::Config{'extensions'} !~ /\bB\b/) ){
7 print "1..0 # Skip -- Perl configured without B module\n";
16 skip "no perlio in this build", 4 unless $Config::Config{useperlio};
18 # The regression this was testing is that the first aelemfast, derived
19 # from a lexical array, is supposed to be a BASEOP "<0>", while the
20 # second, from a global, is an SVOP "<$>" or a PADOP "<#>" depending
21 # on threading. In buggy versions, both showed up as SVOPs/PADOPs. See
22 # B.xs:cc_opclass() for the relevant code.
24 # All this is much simpler, now that aelemfast_lex has been broken out from
26 checkOptree ( name => 'OP_AELEMFAST opclass',
27 code => sub { my @x; our @y; $x[127] + $y[-128]},
28 strip_open_hints => 1,
29 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
30 # 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
31 # - <@> lineseq KP ->7
32 # 1 <;> nextstate(main 634 optree_misc.t:25) v:>,<,% ->2
33 # 2 <0> padav[@x:634,636] vM/LVINTRO ->3
34 # - <;> ex-nextstate(main 1594 optree_misc.t:27) v:>,<,% ->3
35 # - <1> rv2av[t4] vK/OURINTR,1 ->3
37 # 3 <;> nextstate(main 636 optree_misc.t:25) v:>,<,%,{ ->4
38 # 6 <2> add[t6] sK/2 ->7
39 # - <1> ex-aelem sK/2 ->5
40 # 4 <0> aelemfast_lex[@x:634,636] sR/key=127 ->5
41 # - <0> ex-const s ->-
42 # - <1> ex-aelem sK/2 ->6
43 # - <1> ex-rv2av sKR/1 ->-
44 # 5 <#> aelemfast[*y] s/key=128 ->6
45 # - <0> ex-const s/FOLD ->-
47 # 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
48 # - <@> lineseq KP ->7
49 # 1 <;> nextstate(main 634 optree_misc.t:27) v:>,<,% ->2
50 # 2 <0> padav[@x:634,636] vM/LVINTRO ->3
51 # - <;> ex-nextstate(main 1594 optree_misc.t:27) v:>,<,% ->3
52 # - <1> rv2av[t3] vK/OURINTR,1 ->3
54 # 3 <;> nextstate(main 636 optree_misc.t:27) v:>,<,%,{ ->4
55 # 6 <2> add[t4] sK/2 ->7
56 # - <1> ex-aelem sK/2 ->5
57 # 4 <0> aelemfast_lex[@x:634,636] sR/key=127 ->5
58 # - <0> ex-const s ->-
59 # - <1> ex-aelem sK/2 ->6
60 # - <1> ex-rv2av sKR/1 ->-
61 # 5 <$> aelemfast(*y) s/key=128 ->6
62 # - <0> ex-const s/FOLD ->-
65 checkOptree ( name => 'PMOP children',
66 code => sub { $foo =~ s/(a)/$1/ },
67 strip_open_hints => 1,
68 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
69 # 5 <1> leavesub[1 ref] K/REFC,1 ->(end)
70 # - <@> lineseq KP ->5
71 # 1 <;> nextstate(main 1 -e:1) v:>,<,%,{ ->2
72 # 4 </> subst(/"(a)"/) sKS ->5
73 # - <1> ex-rv2sv sKRM/1 ->3
74 # 2 <#> gvsv[*foo] s ->3
75 # - <1> ex-rv2sv sK/1 ->4
76 # 3 <#> gvsv[*1] s ->4
78 # 5 <1> leavesub[1 ref] K/REFC,1 ->(end)
79 # - <@> lineseq KP ->5
80 # 1 <;> nextstate(main 1 -e:1) v:>,<,%,{ ->2
81 # 4 </> subst(/"(a)"/) sKS ->5
82 # - <1> ex-rv2sv sKRM/1 ->3
83 # 2 <$> gvsv(*foo) s ->3
84 # - <1> ex-rv2sv sK/1 ->4
85 # 3 <$> gvsv(*1) s ->4
91 # 8 <@> leave[1 ref] vKP/REFC ->(end)
93 # 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ ->3
94 # 7 <2> sassign vKS/2 ->8
95 # 5 <@> index[t2] sK/2 ->6
96 # - <0> ex-pushmark s ->3
97 # 3 <$> const[PV "foo"] s ->4
98 # 4 <$> const[PVMG "foo"] s ->5
99 # - <1> ex-rv2sv sKRM*/1 ->7
100 # 6 <#> gvsv[*_] s ->7
102 my $nt = <<'EONT_EONT';
103 # 8 <@> leave[1 ref] vKP/REFC ->(end)
105 # 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ ->3
106 # 7 <2> sassign vKS/2 ->8
107 # 5 <@> index[t1] sK/2 ->6
108 # - <0> ex-pushmark s ->3
109 # 3 <$> const(PV "foo") s ->4
110 # 4 <$> const(PVMG "foo") s ->5
111 # - <1> ex-rv2sv sKRM*/1 ->7
112 # 6 <$> gvsv(*_) s ->7
115 checkOptree ( name => 'index and PVBM',
116 prog => '$_ = index q(foo), q(foo)',
117 strip_open_hints => 1,
118 expect => $t, expect_nt => $nt);
120 my $tmpfile = tempfile();
121 open my $fh, '>', $tmpfile or die "Cannot open $tmpfile: $!";
122 print $fh "no warnings;format =\n@<<<\n\$a\n@>>>\n\@b\n.";
125 checkOptree ( name => 'formats',
127 progfile => $tmpfile,
128 strip_open_hints => 1,
129 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
130 # main::STDOUT (FORMAT):
131 # c <1> leavewrite[1 ref] K/REFC,1 ->(end)
132 # - <@> lineseq KP ->c
133 # 1 <;> nextstate(main 1 -:4) v:>,<,% ->2
134 # 5 <@> formline vK/2 ->6
135 # 2 <0> pushmark s ->3
136 # 3 <$> const[PV "@<<<\n"] s ->4
137 # - <@> lineseq lK ->5
138 # - <;> ex-nextstate(main 3 tmp35894B:3) v:>,<,% ->4
139 # - <1> ex-rv2sv sK/1 ->-
140 # 4 <#> gvsv[*a] s ->5
141 # 6 <;> nextstate(main 1 -:6) v:>,<,% ->7
142 # b <@> formline sK/2 ->c
143 # 7 <0> pushmark s ->8
144 # 8 <$> const[PV "@>>>\n"] s ->9
145 # - <@> lineseq lK ->b
146 # - <;> ex-nextstate(main 3 tmp35894B:5) v:>,<,% ->9
147 # a <1> rv2av[t3] lK/1 ->b
150 # main::STDOUT (FORMAT):
151 # c <1> leavewrite[1 ref] K/REFC,1 ->(end)
152 # - <@> lineseq KP ->c
153 # 1 <;> nextstate(main 1 -:4) v:>,<,% ->2
154 # 5 <@> formline vK/2 ->6
155 # 2 <0> pushmark s ->3
156 # 3 <$> const(PV "@<<<\n") s ->4
157 # - <@> lineseq lK ->5
158 # - <;> ex-nextstate(main 3 tmp35894B:3) v:>,<,% ->4
159 # - <1> ex-rv2sv sK/1 ->-
160 # 4 <$> gvsv(*a) s ->5
161 # 6 <;> nextstate(main 1 -:6) v:>,<,% ->7
162 # b <@> formline sK/2 ->c
163 # 7 <0> pushmark s ->8
164 # 8 <$> const(PV "@>>>\n") s ->9
165 # - <@> lineseq lK ->b
166 # - <;> ex-nextstate(main 3 tmp35894B:5) v:>,<,% ->9
167 # a <1> rv2av[t3] lK/1 ->b
171 checkOptree ( name => 'padrange',
172 code => sub { my ($x,$y); @a = ($x,$y); ($x,$y) = @a },
173 strip_open_hints => 1,
174 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
175 # f <1> leavesub[1 ref] K/REFC,1 ->(end)
176 # - <@> lineseq KP ->f
177 # 1 <;> nextstate(main 1 -e:1) v:>,<,% ->2
179 # 2 <0> padrange[$x:1,2; $y:1,2] vM/LVINTRO,range=2 ->3
180 # - <0> padsv[$x:1,2] vM/LVINTRO ->-
181 # - <0> padsv[$y:1,2] vM/LVINTRO ->-
182 # 3 <;> nextstate(main 2 -e:1) v:>,<,% ->4
183 # 8 <2> aassign[t4] vKS/COM_AGG ->9
184 # - <1> ex-list lKP ->5
185 # 4 <0> padrange[$x:1,2; $y:1,2] /range=2 ->5
186 # - <0> padsv[$x:1,2] s ->-
187 # - <0> padsv[$y:1,2] s ->-
188 # - <1> ex-list lK ->8
189 # 5 <0> pushmark s ->6
190 # 7 <1> rv2av[t3] lKRM*/1 ->8
192 # 9 <;> nextstate(main 2 -e:1) v:>,<,%,{ ->a
193 # e <2> aassign[t6] KS/COM_RC1 ->f
194 # - <1> ex-list lK ->d
195 # a <0> pushmark s ->b
196 # c <1> rv2av[t5] lK/1 ->d
198 # - <1> ex-list lKPRM* ->e
199 # d <0> padrange[$x:1,2; $y:1,2] RM/range=2 ->e
200 # - <0> padsv[$x:1,2] sRM* ->-
201 # - <0> padsv[$y:1,2] sRM* ->-
203 # f <1> leavesub[1 ref] K/REFC,1 ->(end)
204 # - <@> lineseq KP ->f
205 # 1 <;> nextstate(main 1 -e:1) v:>,<,% ->2
207 # 2 <0> padrange[$x:1,2; $y:1,2] vM/LVINTRO,range=2 ->3
208 # - <0> padsv[$x:1,2] vM/LVINTRO ->-
209 # - <0> padsv[$y:1,2] vM/LVINTRO ->-
210 # 3 <;> nextstate(main 2 -e:1) v:>,<,% ->4
211 # 8 <2> aassign[t4] vKS/COM_AGG ->9
212 # - <1> ex-list lKP ->5
213 # 4 <0> padrange[$x:1,2; $y:1,2] /range=2 ->5
214 # - <0> padsv[$x:1,2] s ->-
215 # - <0> padsv[$y:1,2] s ->-
216 # - <1> ex-list lK ->8
217 # 5 <0> pushmark s ->6
218 # 7 <1> rv2av[t3] lKRM*/1 ->8
220 # 9 <;> nextstate(main 2 -e:1) v:>,<,%,{ ->a
221 # e <2> aassign[t6] KS/COM_RC1 ->f
222 # - <1> ex-list lK ->d
223 # a <0> pushmark s ->b
224 # c <1> rv2av[t5] lK/1 ->d
226 # - <1> ex-list lKPRM* ->e
227 # d <0> padrange[$x:1,2; $y:1,2] RM/range=2 ->e
228 # - <0> padsv[$x:1,2] sRM* ->-
229 # - <0> padsv[$y:1,2] sRM* ->-
232 checkOptree ( name => 'padrange and @_',
233 code => sub { my ($a,$b) = @_;
238 strip_open_hints => 1,
239 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
240 # d <1> leavesub[1 ref] K/REFC,1 ->(end)
241 # - <@> lineseq KP ->d
242 # 1 <;> nextstate(main 1 p3:1) v:>,<,% ->2
243 # 3 <2> aassign[t5] vKS ->4
244 # - <1> ex-list lK ->-
245 # 2 <0> padrange[$a:1,4; $b:1,4] */LVINTRO,range=2 ->3
246 # - <1> rv2av[t4] lK/1 ->-
248 # - <1> ex-list lKPRM* ->3
249 # - <0> pushmark sRM*/LVINTRO ->-
250 # - <0> padsv[$a:1,4] sRM*/LVINTRO ->-
251 # - <0> padsv[$b:1,4] sRM*/LVINTRO ->-
252 # 4 <;> nextstate(main 2 p3:2) v:>,<,% ->5
253 # 9 <2> aassign[t10] vKS/COM_RC1 ->a
254 # - <1> ex-list lK ->8
255 # 5 <0> pushmark s ->6
256 # 7 <1> rv2av[t9] lK/1 ->8
257 # 6 <#> gv[*X::_] s ->7
258 # - <1> ex-list lKPRM* ->9
259 # 8 <0> padrange[$c:2,4; $d:2,4] RM/LVINTRO,range=2 ->9
260 # - <0> padsv[$c:2,4] sRM*/LVINTRO ->-
261 # - <0> padsv[$d:2,4] sRM*/LVINTRO ->-
262 # a <;> nextstate(Y 3 p3:4) v:>,<,%,{ ->b
263 # c <2> aassign[t15] KS ->d
264 # - <1> ex-list lK ->-
265 # b <0> padrange[$e:3,4; $f:3,4] */LVINTRO,range=2 ->c
266 # - <1> rv2av[t14] lK/1 ->-
268 # - <1> ex-list lKPRM* ->c
269 # - <0> pushmark sRM*/LVINTRO ->-
270 # - <0> padsv[$e:3,4] sRM*/LVINTRO ->-
271 # - <0> padsv[$f:3,4] sRM*/LVINTRO ->-
273 # d <1> leavesub[1 ref] K/REFC,1 ->(end)
274 # - <@> lineseq KP ->d
275 # 1 <;> nextstate(main 1 p3:1) v:>,<,% ->2
276 # 3 <2> aassign[t5] vKS ->4
277 # - <1> ex-list lK ->-
278 # 2 <0> padrange[$a:1,4; $b:1,4] */LVINTRO,range=2 ->3
279 # - <1> rv2av[t4] lK/1 ->-
281 # - <1> ex-list lKPRM* ->3
282 # - <0> pushmark sRM*/LVINTRO ->-
283 # - <0> padsv[$a:1,4] sRM*/LVINTRO ->-
284 # - <0> padsv[$b:1,4] sRM*/LVINTRO ->-
285 # 4 <;> nextstate(main 2 p3:2) v:>,<,% ->5
286 # 9 <2> aassign[t10] vKS/COM_RC1 ->a
287 # - <1> ex-list lK ->8
288 # 5 <0> pushmark s ->6
289 # 7 <1> rv2av[t9] lK/1 ->8
290 # 6 <$> gv(*X::_) s ->7
291 # - <1> ex-list lKPRM* ->9
292 # 8 <0> padrange[$c:2,4; $d:2,4] RM/LVINTRO,range=2 ->9
293 # - <0> padsv[$c:2,4] sRM*/LVINTRO ->-
294 # - <0> padsv[$d:2,4] sRM*/LVINTRO ->-
295 # a <;> nextstate(Y 3 p3:4) v:>,<,%,{ ->b
296 # c <2> aassign[t15] KS ->d
297 # - <1> ex-list lK ->-
298 # b <0> padrange[$e:3,4; $f:3,4] */LVINTRO,range=2 ->c
299 # - <1> rv2av[t14] lK/1 ->-
301 # - <1> ex-list lKPRM* ->c
302 # - <0> pushmark sRM*/LVINTRO ->-
303 # - <0> padsv[$e:3,4] sRM*/LVINTRO ->-
304 # - <0> padsv[$f:3,4] sRM*/LVINTRO ->-
307 checkOptree ( name => 'consolidate padranges',
308 code => sub { my ($a,$b); my ($c,$d); 1 },
309 strip_open_hints => 1,
310 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
311 # 5 <1> leavesub[1 ref] K/REFC,1 ->(end)
312 # - <@> lineseq KP ->5
313 # 1 <;> nextstate(main 900 optree_misc.t:334) v:>,<,% ->2
315 # 2 <0> padrange[$a:900,902; $b:900,902; $c:901,902; $d:901,902] vM/LVINTRO,range=4 ->3
316 # - <0> padsv[$a:900,902] vM/LVINTRO ->-
317 # - <0> padsv[$b:900,902] vM/LVINTRO ->-
318 # - <;> nextstate(main 901 optree_misc.t:334) v:>,<,% ->-
320 # - <0> pushmark vM/LVINTRO ->-
321 # - <0> padsv[$c:901,902] vM/LVINTRO ->-
322 # - <0> padsv[$d:901,902] vM/LVINTRO ->-
323 # 3 <;> nextstate(main 902 optree_misc.t:334) v:>,<,%,{ ->4
324 # 4 <$> const[IV 1] s ->5
326 # 5 <1> leavesub[1 ref] K/REFC,1 ->(end)
327 # - <@> lineseq KP ->5
328 # 1 <;> nextstate(main 900 optree_misc.t:334) v:>,<,% ->2
330 # 2 <0> padrange[$a:900,902; $b:900,902; $c:901,902; $d:901,902] vM/LVINTRO,range=4 ->3
331 # - <0> padsv[$a:900,902] vM/LVINTRO ->-
332 # - <0> padsv[$b:900,902] vM/LVINTRO ->-
333 # - <;> nextstate(main 901 optree_misc.t:334) v:>,<,% ->-
335 # - <0> pushmark vM/LVINTRO ->-
336 # - <0> padsv[$c:901,902] vM/LVINTRO ->-
337 # - <0> padsv[$d:901,902] vM/LVINTRO ->-
338 # 3 <;> nextstate(main 902 optree_misc.t:334) v:>,<,%,{ ->4
339 # 4 <$> const(IV 1) s ->5
343 checkOptree ( name => 'consolidate padranges and singletons',
344 code => sub { my ($a,$b); my $c; my ($d,$e);
345 my @f; my $g; my ($h,$i); my %j; 1 },
346 strip_open_hints => 1,
347 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
348 # 5 <1> leavesub[1 ref] K/REFC,1 ->(end)
349 # - <@> lineseq KP ->5
350 # 1 <;> nextstate(main 903 optree_misc.t:371) v:>,<,% ->2
352 # 2 <0> padrange[$a:903,910; $b:903,910; $c:904,910; $d:905,910; $e:905,910; @f:906,910; $g:907,910; $h:908,910; $i:908,910; %j:909,910] vM/LVINTRO,range=10 ->3
353 # - <0> padsv[$a:903,910] vM/LVINTRO ->-
354 # - <0> padsv[$b:903,910] vM/LVINTRO ->-
355 # - <;> nextstate(main 904 optree_misc.t:371) v:>,<,% ->-
356 # - <0> padsv[$c:904,910] vM/LVINTRO ->-
357 # - <;> nextstate(main 905 optree_misc.t:371) v:>,<,%,{ ->-
359 # - <0> pushmark vM/LVINTRO ->-
360 # - <0> padsv[$d:905,910] vM/LVINTRO ->-
361 # - <0> padsv[$e:905,910] vM/LVINTRO ->-
362 # - <;> nextstate(main 906 optree_misc.t:372) v:>,<,%,{ ->-
363 # - <0> padav[@f:906,910] vM/LVINTRO ->-
364 # - <;> nextstate(main 907 optree_misc.t:372) v:>,<,%,{ ->-
365 # - <0> padsv[$g:907,910] vM/LVINTRO ->-
366 # - <;> nextstate(main 908 optree_misc.t:372) v:>,<,%,{ ->-
368 # - <0> pushmark vM/LVINTRO ->-
369 # - <0> padsv[$h:908,910] vM/LVINTRO ->-
370 # - <0> padsv[$i:908,910] vM/LVINTRO ->-
371 # - <;> nextstate(main 909 optree_misc.t:372) v:>,<,%,{ ->-
372 # - <0> padhv[%j:909,910] vM/LVINTRO ->3
373 # 3 <;> nextstate(main 910 optree_misc.t:372) v:>,<,%,{ ->4
374 # 4 <$> const[IV 1] s ->5
376 # 5 <1> leavesub[1 ref] K/REFC,1 ->(end)
377 # - <@> lineseq KP ->5
378 # 1 <;> nextstate(main 903 optree_misc.t:371) v:>,<,% ->2
380 # 2 <0> padrange[$a:903,910; $b:903,910; $c:904,910; $d:905,910; $e:905,910; @f:906,910; $g:907,910; $h:908,910; $i:908,910; %j:909,910] vM/LVINTRO,range=10 ->3
381 # - <0> padsv[$a:903,910] vM/LVINTRO ->-
382 # - <0> padsv[$b:903,910] vM/LVINTRO ->-
383 # - <;> nextstate(main 904 optree_misc.t:371) v:>,<,% ->-
384 # - <0> padsv[$c:904,910] vM/LVINTRO ->-
385 # - <;> nextstate(main 905 optree_misc.t:371) v:>,<,%,{ ->-
387 # - <0> pushmark vM/LVINTRO ->-
388 # - <0> padsv[$d:905,910] vM/LVINTRO ->-
389 # - <0> padsv[$e:905,910] vM/LVINTRO ->-
390 # - <;> nextstate(main 906 optree_misc.t:372) v:>,<,%,{ ->-
391 # - <0> padav[@f:906,910] vM/LVINTRO ->-
392 # - <;> nextstate(main 907 optree_misc.t:372) v:>,<,%,{ ->-
393 # - <0> padsv[$g:907,910] vM/LVINTRO ->-
394 # - <;> nextstate(main 908 optree_misc.t:372) v:>,<,%,{ ->-
396 # - <0> pushmark vM/LVINTRO ->-
397 # - <0> padsv[$h:908,910] vM/LVINTRO ->-
398 # - <0> padsv[$i:908,910] vM/LVINTRO ->-
399 # - <;> nextstate(main 909 optree_misc.t:372) v:>,<,%,{ ->-
400 # - <0> padhv[%j:909,910] vM/LVINTRO ->3
401 # 3 <;> nextstate(main 910 optree_misc.t:372) v:>,<,%,{ ->4
402 # 4 <$> const(IV 1) s ->5
406 checkOptree ( name => 'm?x?',
407 code => sub { m?x?; },
408 strip_open_hints => 1,
409 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
410 # 3 <1> leavesub[1 ref] K/REFC,1 ->(end)
411 # - <@> lineseq KP ->3
412 # 1 <;> nextstate(main 914 optree_misc.t:434) v:>,<,%,{ ->2
413 # 2 </> match(/"x"/) ->3
415 # 3 <1> leavesub[1 ref] K/REFC,1 ->(end)
416 # - <@> lineseq KP ->3
417 # 1 <;> nextstate(main 914 optree_misc.t:434) v:>,<,%,{ ->2
418 # 2 </> match(/"x"/) ->3