[perl #56766] [PATCH]
[p5sagit/p5-mst-13.2.git] / ext / B / t / optree_constants.t
CommitLineData
d51cf0c9 1#!perl
2
3BEGIN {
4 if ($ENV{PERL_CORE}) {
5 chdir('t') if -d 't';
6 @INC = ('.', '../lib', '../ext/B/t');
7 } else {
8 unshift @INC, 't';
9 push @INC, "../../t";
10 }
11 require Config;
12 if (($Config::Config{'extensions'} !~ /\bB\b/) ){
13 print "1..0 # Skip -- Perl configured without B module\n";
14 exit 0;
15 }
16 # require 'test.pl'; # now done by OptreeCheck
17}
18
19use OptreeCheck; # ALSO DOES @ARGV HANDLING !!!!!!
20use Config;
21
f9f861ec 22my $tests = 30;
d51cf0c9 23plan tests => $tests;
24SKIP: {
25skip "no perlio in this build", $tests unless $Config::Config{useperlio};
26
27#################################
28
29use constant { # see also t/op/gv.t line 282
f9f861ec 30 myaref => [ 1,2,3 ],
31 myfl => 1.414213,
32 myglob => \*STDIN,
33 myhref => { a => 1 },
34 myint => 42,
35 myrex => qr/foo/,
36 mystr => 'hithere',
37 mysub => \&ok,
38 myundef => undef,
39 myunsub => \&nosuch,
40};
41
42sub myyes() { 1==1 }
43sub myno () { return 1!=1 }
44sub pi () { 3.14159 };
45
4df7f6af 46my $RV_class = $] >= 5.011 ? 'IV' : 'RV';
47
f9f861ec 48my $want = { # expected types, how value renders in-line, todos (maybe)
f9f861ec 49 mystr => [ 'PV', '"'.mystr.'"' ],
4df7f6af 50 myhref => [ $RV_class, '\\\\HASH'],
f9f861ec 51 pi => [ 'NV', pi ],
4df7f6af 52 myglob => [ $RV_class, '\\\\' ],
53 mysub => [ $RV_class, '\\\\' ],
54 myunsub => [ $RV_class, '\\\\' ],
f9f861ec 55 # these are not inlined, at least not per BC::Concise
4df7f6af 56 #myyes => [ $RV_class, ],
57 #myno => [ $RV_class, ],
e412117e 58 $] > 5.009 ? (
4df7f6af 59 myaref => [ $RV_class, '\\\\' ],
e412117e 60 myfl => [ 'NV', myfl ],
61 myint => [ 'IV', myint ],
f7c278bf 62 $] >= 5.011 ? (
63 myrex => [ $RV_class, '\\\\"\\(?-xism:Foo\\)"' ],
64 ) : (
4df7f6af 65 myrex => [ $RV_class, '\\\\' ],
f7c278bf 66 ),
e412117e 67 myundef => [ 'NULL', ],
68 ) : (
69 myaref => [ 'PVIV', '' ],
70 myfl => [ 'PVNV', myfl ],
71 myint => [ 'PVIV', myint ],
72 myrex => [ 'PVNV', '' ],
73 myundef => [ 'PVIV', ],
74 )
d51cf0c9 75};
76
77use constant WEEKDAYS
78 => qw ( Sunday Monday Tuesday Wednesday Thursday Friday Saturday );
79
80
d51cf0c9 81$::{napier} = \2.71828; # counter-example (doesn't get optimized).
82eval "sub napier ();";
83
84
85# should be able to undefine constant::import here ???
86INIT {
87 # eval 'sub constant::import () {}';
88 # undef *constant::import::{CODE};
89};
90
91#################################
f9f861ec 92pass("RENDER CONSTANT SUBS RETURNING SCALARS");
2018a5c3 93
f9f861ec 94for $func (sort keys %$want) {
95 # no strict 'refs'; # why not needed ?
96 checkOptree ( name => "$func() as a coderef",
97 code => \&{$func},
98 noanchors => 1,
99 expect => <<EOT_EOT, expect_nt => <<EONT_EONT);
100 is a constant sub, optimized to a $want->{$func}[0]
2018a5c3 101EOT_EOT
f9f861ec 102 is a constant sub, optimized to a $want->{$func}[0]
d51cf0c9 103EONT_EONT
104
f9f861ec 105}
d51cf0c9 106
f9f861ec 107pass("RENDER CALLS TO THOSE CONSTANT SUBS");
d51cf0c9 108
f9f861ec 109for $func (sort keys %$want) {
110 # print "# doing $func\n";
111 checkOptree ( name => "call $func",
112 code => "$func",
113 ($want->{$func}[2]) ? ( todo => $want->{$func}[2]) : (),
114 bc_opts => '-nobanner',
115 expect => <<EOT_EOT, expect_nt => <<EONT_EONT);
d51cf0c9 1163 <1> leavesub[2 refs] K/REFC,1 ->(end)
f9f861ec 117- <\@> lineseq KP ->3
be2b1c74 1181 <;> dbstate(main 833 (eval 44):1) v ->2
f9f861ec 1192 <\$> const[$want->{$func}[0] $want->{$func}[1]] s ->3
d51cf0c9 120EOT_EOT
1213 <1> leavesub[2 refs] K/REFC,1 ->(end)
f9f861ec 122- <\@> lineseq KP ->3
be2b1c74 1231 <;> dbstate(main 833 (eval 44):1) v ->2
f9f861ec 1242 <\$> const($want->{$func}[0] $want->{$func}[1]) s ->3
d51cf0c9 125EONT_EONT
126
f9f861ec 127}
d51cf0c9 128
f9f861ec 129##############
130pass("MORE TESTS");
d51cf0c9 131
f9f861ec 132checkOptree ( name => 'myyes() as coderef',
133 code => sub () { 1==1 },
2018a5c3 134 noanchors => 1,
135 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
f9f861ec 136 is a constant sub, optimized to a SPECIAL
2018a5c3 137EOT_EOT
f9f861ec 138 is a constant sub, optimized to a SPECIAL
2018a5c3 139EONT_EONT
140
141
f9f861ec 142checkOptree ( name => 'myyes() as coderef',
36932700 143 prog => 'sub a() { 1==1 }; print a',
2018a5c3 144 noanchors => 1,
e412117e 145 strip_open_hints => 1,
2018a5c3 146 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
36932700 147# 6 <@> leave[1 ref] vKP/REFC ->(end)
148# 1 <0> enter ->2
e412117e 149# 2 <;> nextstate(main 2 -e:1) v:>,<,%,{ ->3
36932700 150# 5 <@> print vK ->6
151# 3 <0> pushmark s ->4
152# 4 <$> const[SPECIAL sv_yes] s ->5
2018a5c3 153EOT_EOT
36932700 154# 6 <@> leave[1 ref] vKP/REFC ->(end)
155# 1 <0> enter ->2
e412117e 156# 2 <;> nextstate(main 2 -e:1) v:>,<,%,{ ->3
36932700 157# 5 <@> print vK ->6
158# 3 <0> pushmark s ->4
159# 4 <$> const(SPECIAL sv_yes) s ->5
2018a5c3 160EONT_EONT
161
d51cf0c9 162
36932700 163# Need to do this as a prog, not code, as only the first constant to use
164# PL_sv_no actually gets to use the real thing - every one following is
165# copied.
f9f861ec 166checkOptree ( name => 'myno() as coderef',
36932700 167 prog => 'sub a() { 1!=1 }; print a',
d51cf0c9 168 noanchors => 1,
e412117e 169 strip_open_hints => 1,
d51cf0c9 170 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
36932700 171# 6 <@> leave[1 ref] vKP/REFC ->(end)
172# 1 <0> enter ->2
e412117e 173# 2 <;> nextstate(main 2 -e:1) v:>,<,%,{ ->3
36932700 174# 5 <@> print vK ->6
175# 3 <0> pushmark s ->4
176# 4 <$> const[SPECIAL sv_no] s ->5
d51cf0c9 177EOT_EOT
36932700 178# 6 <@> leave[1 ref] vKP/REFC ->(end)
179# 1 <0> enter ->2
e412117e 180# 2 <;> nextstate(main 2 -e:1) v:>,<,%,{ ->3
36932700 181# 5 <@> print vK ->6
182# 3 <0> pushmark s ->4
183# 4 <$> const(SPECIAL sv_no) s ->5
d51cf0c9 184EONT_EONT
185
186
e412117e 187my ($expect, $expect_nt) = (<<'EOT_EOT', <<'EONT_EONT');
d51cf0c9 188# 3 <1> leavesub[2 refs] K/REFC,1 ->(end)
189# - <@> lineseq K ->3
dbeafbd1 190# 1 <;> nextstate(constant 61 constant.pm:118) v:*,& ->2
191# 2 <0> padav[@list:FAKE:m:96] ->3
d51cf0c9 192EOT_EOT
193# 3 <1> leavesub[2 refs] K/REFC,1 ->(end)
194# - <@> lineseq K ->3
dbeafbd1 195# 1 <;> nextstate(constant 61 constant.pm:118) v:*,& ->2
196# 2 <0> padav[@list:FAKE:m:71] ->3
d51cf0c9 197EONT_EONT
198
e412117e 199if($] < 5.009) {
200 # 5.8.x doesn't add the m flag to padav
201 s/FAKE:m:\d+/FAKE/ foreach ($expect, $expect_nt);
202}
203
204checkOptree ( name => 'constant sub returning list',
205 code => \&WEEKDAYS,
206 noanchors => 1,
207 expect => $expect, expect_nt => $expect_nt);
208
d51cf0c9 209
210sub printem {
211 printf "myint %d mystr %s myfl %f pi %f\n"
212 , myint, mystr, myfl, pi;
213}
214
e412117e 215my ($expect, $expect_nt) = (<<'EOT_EOT', <<'EONT_EONT');
d51cf0c9 216# 9 <1> leavesub[1 ref] K/REFC,1 ->(end)
217# - <@> lineseq KP ->9
be2b1c74 218# 1 <;> nextstate(main 635 optree_constants.t:163) v:>,<,% ->2
d51cf0c9 219# 8 <@> prtf sK ->9
220# 2 <0> pushmark s ->3
221# 3 <$> const[PV "myint %d mystr %s myfl %f pi %f\n"] s ->4
222# 4 <$> const[IV 42] s ->5
223# 5 <$> const[PV "hithere"] s ->6
f9f861ec 224# 6 <$> const[NV 1.414213] s ->7
d51cf0c9 225# 7 <$> const[NV 3.14159] s ->8
226EOT_EOT
227# 9 <1> leavesub[1 ref] K/REFC,1 ->(end)
228# - <@> lineseq KP ->9
be2b1c74 229# 1 <;> nextstate(main 635 optree_constants.t:163) v:>,<,% ->2
d51cf0c9 230# 8 <@> prtf sK ->9
231# 2 <0> pushmark s ->3
232# 3 <$> const(PV "myint %d mystr %s myfl %f pi %f\n") s ->4
233# 4 <$> const(IV 42) s ->5
234# 5 <$> const(PV "hithere") s ->6
f9f861ec 235# 6 <$> const(NV 1.414213) s ->7
d51cf0c9 236# 7 <$> const(NV 3.14159) s ->8
237EONT_EONT
238
e412117e 239if($] < 5.009) {
240 # 5.8.x's use constant has larger types
241 foreach ($expect, $expect_nt) {
242 s/IV 42/PV$&/;
243 s/NV 1.41/PV$&/;
244 }
245}
246
247checkOptree ( name => 'call many in a print statement',
248 code => \&printem,
249 strip_open_hints => 1,
250 expect => $expect, expect_nt => $expect_nt);
d51cf0c9 251
252} #skip
253
254__END__
255
256=head NB
257
258Optimized constant subs are stored as bare scalars in the stash
259(package hash), which formerly held only GVs (typeglobs).
260
261But you cant create them manually - you cant assign a scalar to a
262stash element, and expect it to work like a constant-sub, even if you
263provide a prototype.
264
265This is a feature; alternative is too much action-at-a-distance. The
266following test demonstrates - napier is not seen as a function at all,
267much less an optimized one.
268
269=cut
270
271checkOptree ( name => 'not evertnapier',
272 code => \&napier,
273 noanchors => 1,
274 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
275 has no START
276EOT_EOT
277 has no START
278EONT_EONT
279
280