6 @INC = ('.', '../lib', '../ext/B/t');
12 if (($Config::Config{'extensions'} !~ /\bB\b/) ){
13 print "1..0 # Skip -- Perl configured without B module\n";
16 # require 'test.pl'; # now done by OptreeCheck
19 use OptreeCheck; # ALSO DOES @ARGV HANDLING !!!!!!
25 skip "no perlio in this build", $tests unless $Config::Config{useperlio};
27 #################################
29 use constant { # see also t/op/gv.t line 282
43 sub myno () { return 1!=1 }
44 sub pi () { 3.14159 };
46 my $RV_class = $] >= 5.011 ? 'IV' : 'RV';
48 my $want = { # expected types, how value renders in-line, todos (maybe)
49 mystr => [ 'PV', '"'.mystr.'"' ],
50 myhref => [ $RV_class, '\\\\HASH'],
52 myglob => [ $RV_class, '\\\\' ],
53 mysub => [ $RV_class, '\\\\' ],
54 myunsub => [ $RV_class, '\\\\' ],
55 # these are not inlined, at least not per BC::Concise
56 #myyes => [ $RV_class, ],
57 #myno => [ $RV_class, ],
59 myaref => [ $RV_class, '\\\\' ],
60 myfl => [ 'NV', myfl ],
61 myint => [ 'IV', myint ],
63 myrex => [ $RV_class, '\\\\"\\(?-xism:Foo\\)"' ],
65 myrex => [ $RV_class, '\\\\' ],
67 myundef => [ 'NULL', ],
69 myaref => [ 'PVIV', '' ],
70 myfl => [ 'PVNV', myfl ],
71 myint => [ 'PVIV', myint ],
72 myrex => [ 'PVNV', '' ],
73 myundef => [ 'PVIV', ],
78 => qw ( Sunday Monday Tuesday Wednesday Thursday Friday Saturday );
81 $::{napier} = \2.71828; # counter-example (doesn't get optimized).
82 eval "sub napier ();";
85 # should be able to undefine constant::import here ???
87 # eval 'sub constant::import () {}';
88 # undef *constant::import::{CODE};
91 #################################
92 pass("RENDER CONSTANT SUBS RETURNING SCALARS");
94 for $func (sort keys %$want) {
95 # no strict 'refs'; # why not needed ?
96 checkOptree ( name => "$func() as a coderef",
99 expect => <<EOT_EOT, expect_nt => <<EONT_EONT);
100 is a constant sub, optimized to a $want->{$func}[0]
102 is a constant sub, optimized to a $want->{$func}[0]
107 pass("RENDER CALLS TO THOSE CONSTANT SUBS");
109 for $func (sort keys %$want) {
110 # print "# doing $func\n";
111 checkOptree ( name => "call $func",
113 ($want->{$func}[2]) ? ( todo => $want->{$func}[2]) : (),
114 bc_opts => '-nobanner',
115 expect => <<EOT_EOT, expect_nt => <<EONT_EONT);
116 3 <1> leavesub[2 refs] K/REFC,1 ->(end)
117 - <\@> lineseq KP ->3
118 1 <;> dbstate(main 833 (eval 44):1) v ->2
119 2 <\$> const[$want->{$func}[0] $want->{$func}[1]] s ->3
121 3 <1> leavesub[2 refs] K/REFC,1 ->(end)
122 - <\@> lineseq KP ->3
123 1 <;> dbstate(main 833 (eval 44):1) v ->2
124 2 <\$> const($want->{$func}[0] $want->{$func}[1]) s ->3
132 checkOptree ( name => 'myyes() as coderef',
133 code => sub () { 1==1 },
135 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
136 is a constant sub, optimized to a SPECIAL
138 is a constant sub, optimized to a SPECIAL
142 checkOptree ( name => 'myyes() as coderef',
143 prog => 'sub a() { 1==1 }; print a',
145 strip_open_hints => 1,
146 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
147 # 6 <@> leave[1 ref] vKP/REFC ->(end)
149 # 2 <;> nextstate(main 2 -e:1) v:>,<,%,{ ->3
151 # 3 <0> pushmark s ->4
152 # 4 <$> const[SPECIAL sv_yes] s ->5
154 # 6 <@> leave[1 ref] vKP/REFC ->(end)
156 # 2 <;> nextstate(main 2 -e:1) v:>,<,%,{ ->3
158 # 3 <0> pushmark s ->4
159 # 4 <$> const(SPECIAL sv_yes) s ->5
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
166 checkOptree ( name => 'myno() as coderef',
167 prog => 'sub a() { 1!=1 }; print a',
169 strip_open_hints => 1,
170 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
171 # 6 <@> leave[1 ref] vKP/REFC ->(end)
173 # 2 <;> nextstate(main 2 -e:1) v:>,<,%,{ ->3
175 # 3 <0> pushmark s ->4
176 # 4 <$> const[SPECIAL sv_no] s ->5
178 # 6 <@> leave[1 ref] vKP/REFC ->(end)
180 # 2 <;> nextstate(main 2 -e:1) v:>,<,%,{ ->3
182 # 3 <0> pushmark s ->4
183 # 4 <$> const(SPECIAL sv_no) s ->5
187 my ($expect, $expect_nt) = (<<'EOT_EOT', <<'EONT_EONT');
188 # 3 <1> leavesub[2 refs] K/REFC,1 ->(end)
189 # - <@> lineseq K ->3
190 # 1 <;> nextstate(constant 61 constant.pm:118) v:*,& ->2
191 # 2 <0> padav[@list:FAKE:m:96] ->3
193 # 3 <1> leavesub[2 refs] K/REFC,1 ->(end)
194 # - <@> lineseq K ->3
195 # 1 <;> nextstate(constant 61 constant.pm:118) v:*,& ->2
196 # 2 <0> padav[@list:FAKE:m:71] ->3
200 # 5.8.x doesn't add the m flag to padav
201 s/FAKE:m:\d+/FAKE/ foreach ($expect, $expect_nt);
204 checkOptree ( name => 'constant sub returning list',
207 expect => $expect, expect_nt => $expect_nt);
211 printf "myint %d mystr %s myfl %f pi %f\n"
212 , myint, mystr, myfl, pi;
215 my ($expect, $expect_nt) = (<<'EOT_EOT', <<'EONT_EONT');
216 # 9 <1> leavesub[1 ref] K/REFC,1 ->(end)
217 # - <@> lineseq KP ->9
218 # 1 <;> nextstate(main 635 optree_constants.t:163) v:>,<,% ->2
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
224 # 6 <$> const[NV 1.414213] s ->7
225 # 7 <$> const[NV 3.14159] s ->8
227 # 9 <1> leavesub[1 ref] K/REFC,1 ->(end)
228 # - <@> lineseq KP ->9
229 # 1 <;> nextstate(main 635 optree_constants.t:163) v:>,<,% ->2
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
235 # 6 <$> const(NV 1.414213) s ->7
236 # 7 <$> const(NV 3.14159) s ->8
240 # 5.8.x's use constant has larger types
241 foreach ($expect, $expect_nt) {
247 checkOptree ( name => 'call many in a print statement',
249 strip_open_hints => 1,
250 expect => $expect, expect_nt => $expect_nt);
258 Optimized constant subs are stored as bare scalars in the stash
259 (package hash), which formerly held only GVs (typeglobs).
261 But you cant create them manually - you cant assign a scalar to a
262 stash element, and expect it to work like a constant-sub, even if you
265 This is a feature; alternative is too much action-at-a-distance. The
266 following test demonstrates - napier is not seen as a function at all,
267 much less an optimized one.
271 checkOptree ( name => 'not evertnapier',
274 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');