This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add the missing ${^OPEN} hints flag to B::Concise
[perl5.git] / ext / B / t / optree_constants.t
CommitLineData
d51cf0c9
JC
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
JC
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
JC
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
46my $want = { # expected types, how value renders in-line, todos (maybe)
47 myfl => [ 'NV', myfl ],
48 myint => [ 'IV', myint ],
49 mystr => [ 'PV', '"'.mystr.'"' ],
50 myhref => [ 'RV', '\\\\HASH'],
51 myundef => [ 'NULL', ],
52 pi => [ 'NV', pi ],
53 # these have todos, since they render as a bare backslash
54 myaref => [ 'RV', '\\\\', ' - should render as \\ARRAY' ],
55 myglob => [ 'RV', '\\\\', ' - should render as \\GV' ],
56 myrex => [ 'RV', '\\\\', ' - should render as ??' ],
57 mysub => [ 'RV', '\\\\', ' - should render as \\CV' ],
58 myunsub => [ 'RV', '\\\\', ' - should render as \\CV' ],
59 # these are not inlined, at least not per BC::Concise
60 #myyes => [ 'RV', ],
61 #myno => [ 'RV', ],
d51cf0c9
JC
62};
63
64use constant WEEKDAYS
65 => qw ( Sunday Monday Tuesday Wednesday Thursday Friday Saturday );
66
67
d51cf0c9
JC
68$::{napier} = \2.71828; # counter-example (doesn't get optimized).
69eval "sub napier ();";
70
71
72# should be able to undefine constant::import here ???
73INIT {
74 # eval 'sub constant::import () {}';
75 # undef *constant::import::{CODE};
76};
77
78#################################
f9f861ec 79pass("RENDER CONSTANT SUBS RETURNING SCALARS");
2018a5c3 80
f9f861ec
JC
81for $func (sort keys %$want) {
82 # no strict 'refs'; # why not needed ?
83 checkOptree ( name => "$func() as a coderef",
84 code => \&{$func},
85 noanchors => 1,
86 expect => <<EOT_EOT, expect_nt => <<EONT_EONT);
87 is a constant sub, optimized to a $want->{$func}[0]
2018a5c3 88EOT_EOT
f9f861ec 89 is a constant sub, optimized to a $want->{$func}[0]
d51cf0c9
JC
90EONT_EONT
91
f9f861ec 92}
d51cf0c9 93
f9f861ec 94pass("RENDER CALLS TO THOSE CONSTANT SUBS");
d51cf0c9 95
f9f861ec
JC
96for $func (sort keys %$want) {
97 # print "# doing $func\n";
98 checkOptree ( name => "call $func",
99 code => "$func",
100 ($want->{$func}[2]) ? ( todo => $want->{$func}[2]) : (),
101 bc_opts => '-nobanner',
102 expect => <<EOT_EOT, expect_nt => <<EONT_EONT);
d51cf0c9 1033 <1> leavesub[2 refs] K/REFC,1 ->(end)
f9f861ec 104- <\@> lineseq KP ->3
d51cf0c9 1051 <;> dbstate(main 1163 OptreeCheck.pm:511]:1) v ->2
f9f861ec 1062 <\$> const[$want->{$func}[0] $want->{$func}[1]] s ->3
d51cf0c9
JC
107EOT_EOT
1083 <1> leavesub[2 refs] K/REFC,1 ->(end)
f9f861ec 109- <\@> lineseq KP ->3
d51cf0c9 1101 <;> dbstate(main 1163 OptreeCheck.pm:511]:1) v ->2
f9f861ec 1112 <\$> const($want->{$func}[0] $want->{$func}[1]) s ->3
d51cf0c9
JC
112EONT_EONT
113
f9f861ec 114}
d51cf0c9 115
f9f861ec
JC
116##############
117pass("MORE TESTS");
d51cf0c9 118
f9f861ec
JC
119checkOptree ( name => 'myyes() as coderef',
120 code => sub () { 1==1 },
2018a5c3
JC
121 noanchors => 1,
122 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
f9f861ec 123 is a constant sub, optimized to a SPECIAL
2018a5c3 124EOT_EOT
f9f861ec 125 is a constant sub, optimized to a SPECIAL
2018a5c3
JC
126EONT_EONT
127
128
f9f861ec
JC
129checkOptree ( name => 'myyes() as coderef',
130 code => 'sub a() { 1==1 }; print a',
2018a5c3
JC
131 noanchors => 1,
132 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
f9f861ec
JC
133# 5 <1> leavesub[1 ref] K/REFC,1 ->(end)
134# - <@> lineseq KP ->5
135# 1 <;> nextstate(main 810 (eval 47):1) v ->2
136# 4 <@> print sK ->5
137# 2 <0> pushmark s ->3
138# 3 <$> const[SPECIAL sv_yes] s ->4
2018a5c3 139EOT_EOT
f9f861ec
JC
140# 5 <1> leavesub[1 ref] K/REFC,1 ->(end)
141# - <@> lineseq KP ->5
142# 1 <;> nextstate(main 810 (eval 47):1) v ->2
143# 4 <@> print sK ->5
144# 2 <0> pushmark s ->3
145# 3 <$> const(SPECIAL sv_yes) s ->4
2018a5c3
JC
146EONT_EONT
147
d51cf0c9 148
f9f861ec
JC
149checkOptree ( name => 'myno() as coderef',
150 code => 'sub a() { 1!=1 }; print a',
d51cf0c9 151 noanchors => 1,
f9f861ec 152 todo => '- SPECIAL sv_no renders as PVNV 0',
d51cf0c9 153 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
f9f861ec
JC
154# 5 <1> leavesub[1 ref] K/REFC,1 ->(end)
155# - <@> lineseq KP ->5
156# 1 <;> nextstate(main 810 (eval 47):1) v ->2
157# 4 <@> print sK ->5
158# 2 <0> pushmark s ->3
159# 3 <$> const[PVNV 0] s ->4
d51cf0c9 160EOT_EOT
f9f861ec
JC
161# 5 <1> leavesub[1 ref] K/REFC,1 ->(end)
162# - <@> lineseq KP ->5
163# 1 <;> nextstate(main 810 (eval 47):1) v ->2
164# 4 <@> print sK ->5
165# 2 <0> pushmark s ->3
166# 3 <$> const(PVNV 0) s ->4
d51cf0c9
JC
167EONT_EONT
168
169
2018a5c3 170checkOptree ( name => 'constant sub returning list',
d51cf0c9
JC
171 code => \&WEEKDAYS,
172 noanchors => 1,
173 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
174# 3 <1> leavesub[2 refs] K/REFC,1 ->(end)
175# - <@> lineseq K ->3
d5ec2987 176# 1 <;> nextstate(constant 685 constant.pm:121) v:*,& ->2
d51cf0c9
JC
177# 2 <0> padav[@list:FAKE:m:102] ->3
178EOT_EOT
179# 3 <1> leavesub[2 refs] K/REFC,1 ->(end)
180# - <@> lineseq K ->3
d5ec2987 181# 1 <;> nextstate(constant 685 constant.pm:121) v:*,& ->2
d51cf0c9
JC
182# 2 <0> padav[@list:FAKE:m:76] ->3
183EONT_EONT
184
185
186sub printem {
187 printf "myint %d mystr %s myfl %f pi %f\n"
188 , myint, mystr, myfl, pi;
189}
190
2018a5c3 191checkOptree ( name => 'call many in a print statement',
d51cf0c9
JC
192 code => \&printem,
193 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
194# 9 <1> leavesub[1 ref] K/REFC,1 ->(end)
195# - <@> lineseq KP ->9
196# 1 <;> nextstate(main 635 optree_constants.t:163) v ->2
197# 8 <@> prtf sK ->9
198# 2 <0> pushmark s ->3
199# 3 <$> const[PV "myint %d mystr %s myfl %f pi %f\n"] s ->4
200# 4 <$> const[IV 42] s ->5
201# 5 <$> const[PV "hithere"] s ->6
f9f861ec 202# 6 <$> const[NV 1.414213] s ->7
d51cf0c9
JC
203# 7 <$> const[NV 3.14159] s ->8
204EOT_EOT
205# 9 <1> leavesub[1 ref] K/REFC,1 ->(end)
206# - <@> lineseq KP ->9
207# 1 <;> nextstate(main 635 optree_constants.t:163) v ->2
208# 8 <@> prtf sK ->9
209# 2 <0> pushmark s ->3
210# 3 <$> const(PV "myint %d mystr %s myfl %f pi %f\n") s ->4
211# 4 <$> const(IV 42) s ->5
212# 5 <$> const(PV "hithere") s ->6
f9f861ec 213# 6 <$> const(NV 1.414213) s ->7
d51cf0c9
JC
214# 7 <$> const(NV 3.14159) s ->8
215EONT_EONT
216
217
218} #skip
219
220__END__
221
222=head NB
223
224Optimized constant subs are stored as bare scalars in the stash
225(package hash), which formerly held only GVs (typeglobs).
226
227But you cant create them manually - you cant assign a scalar to a
228stash element, and expect it to work like a constant-sub, even if you
229provide a prototype.
230
231This is a feature; alternative is too much action-at-a-distance. The
232following test demonstrates - napier is not seen as a function at all,
233much less an optimized one.
234
235=cut
236
237checkOptree ( name => 'not evertnapier',
238 code => \&napier,
239 noanchors => 1,
240 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
241 has no START
242EOT_EOT
243 has no START
244EONT_EONT
245
246