File Coverage

blib/lib/B/CC.pm
Criterion Covered Total %
statement 103 1530 6.7
branch 25 798 3.1
condition 7 278 2.5
subroutine 19 192 9.9
pod 3 164 1.8
total 157 2962 5.3


line stmt bran cond sub pod time code
1             # CC.pm
2             #
3             # Copyright (c) 1996, 1997, 1998 Malcolm Beattie
4             # Copyright (c) 2009, 2010, 2011 Reini Urban
5             # Copyright (c) 2010 Heinz Knutzen
6             # Copyright (c) 2012-2017 cPanel Inc
7             #
8             # You may distribute under the terms of either the GNU General Public
9             # License or the Artistic License, as specified in the README file.
10              
11             =head1 NAME
12              
13             B::CC - Perl compiler's optimized C translation backend
14              
15             =head1 SYNOPSIS
16              
17             perl -MO=CC[,OPTIONS] foo.pl
18              
19             =head1 DESCRIPTION
20              
21             This compiler backend takes Perl source and generates C source code
22             corresponding to the flow of your program with unrolled ops and optimised
23             stack handling and lexicals variable types. In other words, this backend is
24             somewhat a "real" compiler in the sense that many people think about
25             compilers. Note however that, currently, it is a very poor compiler in that
26             although it generates (mostly, or at least sometimes) correct code, it
27             performs relatively few optimisations. This will change as the compiler and
28             the types develops. The result is that running an executable compiled with
29             this backend may start up more quickly than running the original Perl program
30             (a feature shared by the B compiler backend--see L) and may also
31             execute slightly faster. This is by no means a good optimising compiler--yet.
32              
33             =head1 OPTIONS
34              
35             If there are any non-option arguments, they are taken to be
36             names of objects to be saved (probably doesn't work properly yet).
37             Without extra arguments, it saves the main program.
38              
39             =over 4
40              
41             =item B<-ofilename>
42              
43             Output to filename instead of STDOUT
44              
45             =item B<-c>
46              
47             Check and abort.
48              
49             Compiles and prints only warnings, but does not emit C code.
50              
51             =item B<-v>
52              
53             Verbose compilation (prints a few compilation stages).
54              
55             =item B<-->
56              
57             Force end of options
58              
59             =item B<-uPackname>
60              
61             Force apparently unused subs from package Packname to be compiled.
62             This allows programs to use eval "foo()" even when sub foo is never
63             seen to be used at compile time. The down side is that any subs which
64             really are never used also have code generated. This option is
65             necessary, for example, if you have a signal handler foo which you
66             initialise with C<$SIG{BAR} = "foo">. A better fix, though, is just
67             to change it to C<$SIG{BAR} = \&foo>. You can have multiple B<-u>
68             options. The compiler tries to figure out which packages may possibly
69             have subs in which need compiling but the current version doesn't do
70             it very well. In particular, it is confused by nested packages (i.e.
71             of the form C) where package C does not contain any subs.
72              
73             =item B<-UPackname> "unuse" skip Package
74              
75             Ignore all subs from Package to be compiled.
76              
77             Certain packages might not be needed at run-time, even if the pessimistic
78             walker detects it.
79              
80             =item B<-mModulename>
81              
82             Instead of generating source for a runnable executable, generate
83             source for an XSUB module. The boot_Modulename function (which
84             DynaLoader can look for) does the appropriate initialisation and runs
85             the main part of the Perl source that is being compiled.
86              
87             =item B<-nInitname>
88              
89             Provide a different init name for additional objects added via cmdline.
90              
91             =item B<-strict>
92              
93             With a DEBUGGING perl compile-time errors for range and flip without
94             compile-time context are only warnings.
95             With C<-strict> these warnings are fatal, otherwise only run-time errors occur.
96              
97             =item B<-On>
98              
99             Optimisation level (n = 0, 1, 2). B<-O> means B<-O1>.
100              
101             The following L optimisations are applied automatically:
102              
103             optimize_warn_sv save_data_fh av-init2|av_init save_sig destruct
104             pv_copy_on_grow
105              
106             B<-O1> sets B<-ffreetmps-each-bblock>.
107              
108             B<-O2> adds B<-ffreetmps-each-loop>, C<-faelem> and B<-fno-destruct> from L.
109              
110             The following options must be set explicitly:
111              
112             B<-fno-taint> or B<-fomit-taint>,
113              
114             B<-fslow-signals>,
115              
116             B<-no-autovivify>,
117              
118             B<-fno-magic>.
119              
120             =item B<-f>C
121              
122             Force optimisations on or off one at a time.
123             Unknown optimizations are passed down to L.
124              
125             =item B<-ffreetmps-each-bblock>
126              
127             Delays FREETMPS from the end of each statement to the end of the each
128             basic block.
129              
130             Enabled with B<-O1>.
131              
132             =item B<-ffreetmps-each-loop>
133              
134             Delays FREETMPS from the end of each statement to the end of the group
135             of basic blocks forming a loop. At most one of the freetmps-each-*
136             options can be used.
137              
138             Enabled with B<-O2>.
139              
140             =item B<-faelem>
141              
142             Enable array element access optimizations, allowing unchecked
143             fast access under certain circumstances.
144              
145             Enabled with B<-O2> and not-threaded perls only.
146              
147             =item B<-fno-inline-ops>
148              
149             Do not inline calls to certain small pp ops.
150              
151             Most of the inlinable ops were already inlined.
152             Turns off inlining for some new ops.
153              
154             AUTOMATICALLY inlined:
155              
156             pp_null pp_stub pp_unstack pp_and pp_andassign pp_or pp_orassign pp_cond_expr
157             pp_padsv pp_const pp_nextstate pp_dbstate pp_rv2gv pp_sort pp_gv pp_gvsv
158             pp_aelemfast pp_ncmp pp_add pp_subtract pp_multiply pp_divide pp_modulo
159             pp_left_shift pp_right_shift pp_i_add pp_i_subtract pp_i_multiply pp_i_divide
160             pp_i_modulo pp_eq pp_ne pp_lt pp_gt pp_le pp_ge pp_i_eq pp_i_ne pp_i_lt
161             pp_i_gt pp_i_le pp_i_ge pp_scmp pp_slt pp_sgt pp_sle pp_sge pp_seq pp_sne
162             pp_sassign pp_preinc pp_pushmark pp_list pp_entersub pp_formline pp_goto
163             pp_enterwrite pp_leavesub pp_leavewrite pp_entergiven pp_leavegiven
164             pp_entereval pp_dofile pp_require pp_entertry pp_leavetry pp_grepstart
165             pp_mapstart pp_grepwhile pp_mapwhile pp_return pp_range pp_flip pp_flop
166             pp_enterloop pp_enteriter pp_leaveloop pp_next pp_redo pp_last pp_subst
167             pp_substcont
168              
169             DONE with -finline-ops:
170              
171             pp_enter pp_reset pp_regcreset pp_stringify
172              
173             TODO with -finline-ops:
174              
175             pp_anoncode pp_wantarray pp_srefgen pp_refgen pp_ref pp_trans pp_schop pp_chop
176             pp_schomp pp_chomp pp_not pp_sprintf pp_anonlist pp_shift pp_once pp_lock
177             pp_rcatline pp_close pp_time pp_alarm pp_av2arylen: no lvalue, pp_length: no
178             magic
179              
180             =item B<-fomit-taint>
181              
182             Omits generating code for handling perl's tainting mechanism.
183              
184             =item B<-fslow-signals>
185              
186             Add PERL_ASYNC_CHECK after every op as in the old Perl runloop before 5.13.
187              
188             perl "Safe signals" check the state of incoming signals after every op.
189             See L
190             We trade safety for more speed and delay the execution of non-IO signals
191             (IO signals are already handled in PerlIO) from after every single Perl op
192             to the same ops as used in 5.14.
193              
194             Only with -fslow-signals we get the old slow and safe behaviour.
195              
196             =item B<-fno-name-magic>
197              
198             With the default C<-fname-magic> we infer the SCALAR type for specially named
199             locals vars and most ops use C vars then, not the perl vars.
200             Arithmetic and comparison is inlined. Scalar magic is bypassed.
201              
202             With C<-fno-name-magic> do not infer a local variable type from its name:
203              
204             B<_i> suffix for int, B<_d> for double/num, B<_ir> for register int
205              
206             See the experimental C<-ftype-attr> type attributes.
207             Currently supported are B and B only. See .
208              
209             =item B<-ftype-attr> (DOES NOT WORK YET)
210              
211             Experimentally support B for B and B,
212             SCALAR only so far.
213             For most ops new C vars are used then, not the fat perl vars.
214             Very awkward to use until the basic type classes are supported from
215             within core or use types.
216              
217             Enabled with B<-O2>. See L and .
218              
219             =item B<-fno-autovivify>
220              
221             Do not vivify array and soon also hash elements when accessing them.
222             Beware: Vivified elements default to undef, unvivified elements are
223             invalid.
224              
225             This is the same as the pragma "no autovivification" and allows
226             very fast array accesses, 4-6 times faster, without the overhead of
227             L.
228              
229             =item B<-fno-magic>
230              
231             Assume certain data being optimized is never tied or is holding other magic.
232             This mainly holds for arrays being optimized, but in the future hashes also.
233              
234             =item B<-D>
235              
236             Debug options (concatenated or separate flags like C).
237             Verbose debugging options are crucial, because the interactive
238             debugger L adds a lot of ballast to the resulting code.
239              
240             =item B<-Dr>
241              
242             Writes debugging output to STDERR just as it's about to write to the
243             program's runtime (otherwise writes debugging info as comments in
244             its C output).
245              
246             =item B<-DO>
247              
248             Outputs each OP as it's compiled
249              
250             =item B<-DT>
251              
252             Outputs the contents of the B at each OP.
253             Values are B::Stackobj objects.
254              
255             =item B<-Dc>
256              
257             Outputs the contents of the loop B, the @cxstack.
258              
259             =item B<-Dw>
260              
261             Outputs the contents of the B stack at each OP.
262              
263             =item B<-Da>
264              
265             Outputs the contents of the shadow pad of lexicals as it's loaded for
266             each sub or the main program.
267              
268             =item B<-Dq>
269              
270             Outputs the name of each fake PP function in the queue as it's about
271             to process it.
272              
273             =item B<-Dl>
274              
275             Output the filename and line number of each original line of Perl
276             code as it's processed (C).
277              
278             =item B<-Dt>
279              
280             Outputs timing information of compilation stages.
281              
282             =item B<-DF>
283              
284             Add Flags info to the code.
285              
286             =back
287              
288             =head1 NOTABLE FUNCTIONS
289              
290             =cut
291              
292              
293             package B::CC;
294              
295             our $VERSION = '1.16_01';
296              
297             # Start registering the L namespaces.
298 14     14   151876 use strict;
  14         24  
  14         1002  
299             our %Config;
300             BEGIN {
301 14     14   1071 require B::C::Config;
302 14         43 *Config = \%B::C::Config::Config;
303             # make it a restricted hash
304 14 50       674 Internals::SvREADONLY(%Config, 1) if $] >= 5.008004;
305             }
306             unless ($Config{usecperl}) {
307             eval '$main::int::B_CC = $main::num::B_CC = $main::str::B_CC = $main::double::B_CC = $main::string::B_CC = $VERSION;';
308             }
309              
310             #use 5.008;
311 14         2179 use B qw(main_start main_root comppadlist peekop svref_2object
312             timing_info init_av end_av sv_undef
313             OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST OPf_WANT
314             OPf_MOD OPf_STACKED OPf_SPECIAL OPpLVAL_DEFER OPpLVAL_INTRO
315             OPpASSIGN_BACKWARDS OPpLVAL_INTRO OPpDEREF_AV OPpDEREF_HV
316 14     14   49 OPpDEREF OPpFLIP_LINENUM G_VOID G_SCALAR G_ARRAY);
  14         11  
317             #CXt_NULL CXt_SUB CXt_EVAL CXt_SUBST CXt_BLOCK
318 14         1755 use B::C qw(save_unused_subs objsym init_sections mark_unused mark_skip
319             output_all output_boilerplate output_main output_main_rest fixup_ppaddr save_sig
320 14     14   17995 svop_or_padop_pv inc_cleanup curcv set_curcv);
  14         54  
321 14     14   6270 use B::Bblock qw(find_leaders);
  14         22  
  14         676  
322 14     14   5111 use B::Stackobj qw(:types :flags);
  14         21  
  14         2344  
323 14     14   74 use B::C::Config;
  14         15  
  14         4668  
324             # use attributes qw(get reftype);
325              
326             @B::OP::ISA = qw(B); # support -Do
327             @B::LISTOP::ISA = qw(B::BINOP B); # support -Do
328             push @B::OP::ISA, 'B::NULLOP' if exists $main::B::{'NULLOP'};
329              
330             # These should probably be elsewhere
331             # Flags for $op->flags
332              
333             my $module; # module name (when compiled with -m)
334             my %done; # hash keyed by $$op of leaders of basic blocks
335             # which have already been done.
336             my $leaders; # ref to hash of basic block leaders. Keys are $$op
337             # addresses, values are the $op objects themselves.
338             my @bblock_todo; # list of leaders of basic blocks that need visiting
339             # sometime.
340             my @cc_todo; # list of tuples defining what PP code needs to be
341             # saved (e.g. CV, main or PMOP repl code). Each tuple
342             # is [$name, $root, $start, @padlist]. PMOP repl code
343             # tuples inherit padlist.
344             my %cc_pp_sub; # hashed names of pp_sub functions already saved
345             my @stack; # shadows perl's stack when contents are known.
346             # Values are objects derived from class B::Stackobj
347             my @pad; # Lexicals in current pad as Stackobj-derived objects
348             my @padlist; # Copy of current padlist so PMOP repl code can find it
349             my @cxstack; # Shadows the (compile-time) cxstack for next,last,redo
350             # This covers only a small part of the perl cxstack
351             my $labels; # hashref to array of op labels
352             my %constobj; # OP_CONST constants as Stackobj-derived objects
353             # keyed by $$sv.
354             my $need_freetmps = 0; # We may postpone FREETMPS to the end of each basic
355             # block or even to the end of each loop of blocks,
356             # depending on optimisation options.
357             my $know_op = 0; # Set when C variable op already holds the right op
358             # (from an immediately preceding DOOP(ppname)).
359             my $errors = 0; # Number of errors encountered
360             my $op_count = 0; # for B::compile_stats on verbose
361             my %no_stack; # PP names which don't need save pp restore stack
362             my %skip_stack; # PP names which don't need write_back_stack (empty)
363             my %skip_lexicals; # PP names which don't need write_back_lexicals
364             my %skip_invalidate; # PP names which don't need invalidate_lexicals
365             my %ignore_op; # ops which do nothing except returning op_next
366             my %need_curcop; # ops which need PL_curcop
367             my $package_pv; # sv->pv of previous op for method_named
368              
369             my %lexstate; # state of padsvs at the start of a bblock
370             my ( $verbose, $check );
371             my ( $entertry_defined, $vivify_ref_defined );
372             my ( $init_name, %debug, $strict );
373              
374             # Optimisation options. On the command line, use hyphens instead of
375             # underscores for compatibility with gcc-style options. We use
376             # underscores here because they are OK in (strict) barewords.
377             # Disable with -fno-
378             my ( $freetmps_each_bblock, $freetmps_each_loop, $inline_ops, $opt_taint, $opt_omit_taint,
379             $opt_slow_signals, $opt_name_magic, $opt_type_attr, $opt_autovivify, $opt_magic,
380             $opt_aelem, %c_optimise );
381             $inline_ops = 1 unless $^O eq 'MSWin32'; # Win32 cannot link to unexported pp_op() XXX
382             $opt_name_magic = 1;
383             my %optimise = (
384             freetmps_each_bblock => \$freetmps_each_bblock, # -O1
385             freetmps_each_loop => \$freetmps_each_loop, # -O2
386             aelem => \$opt_aelem, # -O2
387             inline_ops => \$inline_ops, # not on Win32
388             omit_taint => \$opt_omit_taint,
389             taint => \$opt_taint,
390             slow_signals => \$opt_slow_signals,
391             name_magic => \$opt_name_magic,
392             type_attr => \$opt_type_attr,
393             autovivify => \$opt_autovivify,
394             magic => \$opt_magic,
395             );
396             my %async_signals = map { $_ => 1 } # 5.14 ops which do PERL_ASYNC_CHECK
397             qw(wait waitpid nextstate and cond_expr unstack or subst dorassign);
398             $async_signals{$_} = 1 for # more 5.16 ops which do PERL_ASYNC_CHECK
399             qw(substcont next redo goto leavewhen);
400             # perl patchlevel to generate code for (defaults to current patchlevel)
401             my $patchlevel = int( 0.5 + 1000 * ( $] - 5 ) ); # XXX unused?
402             my $MULTI = $Config{usemultiplicity};
403             my $ITHREADS = $Config{useithreads};
404             my $PERL510 = ( $] >= 5.009005 );
405             my $PERL512 = ( $] >= 5.011 );
406              
407             my $SVt_PVLV = $PERL510 ? 10 : 9;
408             my $SVt_PVAV = $PERL510 ? 11 : 10;
409             # use sub qw(CXt_LOOP_PLAIN CXt_LOOP);
410             BEGIN {
411 14 50   14   46 if ($PERL512) {
  0         0  
412 0     0 0 0 sub CXt_LOOP_PLAIN {5} # CXt_LOOP_FOR CXt_LOOP_LAZYSV CXt_LOOP_LAZYIV
413 0         0 } else {
414 0     0 0 0 sub CXt_LOOP {3}
415             }
416             sub CxTYPE_no_LOOP {
417             $PERL512
418             ? ( $_[0]->{type} < 4 or $_[0]->{type} > 7 )
419 0 0 0 0 0 0 : $_[0]->{type} != 3
420             }
421 14 50       41 if ($] < 5.008) {
422 0         0 eval "sub SVs_RMG {0x8000};";
423             } else {
424 14         294 B->import('SVs_RMG');
425             }
426 14 50       48 if ($] <= 5.010) {
    50          
    0          
    0          
427 0         0 eval "sub PMf_ONCE() {0xff}; # unused";
428             } elsif ($] >= 5.018) { # PMf_ONCE not exported
429 14         9563 eval q[sub PMf_ONCE(){ 0x10000 }];
430             } elsif ($] >= 5.014) {
431 0         0 eval q[sub PMf_ONCE(){ 0x8000 }];
432             } elsif ($] >= 5.012) {
433 0         0 eval q[sub PMf_ONCE(){ 0x0080 }];
434             } else { # 5.10. not used with <= 5.8
435 0         0 eval q[sub PMf_ONCE(){ 0x0002 }];
436             }
437             }
438              
439             # Could rewrite push_runtime() and output_runtime() to use a
440             # temporary file if memory is at a premium.
441             my $ppname; # name of current fake PP function
442             my $runtime_list_ref;
443             my $declare_ref; # Hash ref keyed by C variable type of declarations.
444              
445             my @pp_list; # list of [$ppname, $runtime_list_ref, $declare_ref]
446             # tuples to be written out.
447              
448             my ( $init, $decl );
449              
450             sub init_hash {
451 84     84 0 83 map { $_ => 1 } @_;
  616         892  
452             }
453              
454             # Initialise the hashes for the default PP functions where we can avoid
455             # either stack save/restore,write_back_stack, write_back_lexicals or invalidate_lexicals.
456             # XXX We should really take some of this info from Opcodes (was: CORE opcode.pl)
457             #
458             # no args and no return value = Opcodes::argnum 0
459             %no_stack = init_hash qw(pp_unstack pp_break pp_continue);
460             # pp_enter pp_leave, use/change global stack.
461             #skip write_back_stack (no args)
462             %skip_stack = init_hash qw(pp_enter pp_leave pp_nextstate pp_dbstate);
463             # which ops do not read pad vars
464             %skip_lexicals = init_hash qw(pp_enter pp_enterloop pp_leave pp_nextstate pp_dbstate);
465             # which ops no not write to pad vars
466             %skip_invalidate = init_hash qw(pp_enter pp_enterloop pp_leave pp_nextstate pp_dbstate
467             pp_return pp_leavesub pp_list pp_pushmark
468             pp_anonlist
469             );
470              
471             %need_curcop = init_hash qw(pp_rv2gv pp_bless pp_repeat pp_sort pp_caller
472             pp_reset pp_rv2cv pp_entereval pp_require pp_dofile
473             pp_entertry pp_enterloop pp_enteriter pp_entersub pp_entergiven
474             pp_enter pp_method);
475             %ignore_op = init_hash qw(pp_scalar pp_regcmaybe pp_lineseq pp_scope pp_null);
476              
477             { # block necessary for caller to work
478             my $caller = caller;
479             if ( $caller eq 'O' ) {
480             require XSLoader;
481             XSLoader::load('B::C'); # for r-magic only
482             }
483             }
484              
485             sub debug {
486 0 0   0 0 0 if ( $debug{runtime} ) {
487             # TODO: fix COP to callers line number
488 0 0       0 warn(@_) if $verbose;
489             }
490             else {
491 0         0 my @tmp = @_;
492 0         0 runtime( map { chomp; "/* $_ */" } @tmp );
  0         0  
  0         0  
493             }
494             }
495              
496             sub declare {
497 0     0 0 0 my ( $type, $var ) = @_;
498 0         0 push( @{ $declare_ref->{$type} }, $var );
  0         0  
499             }
500              
501             sub push_runtime {
502 0     0 0 0 push( @$runtime_list_ref, @_ );
503 0 0       0 warn join( "\n", @_ ) . "\n" if $debug{runtime};
504             }
505              
506             sub save_runtime {
507 0     0 0 0 push( @pp_list, [ $ppname, $runtime_list_ref, $declare_ref ] );
508             }
509              
510             sub output_runtime {
511 0     0 0 0 my $ppdata;
512 0         0 print qq(\n#include "cc_runtime.h"\n);
513             # CC coverage: 12, 32
514              
515             # Perls >=5.8.9 have a broken PP_ENTERTRY. See PERL_FLEXIBLE_EXCEPTIONS in cop.h
516             # Fixed in CORE with 5.11.4
517 0 0 0     0 print'
518             #undef PP_ENTERTRY
519             #define PP_ENTERTRY(label) \
520             STMT_START { \
521             dJMPENV; \
522             int ret; \
523             JMPENV_PUSH(ret); \
524             switch (ret) { \
525             case 1: JMPENV_POP; JMPENV_JUMP(1);\
526             case 2: JMPENV_POP; JMPENV_JUMP(2);\
527             case 3: JMPENV_POP; SPAGAIN; goto label;\
528             } \
529             } STMT_END'
530             if $entertry_defined and $] < 5.011004;
531             # XXX need to find out when PERL_FLEXIBLE_EXCEPTIONS were actually active.
532             # 5.6.2 not, 5.8.9 not. coverage 32
533              
534             # test 12. Used by entereval + dofile
535 0 0 0     0 if ($PERL510 or $MULTI) {
536             # Threads error Bug#55302: too few arguments to function
537             # CALLRUNOPS()=>CALLRUNOPS(aTHX)
538             # fixed with 5.11.4
539 0         0 print '
540             #undef PP_EVAL
541             #define PP_EVAL(ppaddr, nxt) do { \
542             dJMPENV; \
543             int ret; \
544             PUTBACK; \
545             JMPENV_PUSH(ret); \
546             switch (ret) { \
547             case 0: \
548             PL_op = ppaddr(aTHX); \\';
549 0 0       0 if ($PERL510) {
550             # pp_leaveeval sets: retop = cx->blk_eval.retop
551 0         0 print '
552             cxstack[cxstack_ix].blk_eval.retop = Nullop; \\';
553             } else {
554             # up to 5.8 pp_entereval did set the retstack to next.
555             # nullify that so that we can now exec the rest of this bblock.
556             # (nextstate .. leaveeval)
557 0         0 print '
558             PL_retstack[PL_retstack_ix - 1] = Nullop; \\';
559             }
560 0         0 print '
561             if (PL_op != nxt) CALLRUNOPS(aTHX); \
562             JMPENV_POP; \
563             break; \
564             case 1: JMPENV_POP; JMPENV_JUMP(1); \
565             case 2: JMPENV_POP; JMPENV_JUMP(2); \
566             case 3: \
567             JMPENV_POP; \
568             if (PL_restartop && PL_restartop != nxt) \
569             JMPENV_JUMP(3); \
570             } \
571             PL_op = nxt; \
572             SPAGAIN; \
573             } while (0)
574             ';
575             }
576              
577             # Perl_vivify_ref not exported on MSWin32
578             # coverage: 18
579 0 0 0     0 if ($PERL510 and $^O eq 'MSWin32') {
580             # CC coverage: 18, 29
581 0 0       0 print << '__EOV' if $vivify_ref_defined;
582              
583             /* Code to take a scalar and ready it to hold a reference */
584             # ifndef SVt_RV
585             # define SVt_RV SVt_IV
586             # endif
587             # define prepare_SV_for_RV(sv) \
588             STMT_START { \
589             if (SvTYPE(sv) < SVt_RV) \
590             sv_upgrade(sv, SVt_RV); \
591             else if (SvPVX_const(sv)) { \
592             SvPV_free(sv); \
593             SvLEN_set(sv, 0); \
594             SvCUR_set(sv, 0); \
595             } \
596             } STMT_END
597              
598             #if (PERL_VERSION > 15) || ((PERL_VERSION == 15) && (PERL_SUBVERSION >= 2))
599             SV*
600             #else
601             void
602             #endif
603             Perl_vivify_ref(pTHX_ SV *sv, U32 to_what)
604             {
605             SvGETMAGIC(sv);
606             if (!SvOK(sv)) {
607             if (SvREADONLY(sv))
608             Perl_croak(aTHX_ "%s", PL_no_modify);
609             prepare_SV_for_RV(sv);
610             switch (to_what) {
611             case OPpDEREF_SV:
612             SvRV_set(sv, newSV(0));
613             break;
614             case OPpDEREF_AV:
615             SvRV_set(sv, newAV());
616             break;
617             case OPpDEREF_HV:
618             SvRV_set(sv, newHV());
619             break;
620             }
621             SvROK_on(sv);
622             SvSETMAGIC(sv);
623             }
624             }
625              
626             __EOV
627              
628             }
629              
630 0         0 print '
631              
632             OP *Perl_pp_aelem_nolval(pTHXx);
633             #ifndef SVfARG
634             # define SVfARG(x) (void *)x
635             #endif
636             #ifndef MUTABLE_AV
637             # define MUTABLE_AV(av) av
638             #endif
639             PP(pp_aelem_nolval)
640             {
641             dSP;
642             SV** svp;
643             SV* const elemsv = POPs;
644             IV elem = SvIV(elemsv);
645             AV *const av = MUTABLE_AV(POPs);
646             SV *sv;
647              
648             #if PERL_VERSION > 6
649             if (SvROK(elemsv) && !SvGAMAGIC(elemsv) && ckWARN(WARN_MISC))
650             Perl_warner(aTHX_ packWARN(WARN_MISC),
651             "Use of reference \"%"SVf"\" as array index",
652             SVfARG(elemsv));
653             #endif
654             if (SvTYPE(av) != SVt_PVAV) RETPUSHUNDEF;
655             svp = av_fetch(av, elem, 0);
656             sv = (svp ? *svp : &PL_sv_undef);
657             if (SvRMAGICAL(av) && SvGMAGICAL(sv)) mg_get(sv);
658             PUSHs(sv);
659             RETURN;
660             }
661             ' if 0;
662              
663 0         0 foreach $ppdata (@pp_list) {
664 0         0 my ( $name, $runtime, $declare ) = @$ppdata;
665 0         0 print "\nstatic\nCCPP($name)\n{\n";
666 0         0 my ( $type, $varlist, $line );
667 0         0 while ( ( $type, $varlist ) = each %$declare ) {
668 0         0 $varlist = $declare->{$type};
669 0         0 print "\t$type ", join( ", ", @$varlist ), ";\n";
670             }
671 0         0 foreach $line (@$runtime) {
672 0         0 print $line, "\n";
673             }
674 0         0 print "}\n";
675             }
676             }
677              
678             sub runtime {
679 0     0 0 0 my $line;
680 0         0 foreach $line (@_) {
681 0         0 push_runtime("\t$line");
682             }
683             }
684              
685             sub init_pp {
686 0     0 0 0 $ppname = shift;
687 0         0 $runtime_list_ref = [];
688 0         0 $declare_ref = {};
689 0         0 runtime("dSP;");
690 0         0 declare( "I32", "oldsave" );
691 0         0 map { declare( "SV", "*$_" ) } qw(sv src dst left right);
  0         0  
692 0         0 declare( "MAGIC", "*mg" );
693 0 0 0     0 $decl->add( "#undef cxinc", "#define cxinc() Perl_cxinc(aTHX)")
694             if $] < 5.011001 and $inline_ops;
695 0         0 declare( "PERL_CONTEXT", "*cx" );
696 0         0 declare( "I32", "gimme");
697 0         0 $decl->add("static OP * $ppname (pTHX);");
698 0 0       0 debug "init_pp: $ppname\n" if $debug{queue};
699             }
700              
701             # Initialise runtime_callback function for Stackobj class
702 14     14   56 BEGIN { B::Stackobj::set_callback( \&runtime ) }
703              
704             =head2 cc_queue
705              
706             Creates a new ccpp optree.
707              
708             Initialised by saveoptree_callback in L, replaces B::C::walk_and_save_optree.
709             Called by every C if ROOT.
710             B also creates its block closure with cc_queue.
711              
712             =cut
713              
714             # coverage: test 18, 28 (fixed with B-C-1.30 r971)
715             sub cc_queue {
716 0     0 1 0 my ( $name, $root, $start, @pl ) = @_;
717             debug "cc_queue: name $name, root $root, start $start, padlist (@pl)\n"
718 0 0       0 if $debug{queue};
719 0 0 0     0 if ( $name eq "*ignore*" or $name =~ /^pp_sub_.*(FETCH|MODIFY)_SCALAR_ATTRIBUTES$/) {
720 0         0 $name = '';
721             } else {
722 0 0       0 push( @cc_todo, [ $name, $root, $start, ( @pl ? @pl : @padlist ) ] );
723             }
724 0         0 my $fakeop_next = 0;
725 0 0       0 if ($name =~ /^pp_sub_.*DESTROY$/) {
726             # curse in sv_clean_objs() checks for ->op_next->op_type
727 0         0 $fakeop_next = $start->next->save;
728             }
729 0         0 my $fakeop = B::FAKEOP->new( "next" => $fakeop_next, ppaddr => $name );
730 0         0 $start = $fakeop->save;
731 0 0       0 debug "cc_queue: name $name returns $start\n" if $debug{queue};
732 0         0 return $start;
733             }
734 14     14   57 BEGIN { B::C::set_callback( \&cc_queue ) }
735              
736 0     0 0 0 sub valid_int { $_[0]->{flags} & VALID_INT }
737 0     0 0 0 sub valid_double { $_[0]->{flags} & VALID_NUM }
738 0     0 0 0 sub valid_numeric { $_[0]->{flags} & ( VALID_INT | VALID_NUM ) }
739 0     0 0 0 sub valid_str { $_[0]->{flags} & VALID_STR }
740 0     0 0 0 sub valid_sv { $_[0]->{flags} & VALID_SV }
741              
742 0 0   0 0 0 sub top_int { @stack ? $stack[-1]->as_int : "TOPi" }
743 0 0   0 0 0 sub top_double { @stack ? $stack[-1]->as_double : "TOPn" }
744 0 0   0 0 0 sub top_numeric { @stack ? $stack[-1]->as_numeric : "TOPn" }
745 0 0   0 0 0 sub top_sv { @stack ? $stack[-1]->as_sv : "TOPs" }
746 0 0   0 0 0 sub top_str { @stack ? $stack[-1]->as_str : "TOPs" }
747 0 0   0 0 0 sub top_bool { @stack ? $stack[-1]->as_bool : "SvTRUE(TOPs)" }
748              
749 0 0   0 0 0 sub pop_int { @stack ? ( pop @stack )->as_int : "POPi" }
750 0 0   0 0 0 sub pop_double { @stack ? ( pop @stack )->as_double : "POPn" }
751 0 0   0 0 0 sub pop_numeric { @stack ? ( pop @stack )->as_numeric : "POPn" }
752 0 0   0 0 0 sub pop_str { @stack ? ( pop @stack )->as_str : "POPs" }
753 0 0   0 0 0 sub pop_sv { @stack ? ( pop @stack )->as_sv : "POPs" }
754              
755             sub pop_bool {
756 0 0   0 0 0 if (@stack) {
757 0         0 return ( ( pop @stack )->as_bool );
758             }
759             else {
760             # Careful: POPs has an auto-decrement and SvTRUE evaluates
761             # its argument more than once.
762 0         0 runtime("sv = POPs;");
763 0         0 return "SvTRUE(sv)";
764             }
765             }
766              
767             sub write_back_lexicals {
768 0   0 0 0 0 my $avoid = shift || 0;
769 0         0 debug "write_back_lexicals($avoid) called from @{[(caller(1))[3]]}\n"
770 0 0       0 if $debug{shadow};
771 0         0 my $lex;
772 0         0 foreach $lex (@pad) {
773 0 0       0 next unless ref($lex);
774 0 0       0 $lex->write_back unless $lex->{flags} & $avoid;
775             }
776             }
777              
778             =head1 save_or_restore_lexical_state
779              
780             The compiler tracks state of lexical variables in @pad to generate optimised
781             code. But multiple execution paths lead to the entry point of a basic block.
782             The state of the first execution path is saved and all other execution
783             paths are restored to the state of the first one.
784              
785             Missing flags are regenerated by loading values.
786              
787             Added flags must are removed; otherwise the compiler would be too optimistic,
788             hence generating code which doesn't match state of the other execution paths.
789              
790             =cut
791              
792             sub save_or_restore_lexical_state {
793 0     0 0 0 my $bblock = shift;
794 0 0       0 unless ( exists $lexstate{$bblock} ) {
795 0         0 foreach my $lex (@pad) {
796 0 0       0 next unless ref($lex);
797 0         0 ${ $lexstate{$bblock} }{ $lex->{iv} } = $lex->{flags};
  0         0  
798             }
799             }
800             else {
801 0         0 foreach my $lex (@pad) {
802 0 0       0 next unless ref($lex);
803 0         0 my $old_flags = ${ $lexstate{$bblock} }{ $lex->{iv} };
  0         0  
804 0 0       0 next if ( $old_flags eq $lex->{flags} );
805 0         0 my $changed = $old_flags ^ $lex->{flags};
806 0 0       0 if ( $changed & VALID_SV ) {
807 0 0       0 ( $old_flags & VALID_SV ) ? $lex->write_back : $lex->invalidate;
808             }
809 0 0       0 if ( $changed & VALID_NUM ) {
810 0 0       0 ( $old_flags & VALID_NUM ) ? $lex->load_double : $lex->invalidate_double;
811             }
812 0 0       0 if ( $changed & VALID_INT ) {
813 0 0       0 ( $old_flags & VALID_INT ) ? $lex->load_int : $lex->invalidate_int;
814             }
815 0 0       0 if ( $changed & VALID_STR ) {
816 0 0       0 ( $old_flags & VALID_STR ) ? $lex->load_str : $lex->invalidate_str;
817             }
818             }
819             }
820             }
821              
822             sub write_back_stack {
823 0         0 debug "write_back_stack() ".scalar(@stack)." called from @{[(caller(1))[3]]}\n"
824 0 0   0 0 0 if $debug{shadow};
825 0 0       0 return unless @stack;
826 0         0 runtime( sprintf( "EXTEND(sp, %d);", scalar(@stack) ) );
827 0         0 foreach my $obj (@stack) {
828 0         0 runtime( sprintf( "PUSHs((SV*)%s);", $obj->as_sv ) );
829             }
830 0         0 @stack = ();
831             }
832              
833             sub invalidate_lexicals {
834 0   0 0 0 0 my $avoid = shift || 0;
835 0         0 debug "invalidate_lexicals($avoid) called from @{[(caller(1))[3]]}\n"
836 0 0       0 if $debug{shadow};
837 0         0 my $lex;
838 0         0 foreach $lex (@pad) {
839 0 0       0 next unless ref($lex);
840 0 0       0 $lex->invalidate unless $lex->{flags} & $avoid;
841             }
842             }
843              
844             sub reload_lexicals {
845 0     0 0 0 my $lex;
846 0         0 foreach $lex (@pad) {
847 0 0       0 next unless ref($lex);
848 0         0 my $type = $lex->{type};
849 0 0       0 if ( $type == T_INT ) {
    0          
    0          
850 0         0 $lex->as_int;
851             }
852             elsif ( $type == T_NUM ) {
853 0         0 $lex->as_double;
854             }
855             elsif ( $type == T_STR ) {
856 0         0 $lex->as_str;
857             }
858             else {
859 0         0 $lex->as_sv;
860             }
861             }
862             }
863              
864             {
865              
866             package B::Pseudoreg;
867              
868             #
869             # This class allocates pseudo-registers (OK, so they're C variables).
870             #
871             my %alloc; # Keyed by variable name. A value of 1 means the
872             # variable has been declared. A value of 2 means
873             # it's in use.
874              
875 0     0   0 sub new_scope { %alloc = () }
876              
877             sub new ($$$) {
878 0     0   0 my ( $class, $type, $prefix ) = @_;
879 0         0 my ( $ptr, $i, $varname, $status, $obj );
880 0         0 $prefix =~ s/^(\**)//;
881 0         0 $ptr = $1;
882 0         0 $i = 0;
883 0         0 do {
884 0         0 $varname = "$prefix$i";
885 0 0       0 $status = exists $alloc{$varname} ? $alloc{$varname} : 0;
886             } while $status == 2;
887              
888 0 0       0 if ( $status != 1 ) {
889             # Not declared yet
890 0         0 B::CC::declare( $type, "$ptr$varname" );
891 0         0 $alloc{$varname} = 2; # declared and in use
892             }
893 0         0 $obj = bless \$varname, $class;
894 0         0 return $obj;
895             }
896              
897             sub DESTROY {
898 0     0   0 my $obj = shift;
899 0         0 $alloc{$$obj} = 1; # no longer in use but still declared
900             }
901             }
902             {
903              
904             package B::Shadow;
905              
906             #
907             # This class gives a standard API for a perl object to shadow a
908             # C variable and only generate reloads/write-backs when necessary.
909             #
910             # Use $obj->load($foo) instead of runtime("shadowed_c_var = foo").
911             # Use $obj->write_back whenever shadowed_c_var needs to be up to date.
912             # Use $obj->invalidate whenever an unknown function may have
913             # set shadow itself.
914              
915             sub new {
916 14     14   35 my ( $class, $write_back ) = @_;
917              
918             # Object fields are perl shadow variable, validity flag
919             # (for *C* variable) and callback sub for write_back
920             # (passed perl shadow variable as argument).
921 14         53 bless [ undef, 1, $write_back ], $class;
922             }
923              
924             sub load {
925 0     0   0 my ( $obj, $newval ) = @_;
926 0         0 $obj->[1] = 0; # C variable no longer valid
927 0         0 $obj->[0] = $newval;
928             }
929              
930             sub value {
931 0     0   0 return $_[0]->[0];
932             }
933              
934             sub write_back {
935 0     0   0 my $obj = shift;
936 0 0       0 if ( !( $obj->[1] ) ) {
937 0         0 $obj->[1] = 1; # C variable will now be valid
938 0         0 &{ $obj->[2] }( $obj->[0] );
  0         0  
939             }
940             }
941 0     0   0 sub invalidate { $_[0]->[1] = 0 } # force C variable to be invalid
942             }
943              
944             my $curcop = B::Shadow->new(
945             sub {
946             my $op = shift;
947             my $opsym = $op->save;
948             runtime("PL_curcop = (COP*)$opsym;");
949             }
950             );
951              
952             #
953             # Context stack shadowing. Mimics stuff in pp_ctl.c, cop.h and so on.
954             #
955             sub dopoptoloop {
956 0     0 0 0 my $cxix = $#cxstack;
957 0   0     0 while ( $cxix >= 0 && CxTYPE_no_LOOP( $cxstack[$cxix] ) ) {
958 0         0 $cxix--;
959             }
960 0 0       0 debug "dopoptoloop: returning $cxix" if $debug{cxstack};
961 0         0 return $cxix;
962             }
963              
964             sub dopoptolabel {
965 0     0 0 0 my $label = shift;
966 0         0 my $cxix = $#cxstack;
967 0   0     0 while (
      0        
968             $cxix >= 0
969             && ( CxTYPE_no_LOOP( $cxstack[$cxix] )
970             || $cxstack[$cxix]->{label} ne $label )
971             )
972             {
973 0         0 $cxix--;
974             }
975 0 0       0 debug "dopoptolabel: returning $cxix\n" if $debug{cxstack};
976 0 0 0     0 if ($cxix < 0 and $debug{cxstack}) {
977 0         0 for my $cx (0 .. $#cxstack) {
978 0         0 debug "$cx: ",$cxstack[$cx]->{label},"\n";
979             }
980 0         0 for my $op (keys %{$labels->{label}}) {
  0         0  
981 0         0 debug $labels->{label}->{$op},"\n";
982             }
983             }
984 0         0 return $cxix;
985             }
986              
987             sub push_label {
988 0     0 0 0 my $op = shift;
989 0         0 my $type = shift;
990 0         0 push @{$labels->{$type}}, ( $op );
  0         0  
991             }
992              
993             sub pop_label {
994 0     0 0 0 my $type = shift;
995 0         0 my $op = pop @{$labels->{$type}};
  0         0  
996 0         0 write_label ($op); # avoids duplicate labels
997             }
998              
999             sub error {
1000 0     0 0 0 my $format = shift;
1001 0         0 my $file = $curcop->[0]->file;
1002 0         0 my $line = $curcop->[0]->line;
1003 0         0 $errors++;
1004 0 0       0 if (@_) {
1005 0         0 warn sprintf( "ERROR at %s:%d: $format\n", $file, $line, @_ );
1006             }
1007             else {
1008 0         0 warn sprintf( "ERROR at %s:%d: %s\n", $file, $line, $format );
1009             }
1010             }
1011              
1012             # run-time eval is too late for attrs being checked by perlcore. BEGIN does not help.
1013             # use types is the right approach. But until types is fixed we use this hack.
1014             # Note that we also need a new CHECK_SCALAR_ATTRIBUTES hook, starting with v5.22.
1015             sub init_type_attrs {
1016 0     0 0 0 eval q[
1017              
1018             our $valid_attr = '^(int|num|str|double|string|unsigned|register|temporary|ro|readonly|const)$';
1019             sub MODIFY_SCALAR_ATTRIBUTES {
1020             my $pkg = shift;
1021             my $v = shift;
1022             my $attr = $B::CC::valid_attr;
1023             $attr =~ s/\b$pkg\b//;
1024             if (my @bad = grep !/$attr/, @_) {
1025             return @bad;
1026             } else {
1027             no strict 'refs';
1028             push @{"$pkg\::$v\::attributes"}, @_; # create a magic glob
1029             return ();
1030             }
1031             }
1032             sub FETCH_SCALAR_ATTRIBUTES {
1033             my ($pkg, $v) = @_;
1034             no strict 'refs';
1035             return @{"$pkg\::$v\::attributes"};
1036             }
1037              
1038             # pollute our callers namespace for attributes to be accepted with -MB::CC
1039             *main::MODIFY_SCALAR_ATTRIBUTES = \&B::CC::MODIFY_SCALAR_ATTRIBUTES;
1040             *main::FETCH_SCALAR_ATTRIBUTES = \&B::CC::FETCH_SCALAR_ATTRIBUTES;
1041              
1042             # my int $i : register : ro;
1043             *int::MODIFY_SCALAR_ATTRIBUTES = \&B::CC::MODIFY_SCALAR_ATTRIBUTES;
1044             *int::FETCH_SCALAR_ATTRIBUTES = \&B::CC::FETCH_SCALAR_ATTRIBUTES;
1045              
1046             # my double $d : ro;
1047             *num::MODIFY_SCALAR_ATTRIBUTES = \&B::CC::MODIFY_SCALAR_ATTRIBUTES;
1048             *num::FETCH_SCALAR_ATTRIBUTES = \&B::CC::FETCH_SCALAR_ATTRIBUTES;
1049             *str::MODIFY_SCALAR_ATTRIBUTES = \&B::CC::MODIFY_SCALAR_ATTRIBUTES;
1050             *str::FETCH_SCALAR_ATTRIBUTES = \&B::CC::FETCH_SCALAR_ATTRIBUTES;
1051              
1052             # deprecated:
1053             *double::MODIFY_SCALAR_ATTRIBUTES = \&B::CC::MODIFY_SCALAR_ATTRIBUTES;
1054             *double::FETCH_SCALAR_ATTRIBUTES = \&B::CC::FETCH_SCALAR_ATTRIBUTES;
1055             *string::MODIFY_SCALAR_ATTRIBUTES = \&B::CC::MODIFY_SCALAR_ATTRIBUTES;
1056             *string::FETCH_SCALAR_ATTRIBUTES = \&B::CC::FETCH_SCALAR_ATTRIBUTES;
1057             ];
1058              
1059             }
1060              
1061             =head2 load_pad
1062              
1063             Load pad takes (the elements of) a PADLIST as arguments and loads up @pad
1064             with Stackobj-derived objects which represent those lexicals.
1065              
1066             If/when perl itself can generate type information C<(my int $foo; my $foo : int)> then we'll
1067             take advantage of that here. Until then, we'll use the L<-fname-magic/-fno-name-magic>
1068             hack to tell the compiler when we want a lexical to be a particular type or to be a register.
1069              
1070             =cut
1071              
1072             sub load_pad {
1073 0     0 1 0 my ( $namelistav, $valuelistav ) = @_;
1074 0         0 @padlist = @_;
1075 0         0 my @namelist = $namelistav->ARRAY;
1076 0         0 my @valuelist = $valuelistav->ARRAY;
1077 0         0 my $ix;
1078 0         0 @pad = ();
1079 0 0       0 debug "load_pad: $#namelist names, $#valuelist values\n" if $debug{pad};
1080              
1081             # Temporary lexicals don't get named so it's possible for @valuelist
1082             # to be strictly longer than @namelist. We count $ix up to the end of
1083             # @valuelist but index into @namelist for the name. Any temporaries which
1084             # run off the end of @namelist will make $namesv undefined and we treat
1085             # that the same as having an explicit SPECIAL sv_undef object in @namelist.
1086             # [XXX If/when @_ becomes a lexical, we must start at 0 here.]
1087 0         0 for ( $ix = 1 ; $ix < @valuelist ; $ix++ ) {
1088 0         0 my $namesv = $namelist[$ix];
1089 0         0 my $type = T_UNKNOWN;
1090 0         0 my $flags = 0;
1091 0         0 my $name = "tmp";
1092 0         0 my $class = B::class($namesv);
1093 0 0 0     0 if ( !defined($namesv) || $class eq "SPECIAL" ) {
1094             # temporaries have &PL_sv_undef instead of a PVNV for a name
1095 0         0 $flags = VALID_SV | TEMPORARY | REGISTER;
1096             }
1097             else {
1098 0 0       0 my ($nametry) = $namesv->PV =~ /^\$(.+)$/ if $namesv->PV;
1099 0 0       0 $name = $nametry if $nametry;
1100              
1101             # my int $i; my num $d; compiled code only, unless the source provides the int and num packages.
1102             # With Ctypes it is easier. my c_int $i; defines an external Ctypes int, which can be efficiently
1103             # compiled in Perl also.
1104             # XXX Better use attributes, like my $i:int; my $d:num; which works un-compiled also.
1105 0 0 0     0 if (ref($namesv) eq 'B::PVMG' and ref($namesv->SvSTASH) eq 'B::HV') { # my int
1106 0         0 $class = $namesv->SvSTASH->NAME;
1107 0 0 0     0 if ($class eq 'int') {
    0 0        
    0          
1108 0         0 $type = T_INT;
1109 0         0 $flags = VALID_SV | VALID_INT;
1110             }
1111             elsif ($class eq 'num' or $class eq 'double') { # my num
1112 0         0 $type = T_NUM;
1113 0         0 $flags = VALID_SV | VALID_NUM;
1114             }
1115             elsif ($class eq 'str' or $class eq 'string') { # my str
1116 0         0 $type = T_STR;
1117 0         0 $flags = VALID_SV | VALID_STR;
1118             }
1119             #elsif ($class eq 'c_int') { # use Ctypes;
1120             # $type = T_INT;
1121             # $flags = VALID_SV | VALID_INT;
1122             #}
1123             #elsif ($class eq 'c_double') {
1124             # $type = T_NUM;
1125             # $flags = VALID_SV | VALID_NUM;
1126             #}
1127             # TODO: MooseX::Types
1128             }
1129              
1130             # Valid scalar type attributes:
1131             # int num str ro readonly const unsigned
1132             # Note: PVMG from above also.
1133             # Typed arrays and hashes later.
1134 0         0 if (0 and $class =~ /^(I|P|S|N)V/
1135             and $opt_type_attr
1136             and UNIVERSAL::can($class,"CHECK_SCALAR_ATTRIBUTES")) # with 5.18
1137             {
1138             require attributes;
1139             #my $svtype = uc reftype ($namesv);
1140             # test 105
1141             my @attr = attributes::get(\$namesv); # how to get em from B? see optimize
1142             warn "\$$name attrs: ".@attr if $verbose or $debug{pad};
1143             #my $valid_types = ${"$class\::valid_attr"}; # They ARE valid, parser checked already.
1144             }
1145              
1146             # XXX We should try Devel::TypeCheck for type inference also
1147              
1148             # magic names: my $i_ir, my $d_d. without -fno-name-magic cmdline option only
1149 0 0 0     0 if ( $type == T_UNKNOWN and $opt_name_magic and $name =~ /^(.*)_([dis])(r?)$/ ) {
      0        
1150 0         0 $name = $1;
1151 0 0       0 if ( $2 eq "i" ) {
    0          
    0          
1152 0         0 $type = T_INT;
1153 0         0 $flags = VALID_SV | VALID_INT;
1154             }
1155             elsif ( $2 eq "d" ) {
1156 0         0 $type = T_NUM;
1157 0         0 $flags = VALID_SV | VALID_NUM;
1158             }
1159             elsif ( $2 eq "s" ) {
1160 0         0 $type = T_STR;
1161 0         0 $flags = VALID_SV | VALID_STR;
1162             }
1163 0 0       0 $flags |= REGISTER if $3;
1164             }
1165             }
1166 0         0 $name = "${ix}_$name";
1167             # comppadname bug with overlong strings
1168 0 0 0     0 if ($] < 5.008008 and length($name) > 100 and $name =~ /\0\0/) {
      0        
1169 0         0 my $i = index($name,"\0");
1170 0 0       0 $name = substr($name,0,$i) if $i > -1;
1171             }
1172 0         0 $pad[$ix] =
1173             B::Stackobj::Padsv->new( $type, $flags, $ix, "i$name", "d$name" );
1174              
1175 0 0       0 debug sprintf( "PL_curpad[$ix] = %s\n", $pad[$ix]->peek ) if $debug{pad};
1176             }
1177             }
1178              
1179             sub declare_pad {
1180 0     0 0 0 my $ix;
1181 0         0 for ( $ix = 1 ; $ix <= $#pad ; $ix++ ) {
1182 0         0 my $type = $pad[$ix]->{type};
1183             declare( "IV",
1184             $type == T_INT ? sprintf( "%s=0", $pad[$ix]->{iv} ) : $pad[$ix]->{iv} )
1185 0 0       0 if $pad[$ix]->save_int;
    0          
1186             declare( "NV",
1187             $type == T_NUM
1188             ? sprintf( "%s = 0", $pad[$ix]->{nv} )
1189             : $pad[$ix]->{nv} )
1190 0 0       0 if $pad[$ix]->save_double;
    0          
1191             declare( "PV",
1192             $type == T_STR
1193             ? sprintf( "%s = 0", $pad[$ix]->{sv} )
1194             : $pad[$ix]->{sv} )
1195 0 0       0 if $pad[$ix]->save_str;
    0          
1196             }
1197             }
1198              
1199             # for cc: unique ascii representation of an utf8 string, for labels
1200             sub encode_utf8($) {
1201 0     0 0 0 my $l = shift;
1202 0 0 0     0 if ($] > 5.007 and utf8::is_utf8($l)) {
1203             # utf8::encode($l);
1204             # $l =~ s/([\x{0100}-\x{ffff}])/sprintf("u%x", $1)/ge;
1205             #$l = substr(B::cstring($l), 1, -1);
1206             #$l =~ s/\\/u/g;
1207 0 0       0 $l = join('', map { $_ < 127 ? $_ : sprintf("u_%x_", $_) } unpack("U*", $l));
  0         0  
1208             }
1209 0         0 return $l;
1210             }
1211              
1212             #
1213             # Debugging stuff
1214             #
1215             sub peek_stack {
1216 0     0 0 0 sprintf "stack = %s\n", join( " ", map( $_->minipeek, @stack ) );
1217             }
1218              
1219             #
1220             # OP stuff
1221             #
1222              
1223             =head2 label
1224              
1225             We not only mark named labels in C as such - with prefix "label_".
1226              
1227             We also have to mark each known (back jumps) and yet unknown branch targets
1228             (forward jumps) for compile-time generated branch points, with the "lab_"
1229             prefix.
1230              
1231             =cut
1232              
1233             sub label {
1234 0     0 1 0 my $op = shift;
1235             # Preserve original label name for "real" labels
1236 0 0 0     0 if ($op->can("label") and $op->label) {
1237 0         0 my $l = encode_utf8 $op->label;
1238             # cc should error on duplicate named labels
1239 0         0 return sprintf( "label_%s_%x", $l, $$op);
1240             } else {
1241 0         0 return sprintf( "lab_%x", $$op );
1242             }
1243             }
1244              
1245             sub write_label {
1246 0     0 0 0 my $op = shift;
1247 0 0       0 $op->save if $$op;
1248             # debug sprintf("lab_%x:?\n", $$op) if $debug{cxstack};
1249 0 0       0 unless ($labels->{label}->{$$op}) {
1250 0         0 my $l = label($op);
1251             # named label but op not yet known?
1252 0 0 0     0 if ( $op->can("label") and $op->label ) {
1253 0         0 $l = "label_" . encode_utf8 $op->label;
1254             # only print first such label. test 21
1255             push_runtime(sprintf( " %s:", $l))
1256 0 0       0 unless $labels->{label}->{$l};
1257 0         0 $labels->{label}->{$l} = $$op;
1258             }
1259 0 0       0 if ($verbose) {
1260 0         0 push_runtime(sprintf( " %s:\t/* %s */", label($op), $op->name ));
1261             } else {
1262 0         0 push_runtime(sprintf( " %s:", label($op) ));
1263             }
1264             # avoid printing duplicate jump labels
1265 0         0 $labels->{label}->{$$op} = $l;
1266 0 0 0     0 if ($op->can("label") and $op->label ) {
1267 0 0 0     0 push(@cxstack, {
    0 0        
    0 0        
    0 0        
1268             type => 0,
1269             op => $op,
1270             nextop => ((ref($op) eq 'B::LOOP') && $op->nextop) ? $op->nextop : $op,
1271             redoop => ((ref($op) eq 'B::LOOP') && $op->redoop) ? $op->redoop : $op,
1272             lastop => ((ref($op) eq 'B::LOOP') && $op->lastop) ? $op->lastop : $op,
1273             'label' => $op->can("label") && $op->label ? $op->label : $l
1274             });
1275             }
1276             }
1277             }
1278              
1279             sub loadop {
1280 0     0 0 0 my $op = shift;
1281 0         0 my $opsym = $op->save;
1282 0         0 $op_count++; # for statistics
1283 0 0       0 runtime("PL_op = $opsym;") unless $know_op;
1284 0         0 return $opsym;
1285             }
1286              
1287             sub doop {
1288 0     0 0 0 my $op = shift;
1289 0         0 my $ppaddr = $op->ppaddr;
1290 0         0 my $sym = loadop($op);
1291 0         0 my $ppname = "pp_" . $op->name;
1292 0 0       0 if ($inline_ops) {
1293             # inlining direct calls is safe, just CALLRUNOPS for macros not
1294 0         0 $ppaddr = "Perl_".$ppname;
1295 0 0       0 $no_stack{$ppname}
1296             ? runtime("PL_op = $ppaddr(aTHX);")
1297             : runtime("PUTBACK; PL_op = $ppaddr(aTHX); SPAGAIN;");
1298             } else {
1299 0 0       0 $no_stack{$ppname}
1300             ? runtime("PL_op = $ppaddr(aTHX);")
1301             : runtime("DOOP($ppaddr);");
1302             }
1303 0         0 $know_op = 1;
1304 0         0 return $sym;
1305             }
1306              
1307             sub gimme {
1308 0     0 0 0 my $op = shift;
1309 0         0 my $want = $op->flags & OPf_WANT;
1310 0 0       0 return ( $want == OPf_WANT_VOID ? G_VOID :
    0          
    0          
1311             $want == OPf_WANT_SCALAR ? G_SCALAR :
1312             $want == OPf_WANT_LIST ? G_ARRAY :
1313             undef );
1314             }
1315              
1316             #
1317             # Code generation for PP code
1318             #
1319              
1320             # coverage: 18,19,25,...
1321             sub pp_null {
1322 0     0 0 0 my $op = shift;
1323 0         0 $B::C::nullop_count++;
1324 0         0 return $op->next;
1325             }
1326              
1327             # coverage: 102
1328             sub pp_stub {
1329 0     0 0 0 my $op = shift;
1330 0         0 my $gimme = gimme($op);
1331 0 0       0 if ( not defined $gimme ) {
    0          
1332 0         0 write_back_stack();
1333 0         0 runtime("if (block_gimme() == G_SCALAR)",
1334             "\tXPUSHs(&PL_sv_undef);");
1335             } elsif ( $gimme == G_SCALAR ) {
1336 0         0 my $obj = B::Stackobj::Const->new(sv_undef);
1337 0         0 push( @stack, $obj );
1338             }
1339 0         0 return $op->next;
1340             }
1341              
1342             # coverage: 2,21,28,30
1343             sub pp_unstack {
1344 0     0 0 0 my $op = shift;
1345 0         0 @stack = ();
1346 0         0 runtime("PP_UNSTACK;");
1347 0         0 return $op->next;
1348             }
1349              
1350             # coverage: 2,21,27,28,30
1351             sub pp_and {
1352 0     0 0 0 my $op = shift;
1353 0         0 my $next = $op->next;
1354 0         0 reload_lexicals();
1355 0         0 unshift( @bblock_todo, $next );
1356 0 0       0 if ( @stack >= 1 ) {
1357 0         0 my $obj = pop @stack;
1358 0         0 my $bool = $obj->as_bool;
1359 0         0 write_back_stack();
1360 0         0 save_or_restore_lexical_state($$next);
1361 0 0       0 if ($bool =~ /POPs/) {
1362 0         0 runtime("sv = $bool;",
1363             sprintf("if (!sv) { PUSHs(sv); goto %s;}", label($next)));
1364             } else {
1365 0         0 runtime(sprintf(
1366             "if (!$bool) { PUSHs((SV*)%s); goto %s;}", $obj->as_sv, label($next)
1367             ));
1368             }
1369             }
1370             else {
1371 0         0 save_or_restore_lexical_state($$next);
1372 0         0 runtime( sprintf( "if (!%s) goto %s;", top_bool(), label($next) ),
1373             "sp--;" );
1374             }
1375 0         0 return $op->other;
1376             }
1377              
1378             # Nearly identical to pp_and, but leaves stack unchanged.
1379             sub pp_andassign {
1380 0     0 0 0 my $op = shift;
1381 0         0 my $next = $op->next;
1382 0         0 reload_lexicals();
1383 0         0 unshift( @bblock_todo, $next );
1384 0 0       0 if ( @stack >= 1 ) {
1385 0         0 my $obj = pop @stack;
1386 0         0 my $bool = $obj->as_bool;
1387 0         0 write_back_stack();
1388 0         0 save_or_restore_lexical_state($$next);
1389 0 0       0 if ($bool =~ /POPs/) {
1390 0         0 runtime("sv = $bool;",
1391             sprintf("PUSHs((SV*)%s); if (!$bool) { goto %s;}",
1392             $obj->as_sv, label($next)));
1393             } else {
1394 0         0 runtime(
1395             sprintf("PUSHs((SV*)%s); if (!$bool) { goto %s;}",
1396             $obj->as_sv, label($next)));
1397             }
1398             }
1399             else {
1400 0         0 save_or_restore_lexical_state($$next);
1401 0         0 runtime( sprintf( "if (!%s) goto %s;", top_bool(), label($next) ) );
1402             }
1403 0         0 return $op->other;
1404             }
1405              
1406             # coverage: 28
1407             sub pp_or {
1408 0     0 0 0 my $op = shift;
1409 0         0 my $next = $op->next;
1410 0         0 reload_lexicals();
1411 0         0 unshift( @bblock_todo, $next );
1412 0 0       0 if ( @stack >= 1 ) {
1413 0         0 my $obj = pop @stack;
1414 0         0 my $bool = $obj->as_bool;
1415 0         0 write_back_stack();
1416 0         0 save_or_restore_lexical_state($$next);
1417 0 0       0 if ($bool =~ /POPs/) {
1418 0         0 runtime("sv = $bool;",
1419             sprintf("if (sv) { PUSHs(sv); goto %s;}", label($next)));
1420             } else {
1421 0         0 runtime(
1422             sprintf("if ($bool) { PUSHs((SV*)%s); goto %s; }", $obj->as_sv, label($next)));
1423             }
1424             }
1425             else {
1426 0         0 save_or_restore_lexical_state($$next);
1427 0         0 runtime( sprintf( "if (%s) goto %s;", top_bool(), label($next) ),
1428             "sp--;" );
1429             }
1430 0         0 return $op->other;
1431             }
1432              
1433             # Nearly identical to pp_or, but leaves stack unchanged.
1434             sub pp_orassign {
1435 0     0 0 0 my $op = shift;
1436 0         0 my $next = $op->next;
1437 0         0 reload_lexicals();
1438 0         0 unshift( @bblock_todo, $next );
1439 0 0       0 if ( @stack >= 1 ) {
1440 0         0 my $obj = pop @stack;
1441 0         0 my $bool = $obj->as_bool;
1442 0         0 write_back_stack();
1443 0         0 save_or_restore_lexical_state($$next);
1444 0         0 runtime(
1445             sprintf(
1446             "PUSHs((SV*)%s); if ($bool) { goto %s; }", $obj->as_sv, label($next)
1447             )
1448             );
1449             }
1450             else {
1451 0         0 save_or_restore_lexical_state($$next);
1452 0         0 runtime( sprintf( "if (%s) goto %s;", top_bool(), label($next) ) );
1453             }
1454 0         0 return $op->other;
1455             }
1456              
1457             # coverage: issue 45 (1,2)
1458             # in CORE aliased to pp_defined
1459             # default dor is okay issue 45 (3,4)
1460             sub pp_dorassign {
1461 0     0 0 0 my $op = shift;
1462 0         0 my $next = $op->next;
1463 0         0 reload_lexicals();
1464 0         0 unshift( @bblock_todo, $next );
1465 0         0 my $sv = pop @stack;
1466 0         0 write_back_stack();
1467 0         0 save_or_restore_lexical_state($$next);
1468 0 0       0 runtime( sprintf( "PUSHs(%s); if (%s && SvANY(%s)) goto %s;\t/* dorassign */",
1469             $sv->as_sv, $sv->as_sv, $sv->as_sv, label($next)) ) if $sv;
1470 0         0 return $op->other;
1471             }
1472              
1473             # coverage: 102
1474             sub pp_cond_expr {
1475 0     0 0 0 my $op = shift;
1476 0         0 my $false = $op->next;
1477 0         0 unshift( @bblock_todo, $false );
1478 0         0 reload_lexicals();
1479 0         0 my $bool = pop_bool();
1480 0         0 write_back_stack();
1481 0         0 save_or_restore_lexical_state($$false);
1482 0         0 runtime( sprintf( "if (!$bool) goto %s;\t/* cond_expr */", label($false) ) );
1483 0         0 return $op->other;
1484             }
1485              
1486             # coverage: 9,10,12,17,18,22,28,32
1487             sub pp_padsv {
1488 0     0 0 0 my $op = shift;
1489 0         0 my $ix = $op->targ;
1490 0 0       0 push( @stack, $pad[$ix] ) if $pad[$ix];
1491 0 0       0 if ( $op->flags & OPf_MOD ) {
1492 0         0 my $private = $op->private;
1493 0 0       0 if ( $private & OPpLVAL_INTRO ) {
    0          
1494             # coverage: 9,10,12,17,18,19,20,22,27,28,31,32
1495 0         0 runtime("SAVECLEARSV(PL_curpad[$ix]);");
1496             }
1497             elsif ( $private & OPpDEREF ) {
1498             # coverage: 18
1499 0 0       0 if ($] >= 5.015002) {
1500 0         0 runtime(sprintf( "PL_curpad[%d] = Perl_vivify_ref(aTHX_ PL_curpad[%d], %d);",
1501             $ix, $ix, $private & OPpDEREF ));
1502             } else {
1503 0         0 runtime(sprintf( "Perl_vivify_ref(aTHX_ PL_curpad[%d], %d);",
1504             $ix, $private & OPpDEREF ));
1505             }
1506 0         0 $vivify_ref_defined++;
1507 0 0       0 $pad[$ix]->invalidate if $pad[$ix];
1508             }
1509             }
1510 0         0 return $op->next;
1511             }
1512              
1513             # coverage: 1-5,7-14,18-23,25,27-32
1514             sub pp_const {
1515 0     0 0 0 my $op = shift;
1516 0         0 my $sv = $op->sv;
1517 0         0 my $obj;
1518              
1519             # constant could be in the pad (under useithreads)
1520 0 0       0 if ($$sv) {
1521 0         0 $obj = $constobj{$$sv};
1522 0 0       0 if ( !defined($obj) ) {
1523 0         0 $obj = $constobj{$$sv} = B::Stackobj::Const->new($sv);
1524             }
1525             }
1526             else {
1527 0         0 $obj = $pad[ $op->targ ];
1528             }
1529             # XXX looks like method_named has only const as prev op
1530 0 0 0     0 if ($op->next
      0        
1531             and $op->next->can('name')
1532             and $op->next->name eq 'method_named'
1533             ) {
1534 0         0 $package_pv = svop_or_padop_pv($op);
1535 0 0       0 debug "save package_pv \"$package_pv\" for method_name\n" if $debug{op};
1536             }
1537 0         0 push( @stack, $obj );
1538 0         0 return $op->next;
1539             }
1540              
1541             # coverage: 1-39, fails in 33
1542             sub pp_nextstate {
1543 0     0 0 0 my $op = shift;
1544 0 0 0     0 if ($labels->{'nextstate'}->[-1] and $labels->{'nextstate'}->[-1] == $op) {
1545 0 0       0 debug sprintf("pop_label nextstate: cxstack label %s\n", $curcop->[0]->label) if $debug{cxstack};
1546 0         0 pop_label 'nextstate';
1547             } else {
1548 0         0 write_label($op);
1549             }
1550 0         0 $curcop->load($op);
1551 0         0 loadop($op);
1552             #testcc 48: protect CopFILE_free and CopSTASH_free in END block (#296)
1553 0 0 0     0 if ($ppname =~ /^pp_sub_END(_\d+)?$/ and $ITHREADS) {
1554 0         0 runtime("#ifdef USE_ITHREADS",
1555             "CopFILE((COP*)PL_op) = NULL;");
1556 0 0 0     0 if ($] >= 5.018) {
    0          
1557 0         0 runtime("CopSTASH_set((COP*)PL_op, NULL);");
1558             } elsif ($] >= 5.016 and $] <= 5.017) {
1559 0         0 runtime("CopSTASHPV_set((COP*)PL_op, NULL, 0);");
1560             } else {
1561 0         0 runtime("CopSTASHPV_set((COP*)PL_op, NULL);");
1562             }
1563 0         0 runtime("#endif");
1564             }
1565 0         0 @stack = ();
1566 0 0       0 debug( sprintf( "%s:%d\n", $op->file, $op->line ) ) if $debug{lineno};
1567 0 0 0     0 debug( sprintf( "CopLABEL %s\n", $op->label ) ) if $op->label and $debug{cxstack};
1568 0 0       0 runtime("TAINT_NOT;") if $opt_taint; # TODO Not always needed (resets PL_taint = 0)
1569 0         0 runtime("sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;"); # TODO reset sp not needed always
1570 0 0 0     0 if ( $freetmps_each_bblock || $freetmps_each_loop ) {
1571 0         0 $need_freetmps = 1;
1572             }
1573             else {
1574 0         0 runtime("FREETMPS;"); # TODO Not always needed
1575             }
1576 0         0 return $op->next;
1577             }
1578              
1579             # Like pp_nextstate, but used instead when the debugger is active.
1580 0     0 0 0 sub pp_dbstate { pp_nextstate(@_) }
1581              
1582             #default_pp will handle this:
1583             #sub pp_bless { $curcop->write_back; default_pp(@_) }
1584             #sub pp_repeat { $curcop->write_back; default_pp(@_) }
1585             # The following subs need $curcop->write_back if we decide to support arybase:
1586             # pp_pos, pp_substr, pp_index, pp_rindex, pp_aslice, pp_lslice, pp_splice
1587             #sub pp_caller { $curcop->write_back; default_pp(@_) }
1588              
1589             # coverage: ny
1590             sub bad_pp_reset {
1591 0 0   0 0 0 if ($inline_ops) {
1592 0         0 my $op = shift;
1593 0 0       0 warn "inlining reset\n" if $debug{op};
1594 0 0       0 $curcop->write_back if $curcop;
1595 0         0 runtime '{ /* pp_reset */';
1596 0         0 runtime ' const char * const tmps = (MAXARG < 1) ? (const char *)"" : POPpconstx;';
1597 0         0 runtime ' sv_reset(tmps, CopSTASH(PL_curcop));}';
1598 0         0 runtime 'PUSHs(&PL_sv_yes);';
1599 0         0 return $op->next;
1600             } else {
1601 0         0 default_pp(@_);
1602             }
1603             }
1604              
1605             # coverage: 20
1606             sub pp_regcreset {
1607 0 0   0 0 0 if ($inline_ops) {
1608 0         0 my $op = shift;
1609 0 0       0 warn "inlining regcreset\n" if $debug{op};
1610 0 0       0 $curcop->write_back if $curcop;
1611 0         0 runtime 'PL_reginterp_cnt = 0; /* pp_regcreset */';
1612 0 0       0 runtime 'TAINT_NOT;' if $opt_taint;
1613 0         0 return $op->next;
1614             } else {
1615 0         0 default_pp(@_);
1616             }
1617             }
1618              
1619             # coverage: 103
1620             sub pp_stringify {
1621 0 0 0 0 0 0 if ($inline_ops and $] >= 5.008) {
1622 0         0 my $op = shift;
1623 0 0       0 warn "inlining stringify\n" if $debug{op};
1624 0         0 my $sv = top_sv();
1625 0         0 my $ix = $op->targ;
1626 0         0 my $targ = $pad[$ix];
1627 0         0 runtime "sv_copypv(PL_curpad[$ix], $sv);\t/* pp_stringify */";
1628 0 0       0 $stack[-1] = $targ if @stack;
1629 0         0 return $op->next;
1630             } else {
1631 0         0 default_pp(@_);
1632             }
1633             }
1634              
1635             # coverage: 9,10,27
1636             sub bad_pp_anoncode {
1637 0 0   0 0 0 if ($inline_ops) {
1638 0         0 my $op = shift;
1639 0 0       0 warn "inlining anoncode\n" if $debug{op};
1640 0         0 my $ix = $op->targ;
1641 0         0 my $ppname = "pp_" . $op->name;
1642 0 0       0 write_back_lexicals() unless $skip_lexicals{$ppname};
1643 0 0       0 write_back_stack() unless $skip_stack{$ppname};
1644             # XXX finish me. this works only with >= 5.10
1645 0         0 runtime '{ /* pp_anoncode */',
1646             ' CV *cv = MUTABLE_CV(PAD_SV(PL_op->op_targ));',
1647             ' if (CvCLONE(cv))',
1648             ' cv = MUTABLE_CV(sv_2mortal(MUTABLE_SV(Perl_cv_clone(aTHX_ cv))));',
1649             ' EXTEND(SP,1);',
1650             ' PUSHs(MUTABLE_SV(cv));',
1651             '}';
1652 0 0       0 invalidate_lexicals() unless $skip_invalidate{$ppname};
1653 0         0 return $op->next;
1654             } else {
1655 0         0 default_pp(@_);
1656             }
1657             }
1658              
1659             # coverage: 35
1660             # XXX TODO get prev op. For now saved in pp_const.
1661             sub pp_method_named {
1662 0     0 0 0 my ( $op ) = @_;
1663 0         0 my $name = svop_or_padop_pv($op);
1664             # The pkg PV is at [PL_stack_base+TOPMARK+1], the previous op->sv->PV.
1665 0 0       0 my $stash = $package_pv ? $package_pv."::" : "main::";
1666 0         0 $name = $stash . $name;
1667 0 0       0 if (exists &$name) {
1668 0 0       0 debug "save method_name \"$name\"\n" if $debug{op};
1669 0         0 svref_2object( \&{$name} )->save;
  0         0  
1670             } else {
1671 0 0       0 debug "skip saving non-existing method_name \"$name\"\n" if $debug{op}; #CC 50
1672             }
1673 0         0 default_pp(@_);
1674             }
1675              
1676             # inconsequence: gvs are not passed around on the stack
1677             # coverage: 26,103
1678             sub bad_pp_srefgen {
1679 0 0   0 0 0 if ($inline_ops) {
1680 0         0 my $op = shift;
1681 0 0       0 warn "inlining srefgen\n" if $debug{op};
1682             #my $ppname = "pp_" . $op->name;
1683             #$curcop->write_back;
1684             #write_back_lexicals() unless $skip_lexicals{$ppname};
1685             #write_back_stack() unless $skip_stack{$ppname};
1686 0         0 my $svobj = $stack[-1]->as_sv;
1687 0         0 my $sv = pop_sv();
1688             # XXX fix me
1689 0         0 runtime "{ /* pp_srefgen */
1690             SV* rv;
1691             SV* sv = $sv;";
1692             # sv = POPs
1693             #B::svref_2object(\$sv);
1694 0 0 0     0 if (($svobj->flags & 0xff) == $SVt_PVLV
    0          
1695             and B::PVLV::LvTYPE($svobj) eq ord('y'))
1696             {
1697 0         0 runtime 'if (LvTARGLEN(sv))
1698             vivify_defelem(sv);
1699             if (!(sv = LvTARG(sv)))
1700             sv = &PL_sv_undef;
1701             else
1702             SvREFCNT_inc_void_NN(sv);';
1703             }
1704             elsif (($svobj->flags & 0xff) == $SVt_PVAV) {
1705 0         0 runtime 'if (!AvREAL((const AV *)sv) && AvREIFY((const AV *)sv))
1706             av_reify(MUTABLE_AV(sv));
1707             SvTEMP_off(sv);
1708             SvREFCNT_inc_void_NN(sv);';
1709             }
1710             #elsif ($sv->SvPADTMP && !IS_PADGV(sv)) {
1711             # runtime 'sv = newSVsv(sv);';
1712             #}
1713             else {
1714 0         0 runtime 'SvTEMP_off(sv);
1715             SvREFCNT_inc_void_NN(sv);';
1716             }
1717 0         0 runtime 'rv = sv_newmortal();
1718             sv_upgrade(rv, SVt_IV);
1719             SvRV_set(rv, sv);
1720             SvROK_on(rv);
1721             PUSHBACK;
1722             }';
1723 0         0 return $op->next;
1724             } else {
1725 0         0 default_pp(@_);
1726             }
1727             }
1728              
1729             # coverage: 9,10,27
1730             #sub pp_refgen
1731              
1732             # coverage: 28, 14
1733             sub pp_rv2gv {
1734 0     0 0 0 my $op = shift;
1735 0 0       0 $curcop->write_back if $curcop;
1736 0         0 my $ppname = "pp_" . $op->name;
1737 0 0       0 write_back_lexicals() unless $skip_lexicals{$ppname};
1738 0 0       0 write_back_stack() unless $skip_stack{$ppname};
1739 0         0 my $sym = doop($op);
1740 0 0       0 if ( $op->private & OPpDEREF ) {
1741 0         0 $init->add( sprintf("((UNOP *)$sym)->op_first = $sym;") );
1742 0         0 $init->add( sprintf( "((UNOP *)$sym)->op_type = %d;", $op->first->type ) );
1743             }
1744 0         0 return $op->next;
1745             }
1746              
1747             # coverage: 18,19,25
1748             sub pp_sort {
1749 0     0 0 0 my $op = shift;
1750             #my $ppname = $op->ppaddr;
1751 0 0 0     0 if ( $op->flags & OPf_SPECIAL && $op->flags & OPf_STACKED ) {
1752             # blocksort is awful. E.g. we need to the leading NULL op, invalidates -fcop
1753             # Ugly surgery required. sort expects as block: pushmark rv2gv leave => enter
1754             # pp_sort() OP *kid = cLISTOP->op_first->op_sibling;/* skip over pushmark 4 to null */
1755             # kid = cUNOPx(kid)->op_first; /* pass rv2gv (null'ed) */
1756             # kid = cUNOPx(kid)->op_first; /* pass leave */
1757             #
1758             #3 <0> pushmark s ->4
1759             #8 <@> sort lKS* ->9
1760             #4 <0> pushmark s ->5
1761             #- <1> null sK/1 ->5
1762             #- <1> ex-leave sKP ->-
1763             #- <0> enter s ->-
1764             # some code doing cmp or ncmp
1765             # Example with 3 const args: print sort { bla; $b <=> $a } 1,4,3
1766             #5 <$> const[IV 1] s ->6
1767             #6 <$> const[IV 4] s ->7
1768             #7 <$> const[IV 3] s ->8 => sort
1769             #
1770 0         0 my $root = $op->first->sibling->first; #leave or null
1771 0         0 my $start = $root->first; #enter
1772 0 0       0 warn "blocksort: root=",$root->name,", start=",$start->name,"\n" if $debug{op};
1773 0         0 my $pushmark = $op->first->save; #pushmark sibling to null
1774 0         0 $op->first->sibling->save; #null->first to leave
1775 0         0 $root->save; #ex-leave
1776 0         0 my $sym = $start->save; #enter
1777 0         0 my $fakeop = cc_queue( "pp_sort" . sprintf("%x",abs($$op)), $root, $start );
1778 0         0 $init->add( sprintf( "(%s)->op_next = %s;", $sym, $fakeop ) );
1779             }
1780 0         0 $curcop->write_back;
1781 0         0 write_back_lexicals();
1782 0         0 write_back_stack();
1783 0         0 doop($op);
1784 0         0 return $op->next;
1785             }
1786              
1787             # coverage: 2-4,6,7,13,15,21,24,26,27,30,31
1788             sub pp_gv {
1789 0     0 0 0 my $op = shift;
1790 0         0 my $gvsym;
1791 0 0       0 if ($ITHREADS) {
1792 0         0 $gvsym = $pad[ $op->padix ]->as_sv;
1793             #push @stack, ($pad[$op->padix]);
1794             }
1795             else {
1796 0         0 $gvsym = $op->gv->save;
1797             # XXX
1798             #my $obj = new B::Stackobj::Const($op->gv);
1799             #push( @stack, $obj );
1800             }
1801 0         0 write_back_stack();
1802 0         0 runtime("XPUSHs((SV*)$gvsym);");
1803 0         0 return $op->next;
1804             }
1805              
1806             # coverage: 2,3,4,9,11,14,20,21,23,28
1807             sub pp_gvsv {
1808 0     0 0 0 my $op = shift;
1809 0         0 my $gvsym;
1810 0 0       0 if ($ITHREADS) {
1811             #debug(sprintf("OP name=%s, class=%s\n",$op->name,B::class($op))) if $debug{pad};
1812 0 0       0 debug( sprintf( "GVSV->padix = %d\n", $op->padix ) ) if $debug{pad};
1813 0         0 $gvsym = $pad[ $op->padix ]->as_sv;
1814 0 0       0 debug( sprintf( "GVSV->private = 0x%x\n", $op->private ) ) if $debug{pad};
1815             }
1816             else {
1817 0         0 $gvsym = $op->gv->save;
1818             }
1819             # Expects GV*, not SV* PL_curpad
1820 0 0       0 $gvsym = "(GV*)$gvsym" if $gvsym =~ /PL_curpad/;
1821 0         0 write_back_stack();
1822 0 0       0 if ( $op->private & OPpLVAL_INTRO ) {
1823 0         0 runtime("XPUSHs(save_scalar($gvsym));");
1824             #my $obj = new B::Stackobj::Const($op->gv);
1825             #push( @stack, $obj );
1826             }
1827             else {
1828 0 0       0 $PERL510
1829             ? runtime("XPUSHs(GvSVn($gvsym));")
1830             : runtime("XPUSHs(GvSV($gvsym));");
1831             }
1832 0         0 return $op->next;
1833             }
1834              
1835             # Check for faster fetch calls. Returns 0 if the fast 'no' is in effect.
1836             sub autovivification {
1837 0 0   0 0 0 if (!$opt_autovivify) {
    0          
1838 0         0 return 0;
1839             } elsif ($INC{'autovivification.pm'}) {
1840 0         0 return _autovivification($curcop->[0]);
1841             } else {
1842 0         0 return 1;
1843             }
1844             }
1845              
1846             # coverage: 16, issue44
1847             sub pp_aelemfast {
1848 0     0 0 0 my $op = shift;
1849 0         0 my ($av, $rmg);
1850 0 0       0 if ($op->flags & OPf_SPECIAL) {
1851 0         0 my $sv = $pad[ $op->targ ]->as_sv;
1852 0         0 my @c = comppadlist->ARRAY;
1853 0         0 my @p = $c[1]->ARRAY;
1854 0         0 my $lex = $p[ $op->targ ];
1855 0 0 0     0 $rmg = ($lex and ref $lex eq 'B::AV' and ($lex->MAGICAL & SVs_RMG or !$lex->ARRAY)) ? 1 : 0;
1856             # MUTABLE_AV is only needed to catch compiler const loss
1857             # $av = $] > 5.01000 ? "MUTABLE_AV($sv)" : $sv;
1858 0         0 $av = "(AV*)$sv";
1859             } else {
1860 0         0 my $gvsym;
1861 0 0       0 if ($ITHREADS) { #padop XXX if it's only a OP, no PADOP? t/CORE/op/ref.t test 36
1862 0 0       0 if ($op->can('padix')) {
1863             #warn "padix\n";
1864 0         0 $gvsym = $pad[ $op->padix ]->as_sv;
1865 0         0 my @c = comppadlist->ARRAY; # XXX curpad, not comppad!!
1866 0         0 my @p = $c[1]->ARRAY;
1867 0         0 my $lex = $p[ $op->padix ];
1868 0 0 0     0 $rmg = ($lex and ref $lex eq 'B::AV' and ($lex->MAGICAL & SVs_RMG or !$lex->ARRAY)) ? 1 : 0;
1869             } else {
1870 0         0 $gvsym = 'PL_incgv'; # XXX passes, but need to investigate why. cc test 43 5.10.1
1871             #write_back_stack();
1872             #runtime("PUSHs(&PL_sv_undef);");
1873             #return $op->next;
1874             }
1875             }
1876             else { #svop
1877 0         0 my $gv = $op->gv;
1878 0         0 $gvsym = $gv->save;
1879 0         0 my $gvav = $gv->AV; # test 16, tied gvav
1880 0 0 0     0 $rmg = $] < 5.007 ? 0 : ($gvav and ($gvav->MAGICAL & SVs_RMG or !$gvav->ARRAY)) ? 1 : 0;
    0          
1881             }
1882 0         0 $av = "GvAV($gvsym)";
1883             }
1884 0         0 my $ix = $op->private;
1885 0         0 my $lval = $op->flags & OPf_MOD;
1886 0 0       0 my $vivify = !$rmg ? autovivification() : 1; # no need to call if $rmg
1887 0 0       0 debug "aelemfast: vivify=$vivify, rmg=$rmg, lval=$lval, -fautovivify=$opt_autovivify -faelem=$opt_aelem\n" if $debug{pad};
1888 0         0 return _aelem($op, $av, $ix, $lval, $rmg, $vivify);
1889             }
1890              
1891             sub _aelem {
1892 0     0   0 my ($op, $av, $ix, $lval, $rmg, $vivify) = @_;
1893 0 0 0     0 if ($opt_aelem and !$rmg and !$vivify and $ix >= 0) {
      0        
      0        
1894 0         0 push @stack, B::Stackobj::Aelem->new($av, $ix, $lval);
1895             } else {
1896 0         0 write_back_stack();
1897 0 0 0     0 runtime(
1898             "{ AV* av = (AV*)$av;",
1899             " SV** const svp = av_fetch(av, $ix, $lval);",
1900             " SV *sv = (svp ? *svp : &PL_sv_undef);",
1901             (!$lval and $rmg) ? " if (SvRMAGICAL(av) && SvGMAGICAL(sv)) mg_get(sv);" : "",
1902             " PUSHs(sv);",
1903             "}"
1904             );
1905             }
1906 0         0 return $op->next;
1907             }
1908              
1909             # coverage: ?
1910             sub pp_aelem {
1911 0     0 0 0 my $op = shift;
1912 0         0 my ($ix, $av);
1913 0 0 0     0 my $lval = ($op->flags & OPf_MOD or $op->private & (OPpLVAL_DEFER || OPpLVAL_INTRO)) ? 1 : 0;
1914 0         0 my $vivify = autovivification();
1915 0         0 my $rmg = $opt_magic; # use -fno-magic for the av (2nd stack arg)
1916 0 0       0 if (@stack >= 1) { # at least ix
1917 0         0 $ix = pop_int(); # TODO: substract CopARYBASE from ix
1918 0 0       0 if (@stack >= 1) {
1919 0         0 my $avobj = $stack[-1]->as_obj;
1920 0 0 0     0 $rmg = ($avobj and $avobj->MAGICAL & SVs_RMG) ? 1 : 0;
1921             }
1922 0         0 $av = pop_sv();
1923 0 0       0 debug "aelem: vivify = $vivify, rmg = $rmg, lval = $lval\n" if $debug{pad};
1924 0         0 return _aelem($op, $av, $ix, $lval, $rmg, $vivify);
1925             } else {
1926 0 0 0     0 if ($lval or $rmg) { # always
1927 0         0 return default_pp($op);
1928             } else {
1929 0         0 $ix = pop_int(); # TODO: substract CopARYBASE from ix
1930 0         0 $av = pop_sv();
1931 0 0       0 debug "aelem: vivify = $vivify, rmg = $rmg, lval = $lval\n" if $debug{pad};
1932 0         0 return _aelem($op, $av, $ix, $lval, $rmg, $vivify);
1933             }
1934             }
1935             }
1936              
1937             # coverage: ?
1938             sub int_binop {
1939 0     0 0 0 my ( $op, $operator, $unsigned ) = @_;
1940 0 0       0 if ( $op->flags & OPf_STACKED ) {
1941 0         0 my $right = pop_int();
1942 0 0       0 if ( @stack >= 1 ) {
1943 0         0 my $left = top_int();
1944 0         0 $stack[-1]->set_int( &$operator( $left, $right ), $unsigned );
1945             }
1946             else {
1947 0 0       0 my $sv_setxv = $unsigned ? 'sv_setuv' : 'sv_setiv';
1948 0         0 runtime( sprintf( "$sv_setxv(TOPs, %s);", &$operator( "TOPi", $right ) ) );
1949             }
1950             }
1951             else {
1952 0         0 my $targ = $pad[ $op->targ ];
1953 0         0 my $right = B::Pseudoreg->new( "IV", "riv" );
1954 0         0 my $left = B::Pseudoreg->new( "IV", "liv" );
1955 0         0 runtime( sprintf( "$$right = %s; $$left = %s;", pop_int(), pop_int ) );
1956 0         0 $targ->set_int( &$operator( $$left, $$right ), $unsigned );
1957 0         0 push( @stack, $targ );
1958             }
1959 0         0 return $op->next;
1960             }
1961              
1962             sub INTS_CLOSED () { 0x1 }
1963             sub INT_RESULT () { 0x2 }
1964             sub NUMERIC_RESULT () { 0x4 }
1965              
1966             # coverage: 101
1967             sub numeric_binop {
1968 0     0 0 0 my ( $op, $operator, $flags ) = @_;
1969 0         0 my $force_int = 0;
1970 0 0       0 $flags = 0 unless $flags;
1971 0   0     0 $force_int ||= ( $flags & INT_RESULT );
1972 0   0     0 $force_int ||=
      0        
1973             ( $flags & INTS_CLOSED
1974             && @stack >= 2
1975             && valid_int( $stack[-2] )
1976             && valid_int( $stack[-1] ) );
1977 0 0       0 if ( $op->flags & OPf_STACKED ) {
1978 0 0       0 runtime(sprintf("/* %s */", $op->name)) if $verbose;
1979 0         0 my $right = pop_numeric();
1980 0 0       0 if ( @stack >= 1 ) {
1981 0         0 my $left = top_numeric();
1982 0 0       0 if ($force_int) {
1983 0         0 $stack[-1]->set_int( &$operator( $left, $right ) );
1984             }
1985             else {
1986 0         0 $stack[-1]->set_numeric( &$operator( $left, $right ) );
1987             }
1988             }
1989             else {
1990 0 0       0 if ($force_int) {
1991 0         0 my $rightruntime = B::Pseudoreg->new( "IV", "riv" );
1992 0         0 runtime( sprintf( "$$rightruntime = %s;", $right ) );
1993 0         0 runtime(
1994             sprintf(
1995             "sv_setiv(TOPs, %s);", &$operator( "TOPi", $$rightruntime )
1996             )
1997             );
1998             }
1999             else {
2000 0         0 my $rightruntime = B::Pseudoreg->new( "NV", "rnv" );
2001 0         0 runtime( sprintf( "$$rightruntime = %s;\t/* %s */", $right, $op->name ) );
2002 0         0 runtime(
2003             sprintf(
2004             "sv_setnv(TOPs, %s);", &$operator( "TOPn", $$rightruntime )
2005             )
2006             );
2007             }
2008             }
2009             }
2010             else {
2011 0         0 my $targ = $pad[ $op->targ ];
2012 0   0     0 $force_int ||= ( $targ->{type} == T_INT );
2013 0 0       0 if ($force_int) {
2014 0         0 my $right = B::Pseudoreg->new( "IV", "riv" );
2015 0         0 my $left = B::Pseudoreg->new( "IV", "liv" );
2016 0         0 runtime(
2017             sprintf( "$$right = %s;", pop_numeric()),
2018             sprintf( "$$left = %s;\t/* %s */", pop_numeric(), pop_numeric(), $op->name ) );
2019 0         0 $targ->set_int( &$operator( $$left, $$right ) );
2020             }
2021             else {
2022 0         0 my $right = B::Pseudoreg->new( "NV", "rnv" );
2023 0         0 my $left = B::Pseudoreg->new( "NV", "lnv" );
2024 0         0 runtime(
2025             sprintf( "$$right = %s;", pop_numeric()),
2026             sprintf( "$$left = %s;\t/* %s */", pop_numeric(), $op->name ) );
2027 0         0 $targ->set_numeric( &$operator( $$left, $$right ) );
2028             }
2029 0         0 push( @stack, $targ );
2030             }
2031 0         0 return $op->next;
2032             }
2033              
2034             sub numeric_unop {
2035 0     0 0 0 my ( $op, $operator, $flags ) = @_;
2036 0         0 my $force_int = 0;
2037 0   0     0 $force_int ||= ( $flags & INT_RESULT );
2038 0   0     0 $force_int ||=
      0        
2039             ( $flags & INTS_CLOSED
2040             && @stack >= 1
2041             && valid_int( $stack[-1] ) );
2042 0         0 my $targ = $pad[ $op->targ ];
2043 0   0     0 $force_int ||= ( $targ->{type} == T_INT );
2044 0 0       0 if ($force_int) {
2045 0         0 my $arg = B::Pseudoreg->new( "IV", "liv" );
2046 0         0 runtime(sprintf( "$$arg = %s;\t/* %s */",
2047             pop_numeric, $op->name ) );
2048             # XXX set targ?
2049 0         0 $targ->set_int( &$operator( $$arg ) );
2050             }
2051             else {
2052 0         0 my $arg = B::Pseudoreg->new( "NV", "lnv" );
2053 0         0 runtime(sprintf( "$$arg = %s;\t/* %s */",
2054             pop_numeric, $op->name ) );
2055             # XXX set targ?
2056 0         0 $targ->set_numeric( &$operator( $$arg ) );
2057             }
2058 0         0 push( @stack, $targ );
2059 0         0 return $op->next;
2060             }
2061              
2062             # coverage: 18
2063             sub pp_ncmp {
2064 0     0 0 0 my ($op) = @_;
2065 0 0       0 if ( $op->flags & OPf_STACKED ) {
2066 0         0 my $right = pop_numeric();
2067 0 0       0 if ( @stack >= 1 ) {
2068 0         0 my $left = top_numeric();
2069 0         0 runtime sprintf( "if (%s > %s){\t/* %s */", $left, $right, $op->name );
2070 0         0 $stack[-1]->set_int(1);
2071 0         0 $stack[-1]->write_back();
2072 0         0 runtime sprintf( "}else if (%s < %s ) {", $left, $right );
2073 0         0 $stack[-1]->set_int(-1);
2074 0         0 $stack[-1]->write_back();
2075 0         0 runtime sprintf( "}else if (%s == %s) {", $left, $right );
2076 0         0 $stack[-1]->set_int(0);
2077 0         0 $stack[-1]->write_back();
2078 0         0 runtime sprintf("}else {");
2079 0         0 $stack[-1]->set_sv("&PL_sv_undef");
2080 0         0 runtime "}";
2081             }
2082             else {
2083 0         0 my $rightruntime = B::Pseudoreg->new( "NV", "rnv" );
2084 0         0 runtime( sprintf( "$$rightruntime = %s;\t/* %s */", $right, $op->name ) );
2085 0         0 runtime sprintf( qq/if ("TOPn" > %s){/, $rightruntime );
2086 0         0 runtime sprintf(" sv_setiv(TOPs,1);");
2087 0         0 runtime sprintf( qq/}else if ( "TOPn" < %s ) {/, $$rightruntime );
2088 0         0 runtime sprintf(" sv_setiv(TOPs,-1);");
2089 0         0 runtime sprintf( qq/} else if ("TOPn" == %s) {/, $$rightruntime );
2090 0         0 runtime sprintf(" sv_setiv(TOPs,0);");
2091 0         0 runtime sprintf(qq/}else {/);
2092 0         0 runtime sprintf(" sv_setiv(TOPs,&PL_sv_undef;");
2093 0         0 runtime "}";
2094             }
2095             }
2096             else {
2097 0         0 my $targ = $pad[ $op->targ ];
2098 0         0 my $right = B::Pseudoreg->new( "NV", "rnv" );
2099 0         0 my $left = B::Pseudoreg->new( "NV", "lnv" );
2100 0         0 runtime(
2101             sprintf( "$$right = %s; $$left = %s;\t/* %s */",
2102             pop_numeric(), pop_numeric, $op->name ) );
2103 0         0 runtime sprintf( "if (%s > %s){ /*targ*/", $$left, $$right );
2104 0         0 $targ->set_int(1);
2105 0         0 $targ->write_back();
2106 0         0 runtime sprintf( "}else if (%s < %s ) {", $$left, $$right );
2107 0         0 $targ->set_int(-1);
2108 0         0 $targ->write_back();
2109 0         0 runtime sprintf( "}else if (%s == %s) {", $$left, $$right );
2110 0         0 $targ->set_int(0);
2111 0         0 $targ->write_back();
2112 0         0 runtime sprintf("}else {");
2113 0         0 $targ->set_sv("&PL_sv_undef");
2114 0         0 runtime "}";
2115 0         0 push( @stack, $targ );
2116             }
2117             #runtime "return NULL;";
2118 0         0 return $op->next;
2119             }
2120              
2121             # coverage: ?
2122             sub sv_binop {
2123 0     0 0 0 my ( $op, $operator, $flags ) = @_;
2124 0 0       0 if ( $op->flags & OPf_STACKED ) {
2125 0         0 my $right = pop_sv();
2126 0 0       0 if ( @stack >= 1 ) {
2127 0         0 my $left = top_sv();
2128 0 0       0 if ( $flags & INT_RESULT ) {
    0          
2129 0         0 $stack[-1]->set_int( &$operator( $left, $right ) );
2130             }
2131             elsif ( $flags & NUMERIC_RESULT ) {
2132 0         0 $stack[-1]->set_numeric( &$operator( $left, $right ) );
2133             }
2134             else {
2135             # XXX Does this work?
2136 0         0 runtime(
2137             sprintf( "sv_setsv($left, %s);\t/* %s */",
2138             &$operator( $left, $right ), $op->name ) );
2139 0         0 $stack[-1]->invalidate;
2140             }
2141             }
2142             else {
2143 0         0 my $f;
2144 0 0       0 if ( $flags & INT_RESULT ) {
    0          
2145 0         0 $f = "sv_setiv";
2146             }
2147             elsif ( $flags & NUMERIC_RESULT ) {
2148 0         0 $f = "sv_setnv";
2149             }
2150             else {
2151 0         0 $f = "sv_setsv";
2152             }
2153 0         0 runtime( sprintf( "%s(TOPs, %s);\t/* %s */",
2154             $f, &$operator( "TOPs", $right ), $op->name ) );
2155             }
2156             }
2157             else {
2158 0         0 my $targ = $pad[ $op->targ ];
2159 0         0 runtime( sprintf( "right = %s; left = %s;\t/* %s */",
2160             pop_sv(), pop_sv, $op->name ) );
2161 0 0       0 if ( $flags & INT_RESULT ) {
    0          
2162 0         0 $targ->set_int( &$operator( "left", "right" ) );
2163             }
2164             elsif ( $flags & NUMERIC_RESULT ) {
2165 0         0 $targ->set_numeric( &$operator( "left", "right" ) );
2166             }
2167             else {
2168             # XXX Does this work?
2169 0         0 runtime(sprintf("sv_setsv(%s, %s);",
2170             $targ->as_sv, &$operator( "left", "right" ) ));
2171 0         0 $targ->invalidate;
2172             }
2173 0         0 push( @stack, $targ );
2174             }
2175 0         0 return $op->next;
2176             }
2177              
2178             # coverage: ?
2179             sub bool_int_binop {
2180 0     0 0 0 my ( $op, $operator ) = @_;
2181 0         0 my $right = B::Pseudoreg->new( "IV", "riv" );
2182 0         0 my $left = B::Pseudoreg->new( "IV", "liv" );
2183 0         0 runtime( sprintf( "$$right = %s; $$left = %s;\t/* %s */",
2184             pop_int(), pop_int(), $op->name ) );
2185 0         0 my $bool = B::Stackobj::Bool->new( B::Pseudoreg->new( "int", "b" ) );
2186 0         0 $bool->set_int( &$operator( $$left, $$right ) );
2187 0         0 push( @stack, $bool );
2188 0         0 return $op->next;
2189             }
2190              
2191             # coverage: ?
2192             sub bool_numeric_binop {
2193 0     0 0 0 my ( $op, $operator ) = @_;
2194 0         0 my $right = B::Pseudoreg->new( "NV", "rnv" );
2195 0         0 my $left = B::Pseudoreg->new( "NV", "lnv" );
2196 0         0 runtime(
2197             sprintf( "$$right = %s; $$left = %s;\t/* %s */",
2198             pop_numeric(), pop_numeric(), $op->name ) );
2199 0         0 my $bool = B::Stackobj::Bool->new( B::Pseudoreg->new( "int", "b" ) );
2200 0         0 $bool->set_numeric( &$operator( $$left, $$right ) );
2201 0         0 push( @stack, $bool );
2202 0         0 return $op->next;
2203             }
2204              
2205             # coverage: ?
2206             sub bool_sv_binop {
2207 0     0 0 0 my ( $op, $operator ) = @_;
2208 0         0 runtime( sprintf( "right = %s; left = %s;\t/* %s */",
2209             pop_sv(), pop_sv(), $op->name ) );
2210 0         0 my $bool = B::Stackobj::Bool->new( B::Pseudoreg->new( "int", "b" ) );
2211 0         0 $bool->set_numeric( &$operator( "left", "right" ) );
2212 0         0 push( @stack, $bool );
2213 0         0 return $op->next;
2214             }
2215              
2216             # coverage: ?
2217             sub infix_op {
2218 182     182 0 157 my $opname = shift;
2219 0     0   0 return sub { "$_[0] $opname $_[1]" }
2220 182         46803 }
2221              
2222             # coverage: ?
2223             sub prefix_op {
2224 42     42 0 40 my $opname = shift;
2225 0     0   0 return sub { sprintf( "%s(%s)", $opname, join( ", ", @_ ) ) }
2226 42         141 }
2227              
2228 0         0 BEGIN {
2229 14     14   49 my $plus_op = infix_op("+");
2230 14         26 my $minus_op = infix_op("-");
2231 14         28 my $multiply_op = infix_op("*");
2232 14         37 my $divide_op = infix_op("/");
2233 14         31 my $modulo_op = infix_op("%");
2234 14         30 my $lshift_op = infix_op("<<");
2235 14         25 my $rshift_op = infix_op(">>");
2236 14         32 my $scmp_op = prefix_op("sv_cmp");
2237 14         25 my $seq_op = prefix_op("sv_eq");
2238 14         29 my $sne_op = prefix_op("!sv_eq");
2239 14         43 my $slt_op = sub { "sv_cmp($_[0], $_[1]) < 0" };
  0         0  
2240 14         34 my $sgt_op = sub { "sv_cmp($_[0], $_[1]) > 0" };
  0         0  
2241 14         25 my $sle_op = sub { "sv_cmp($_[0], $_[1]) <= 0" };
  0         0  
2242 14         28 my $sge_op = sub { "sv_cmp($_[0], $_[1]) >= 0" };
  0         0  
2243 14         27 my $eq_op = infix_op("==");
2244 14         24 my $ne_op = infix_op("!=");
2245 14         33 my $lt_op = infix_op("<");
2246 14         33 my $gt_op = infix_op(">");
2247 14         30 my $le_op = infix_op("<=");
2248 14         30 my $ge_op = infix_op(">=");
2249              
2250             #
2251             # XXX The standard perl PP code has extra handling for
2252             # some special case arguments of these operators.
2253             #
2254 0     0 0 0 sub pp_add { numeric_binop( $_[0], $plus_op ) }
2255 0     0 0 0 sub pp_subtract { numeric_binop( $_[0], $minus_op ) }
2256 0     0 0 0 sub pp_multiply { numeric_binop( $_[0], $multiply_op ) }
2257 0     0 0 0 sub pp_divide { numeric_binop( $_[0], $divide_op ) }
2258              
2259 0     0 0 0 sub pp_modulo { int_binop( $_[0], $modulo_op ) } # differs from perl's
2260             # http://perldoc.perl.org/perlop.html#Shift-Operators:
2261             # If use integer is in force then signed C integers are used,
2262             # else unsigned C integers are used.
2263 0     0 0 0 sub pp_left_shift { int_binop( $_[0], $lshift_op, VALID_UNSIGNED ) }
2264 0     0 0 0 sub pp_right_shift { int_binop( $_[0], $rshift_op, VALID_UNSIGNED ) }
2265 0     0 0 0 sub pp_i_add { int_binop( $_[0], $plus_op ) }
2266 0     0 0 0 sub pp_i_subtract { int_binop( $_[0], $minus_op ) }
2267 0     0 0 0 sub pp_i_multiply { int_binop( $_[0], $multiply_op ) }
2268 0     0 0 0 sub pp_i_divide { int_binop( $_[0], $divide_op ) }
2269 0     0 0 0 sub pp_i_modulo { int_binop( $_[0], $modulo_op ) }
2270              
2271 0     0 0 0 sub pp_eq { bool_numeric_binop( $_[0], $eq_op ) }
2272 0     0 0 0 sub pp_ne { bool_numeric_binop( $_[0], $ne_op ) }
2273             # coverage: 21
2274 0     0 0 0 sub pp_lt { bool_numeric_binop( $_[0], $lt_op ) }
2275             # coverage: 28
2276 0     0 0 0 sub pp_gt { bool_numeric_binop( $_[0], $gt_op ) }
2277 0     0 0 0 sub pp_le { bool_numeric_binop( $_[0], $le_op ) }
2278 0     0 0 0 sub pp_ge { bool_numeric_binop( $_[0], $ge_op ) }
2279              
2280 0     0 0 0 sub pp_i_eq { bool_int_binop( $_[0], $eq_op ) }
2281 0     0 0 0 sub pp_i_ne { bool_int_binop( $_[0], $ne_op ) }
2282 0     0 0 0 sub pp_i_lt { bool_int_binop( $_[0], $lt_op ) }
2283 0     0 0 0 sub pp_i_gt { bool_int_binop( $_[0], $gt_op ) }
2284 0     0 0 0 sub pp_i_le { bool_int_binop( $_[0], $le_op ) }
2285 0     0 0 0 sub pp_i_ge { bool_int_binop( $_[0], $ge_op ) }
2286              
2287 0     0 0 0 sub pp_scmp { sv_binop( $_[0], $scmp_op, INT_RESULT ) }
2288 0     0 0 0 sub pp_slt { bool_sv_binop( $_[0], $slt_op ) }
2289 0     0 0 0 sub pp_sgt { bool_sv_binop( $_[0], $sgt_op ) }
2290 0     0 0 0 sub pp_sle { bool_sv_binop( $_[0], $sle_op ) }
2291 0     0 0 0 sub pp_sge { bool_sv_binop( $_[0], $sge_op ) }
2292 0     0 0 0 sub pp_seq { bool_sv_binop( $_[0], $seq_op ) }
2293 0     0 0 0 sub pp_sne { bool_sv_binop( $_[0], $sne_op ) }
2294              
2295             # sub pp_sin { numeric_unop( $_[0], prefix_op("Perl_sin"), NUMERIC_RESULT ) }
2296             # sub pp_cos { numeric_unop( $_[0], prefix_op("Perl_cos"), NUMERIC_RESULT ) }
2297             # sub pp_exp { numeric_unop( $_[0], prefix_op("Perl_exp"), NUMERIC_RESULT ) }
2298             # sub pp_abs { numeric_unop( $_[0], prefix_op("abs") ) }
2299             # sub pp_negate { numeric_unop( $_[0], sub { "- $_[0]" }; ) }
2300              
2301             # pow has special perl logic
2302             ## sub pp_pow { numeric_binop( $_[0], prefix_op("Perl_pow"), NUMERIC_RESULT ) }
2303             #XXX log and sqrt need to check negative args
2304             # sub pp_sqrt { numeric_unop( $_[0], prefix_op("Perl_sqrt"), NUMERIC_RESULT ) }
2305             # sub pp_log { numeric_unop( $_[0], prefix_op("Perl_log"), NUMERIC_RESULT ) }
2306             # sub pp_atan2 { numeric_binop( $_[0], prefix_op("Perl_atan2"), NUMERIC_RESULT ) }
2307              
2308             }
2309              
2310             # coverage: 3,4,9,10,11,12,17,18,20,21,23
2311             sub pp_sassign {
2312 0     0 0 0 my $op = shift;
2313 0         0 my $backwards = $op->private & OPpASSIGN_BACKWARDS;
2314 0 0       0 debug( sprintf( "sassign->private=0x%x\n", $op->private ) ) if $debug{op};
2315 0         0 my ( $dst, $src );
2316 0 0       0 runtime("/* pp_sassign */") if $verbose;
2317 0 0       0 if ( @stack >= 2 ) {
    0          
2318 0         0 $dst = pop @stack;
2319 0         0 $src = pop @stack;
2320 0 0       0 ( $src, $dst ) = ( $dst, $src ) if $backwards;
2321 0         0 my $type = $src->{type};
2322 0 0       0 if ( $type == T_INT ) {
    0          
2323 0         0 $dst->set_int( $src->as_int, $src->{flags} & VALID_UNSIGNED );
2324             }
2325             elsif ( $type == T_NUM ) {
2326 0         0 $dst->set_numeric( $src->as_numeric );
2327             }
2328             else {
2329 0         0 $dst->set_sv( $src->as_sv );
2330             }
2331 0         0 push( @stack, $dst );
2332             }
2333             elsif ( @stack == 1 ) {
2334 0 0       0 if ($backwards) {
2335 0         0 my $src = pop @stack;
2336 0         0 my $type = $src->{type};
2337 0 0       0 runtime("if (PL_tainting && PL_tainted) TAINT_NOT;") if $opt_taint;
2338 0 0       0 if ( $type == T_INT ) {
    0          
2339 0 0       0 if ( $src->{flags} & VALID_UNSIGNED ) {
2340 0         0 runtime sprintf( "sv_setuv(TOPs, %s);", $src->as_int );
2341             }
2342             else {
2343 0         0 runtime sprintf( "sv_setiv(TOPs, %s);", $src->as_int );
2344             }
2345             }
2346             elsif ( $type == T_NUM ) {
2347 0         0 runtime sprintf( "sv_setnv(TOPs, %s);", $src->as_double );
2348             }
2349             else {
2350 0         0 runtime sprintf( "sv_setsv(TOPs, %s);", $src->as_sv );
2351             }
2352 0 0       0 runtime("SvSETMAGIC(TOPs);") if $opt_magic;
2353             }
2354             else {
2355 0         0 my $dst = $stack[-1];
2356 0         0 my $type = $dst->{type};
2357 0         0 runtime("sv = POPs;");
2358 0 0       0 runtime("MAYBE_TAINT_SASSIGN_SRC(sv);") if $opt_taint;
2359 0 0       0 if ( $type == T_INT ) {
    0          
2360 0         0 $dst->set_int("SvIV(sv)");
2361             }
2362             elsif ( $type == T_NUM ) {
2363 0         0 $dst->set_double("SvNV(sv)");
2364             }
2365             else {
2366 0 0       0 $opt_magic
2367             ? runtime("SvSetMagicSV($dst->{sv}, sv);")
2368             : runtime("SvSetSV($dst->{sv}, sv);");
2369 0         0 $dst->invalidate;
2370             }
2371             }
2372             }
2373             else {
2374             # empty perl stack, both at run-time
2375 0 0       0 if ($backwards) {
2376 0         0 runtime("src = POPs; dst = TOPs;");
2377             }
2378             else {
2379 0         0 runtime("dst = POPs; src = TOPs;");
2380             }
2381 0 0       0 runtime(
    0          
2382             $opt_taint ? "MAYBE_TAINT_SASSIGN_SRC(src);" : "",
2383             "SvSetSV(dst, src);",
2384             $opt_magic ? "SvSETMAGIC(dst);" : "",
2385             "SETs(dst);"
2386             );
2387             }
2388 0         0 return $op->next;
2389             }
2390              
2391             # coverage: ny
2392             sub pp_preinc {
2393 0     0 0 0 my $op = shift;
2394 0 0       0 if ( @stack >= 1 ) {
2395 0         0 my $obj = $stack[-1];
2396 0         0 my $type = $obj->{type};
2397 0 0 0     0 if ( $type == T_INT || $type == T_NUM ) {
2398 0         0 $obj->set_int( $obj->as_int . " + 1" );
2399             }
2400             else {
2401 0         0 runtime sprintf( "PP_PREINC(%s);", $obj->as_sv );
2402 0         0 $obj->invalidate();
2403             }
2404             }
2405             else {
2406 0         0 runtime sprintf("PP_PREINC(TOPs);");
2407             }
2408 0         0 return $op->next;
2409             }
2410              
2411             # coverage: 1-32,35
2412             sub pp_pushmark {
2413 0     0 0 0 my $op = shift;
2414             # runtime(sprintf("/* %s */", $op->name)) if $verbose;
2415 0         0 write_back_stack();
2416 0         0 runtime("PUSHMARK(sp);");
2417 0         0 return $op->next;
2418             }
2419              
2420             # coverage: 28
2421             sub pp_list {
2422 0     0 0 0 my $op = shift;
2423 0 0       0 runtime(sprintf("/* %s */", $op->name)) if $verbose;
2424 0         0 write_back_stack();
2425 0         0 my $gimme = gimme($op);
2426 0 0       0 if ( not defined $gimme ) {
    0          
2427 0         0 runtime("PP_LIST(block_gimme());");
2428             } elsif ( $gimme == G_ARRAY ) { # sic
2429 0         0 runtime("POPMARK;"); # need this even though not a "full" pp_list
2430             }
2431             else {
2432 0         0 runtime("PP_LIST($gimme);");
2433             }
2434 0         0 return $op->next;
2435             }
2436              
2437             # coverage: 6,8,9,10,24,26,27,31,35
2438             sub pp_entersub {
2439 0     0 0 0 my $op = shift;
2440 0 0       0 runtime(sprintf("/* %s */", $op->name)) if $verbose;
2441 0 0       0 $curcop->write_back if $curcop;
2442 0         0 write_back_lexicals( REGISTER | TEMPORARY );
2443 0         0 write_back_stack();
2444 0         0 my $sym = doop($op);
2445 0 0       0 $op->next->save if ${$op->next};
  0         0  
2446 0 0 0     0 $op->first->save if ${$op->first} and $op->first->type;
  0         0  
2447             # sometimes needs an additional check
2448 0 0       0 my $ck_next = ${$op->next} ? "PL_op != ($sym)->op_next && " : "";
  0         0  
2449 0         0 runtime("while ($ck_next PL_op != (OP*)0 ){",
2450             "\tPL_op = (*PL_op->op_ppaddr)(aTHX);",
2451             "\tSPAGAIN;}");
2452 0         0 $know_op = 0;
2453 0         0 invalidate_lexicals( REGISTER | TEMPORARY );
2454             # B::C::check_entersub($op);
2455 0         0 return $op->next;
2456             }
2457              
2458             # coverage: 16,26,35,51,72,73
2459             sub pp_bless {
2460 0     0 0 0 my $op = shift;
2461 0 0       0 $curcop->write_back if $curcop;
2462             # B::C::check_bless($op);
2463 0         0 default_pp($op);
2464             }
2465              
2466              
2467             # coverage: ny
2468             sub pp_formline {
2469 0     0 0 0 my $op = shift;
2470 0         0 my $ppname = "pp_" . $op->name;
2471 0 0       0 runtime(sprintf("/* %s */", $ppname)) if $verbose;
2472 0 0       0 write_back_lexicals() unless $skip_lexicals{$ppname};
2473 0 0       0 write_back_stack() unless $skip_stack{$ppname};
2474 0         0 my $sym = doop($op);
2475              
2476             # See comment in pp_grepwhile to see why!
2477 0         0 $init->add("((LISTOP*)$sym)->op_first = $sym;");
2478 0         0 runtime("if (PL_op == ((LISTOP*)($sym))->op_first) {");
2479 0         0 save_or_restore_lexical_state( ${ $op->first } );
  0         0  
2480 0         0 runtime( sprintf( "goto %s;", label( $op->first ) ),
2481             "}");
2482 0         0 return $op->next;
2483             }
2484              
2485             # coverage: 2,17,21,28,30
2486             sub pp_goto {
2487 0     0 0 0 my $op = shift;
2488 0         0 my $ppname = "pp_" . $op->name;
2489 0 0       0 runtime(sprintf("/* %s */", $ppname)) if $verbose;
2490 0 0       0 write_back_lexicals() unless $skip_lexicals{$ppname};
2491 0 0       0 write_back_stack() unless $skip_stack{$ppname};
2492 0         0 my $sym = doop($op);
2493 0         0 runtime("if (PL_op != ($sym)->op_next && PL_op != (OP*)0){return PL_op;}");
2494 0 0       0 invalidate_lexicals() unless $skip_invalidate{$ppname};
2495 0         0 return $op->next;
2496             }
2497              
2498             # coverage: 1-39, c_argv.t 2
2499             sub pp_enter {
2500             # XXX fails with simple c_argv.t 2. no cxix. Disabled for now
2501 0     0 0 0 if (0 and $inline_ops) {
2502             my $op = shift;
2503             runtime(sprintf("/* %s */", $op->name)) if $verbose;
2504             warn "inlining enter\n" if $debug{op};
2505             $curcop->write_back if $curcop;
2506             if (!($op->flags & OPf_WANT)) {
2507             my $cxix = $#cxstack;
2508             if ( $cxix >= 0 ) {
2509             if ( $op->flags & OPf_SPECIAL ) {
2510             runtime "gimme = block_gimme();";
2511             } else {
2512             runtime "gimme = cxstack[cxstack_ix].blk_gimme;";
2513             }
2514             } else {
2515             runtime "gimme = G_SCALAR;";
2516             }
2517             } else {
2518             runtime "gimme = OP_GIMME(PL_op, -1);";
2519             }
2520             runtime($] >= 5.011001 and $] < 5.011004
2521             ? 'ENTER_with_name("block");' : 'ENTER;',
2522             "SAVETMPS;",
2523             "PUSHBLOCK(cx, CXt_BLOCK, SP);");
2524             return $op->next;
2525             } else {
2526 0         0 return default_pp(@_);
2527             }
2528             }
2529              
2530             # coverage: ny
2531 0     0 0 0 sub pp_enterwrite { pp_entersub(@_) }
2532              
2533             # coverage: 6,8,9,10,24,26,27,31
2534             sub pp_leavesub {
2535 0     0 0 0 my $op = shift;
2536 0         0 my $ppname = "pp_" . $op->name;
2537 0 0       0 write_back_lexicals() unless $skip_lexicals{$ppname};
2538 0 0       0 write_back_stack() unless $skip_stack{$ppname};
2539 0         0 runtime("if (PL_curstackinfo->si_type == PERLSI_SORT){",
2540             "\tPUTBACK;return 0;",
2541             "}");
2542 0         0 doop($op);
2543 0         0 return $op->next;
2544             }
2545              
2546             # coverage: ny
2547             sub pp_leavewrite {
2548 0     0 0 0 my $op = shift;
2549 0         0 write_back_lexicals( REGISTER | TEMPORARY );
2550 0         0 write_back_stack();
2551 0         0 my $sym = doop($op);
2552              
2553             # XXX Is this the right way to distinguish between it returning
2554             # CvSTART(cv) (via doform) and pop_return()?
2555             #runtime("if (PL_op) PL_op = (*PL_op->op_ppaddr)(aTHX);");
2556 0         0 runtime("SPAGAIN;");
2557 0         0 $know_op = 0;
2558 0         0 invalidate_lexicals( REGISTER | TEMPORARY );
2559 0         0 return $op->next;
2560             }
2561              
2562             # coverage: ny
2563 0     0 0 0 sub pp_entergiven { pp_enterwrite(@_) }
2564             # coverage: ny
2565 0     0 0 0 sub pp_leavegiven { pp_leavewrite(@_) }
2566              
2567             sub doeval {
2568 0     0 0 0 my $op = shift;
2569 0         0 $curcop->write_back;
2570 0         0 write_back_lexicals( REGISTER | TEMPORARY );
2571 0         0 write_back_stack();
2572 0         0 my $sym = loadop($op);
2573 0         0 my $ppaddr = $op->ppaddr;
2574 0         0 runtime("PP_EVAL($ppaddr, ($sym)->op_next);");
2575 0         0 $know_op = 1;
2576 0         0 invalidate_lexicals( REGISTER | TEMPORARY );
2577 0         0 return $op->next;
2578             }
2579              
2580             # coverage: 12
2581 0     0 0 0 sub pp_entereval { doeval(@_) }
2582             # coverage: ny
2583 0     0 0 0 sub pp_dofile { doeval(@_) }
2584              
2585             # coverage: 28
2586             #pp_require is protected by pp_entertry, so no protection for it.
2587             sub pp_require {
2588 0     0 0 0 my $op = shift;
2589 0         0 $curcop->write_back;
2590 0         0 write_back_lexicals( REGISTER | TEMPORARY );
2591 0         0 write_back_stack();
2592 0         0 my $sym = doop($op);
2593             # sometimes needs an additional check
2594 0 0       0 my $ck_next = ${$op->next} ? "PL_op != ($sym)->op_next && " : "";
  0         0  
2595 0         0 runtime("while ($ck_next PL_op != (OP*)0 ) {", #(test 28).
2596             " PL_op = (*PL_op->op_ppaddr)(aTHX);",
2597             " SPAGAIN;",
2598             "}");
2599 0         0 $know_op = 1;
2600 0         0 invalidate_lexicals( REGISTER | TEMPORARY );
2601             # B::C::check_require($op); # mark package
2602 0         0 return $op->next;
2603             }
2604              
2605             # coverage: 32
2606             sub pp_entertry {
2607 0     0 0 0 my $op = shift;
2608 0         0 $curcop->write_back;
2609 0         0 write_back_lexicals( REGISTER | TEMPORARY );
2610 0         0 write_back_stack();
2611 0         0 my $sym = doop($op);
2612 0         0 $entertry_defined = 1;
2613 0         0 my $next = $op->next; # broken in 5.12, fixed in B::C by upgrading BASEOP
2614             # jump past leavetry
2615 0 0       0 $next = $op->other->next if $op->can("other"); # before 5.11.4 and after 5.13.8
2616 0         0 my $l = label( $next );
2617 0         0 debug "ENTERTRY label=$l (".ref($op).") ->".$next->name."(".ref($next).")\n";
2618 0         0 runtime(sprintf( "PP_ENTERTRY(%s);", $l));
2619 0 0       0 if ($next->isa('B::COP')) {
2620 0         0 push_label($next, 'nextstate');
2621             } else {
2622 0 0       0 push_label($op->other, 'leavetry') if $op->can("other");
2623             }
2624 0         0 invalidate_lexicals( REGISTER | TEMPORARY );
2625 0         0 return $op->next;
2626             }
2627              
2628             # coverage: 32
2629             sub pp_leavetry {
2630 0     0 0 0 my $op = shift;
2631 0 0 0     0 pop_label 'leavetry' if $labels->{'leavetry'}->[-1] and $labels->{'leavetry'}->[-1] == $op;
2632 0         0 default_pp($op);
2633 0         0 runtime("PP_LEAVETRY;");
2634 0         0 write_label($op->next);
2635 0         0 return $op->next;
2636             }
2637              
2638             # coverage: ny
2639             sub pp_grepstart {
2640 0     0 0 0 my $op = shift;
2641 0 0 0     0 if ( $need_freetmps && $freetmps_each_loop ) {
2642 0         0 runtime("FREETMPS;"); # otherwise the grepwhile loop messes things up
2643 0         0 $need_freetmps = 0;
2644             }
2645 0         0 write_back_stack();
2646 0         0 my $sym = doop($op);
2647 0         0 my $next = $op->next;
2648 0         0 $next->save;
2649 0         0 my $nexttonext = $next->next;
2650 0         0 $nexttonext->save;
2651 0         0 save_or_restore_lexical_state($$nexttonext);
2652 0         0 runtime(
2653             sprintf( "if (PL_op == (($sym)->op_next)->op_next) goto %s;",
2654             label($nexttonext) )
2655             );
2656 0         0 return $op->next->other;
2657             }
2658              
2659             # coverage: ny
2660             sub pp_mapstart {
2661 0     0 0 0 my $op = shift;
2662 0 0 0     0 if ( $need_freetmps && $freetmps_each_loop ) {
2663 0         0 runtime("FREETMPS;"); # otherwise the mapwhile loop messes things up
2664 0         0 $need_freetmps = 0;
2665             }
2666 0         0 write_back_stack();
2667              
2668             # pp_mapstart can return either op_next->op_next or op_next->op_other and
2669             # we need to be able to distinguish the two at runtime.
2670 0         0 my $sym = doop($op);
2671 0         0 my $next = $op->next;
2672 0         0 $next->save;
2673 0         0 my $nexttonext = $next->next;
2674 0         0 $nexttonext->save;
2675 0         0 save_or_restore_lexical_state($$nexttonext);
2676 0         0 runtime(
2677             sprintf( "if (PL_op == (($sym)->op_next)->op_next) goto %s;",
2678             label($nexttonext) )
2679             );
2680 0         0 return $op->next->other;
2681             }
2682              
2683             # coverage: ny
2684             sub pp_grepwhile {
2685 0     0 0 0 my $op = shift;
2686 0         0 my $next = $op->next;
2687 0         0 unshift( @bblock_todo, $next );
2688 0         0 write_back_lexicals();
2689 0         0 write_back_stack();
2690 0         0 my $sym = doop($op);
2691              
2692             # pp_grepwhile can return either op_next or op_other and we need to
2693             # be able to distinguish the two at runtime. Since it's possible for
2694             # both ops to be "inlined", the fields could both be zero. To get
2695             # around that, we hack op_next to be our own op (purely because we
2696             # know it's a non-NULL pointer and can't be the same as op_other).
2697 0         0 $init->add("((LOGOP*)$sym)->op_next = $sym;");
2698 0         0 save_or_restore_lexical_state($$next);
2699 0         0 runtime( sprintf( "if (PL_op == ($sym)->op_next) goto %s;", label($next) ) );
2700 0         0 $know_op = 0;
2701 0         0 return $op->other;
2702             }
2703              
2704             # coverage: ny
2705 0     0 0 0 sub pp_mapwhile { pp_grepwhile(@_) }
2706              
2707             # coverage: 24
2708             sub pp_return {
2709 0     0 0 0 my $op = shift;
2710 0         0 write_back_lexicals( REGISTER | TEMPORARY );
2711 0         0 write_back_stack();
2712 0         0 doop($op);
2713 0         0 runtime( "PUTBACK;", "return PL_op;" );
2714 0         0 $know_op = 0;
2715 0         0 return $op->next;
2716             }
2717              
2718             sub nyi {
2719 0     0 0 0 my $op = shift;
2720 0         0 warn sprintf( "Warning: %s not yet implemented properly\n", $op->ppaddr );
2721 0         0 return default_pp($op);
2722             }
2723              
2724             # coverage: 17
2725             sub pp_range {
2726 0     0 0 0 my $op = shift;
2727 0         0 my $flags = $op->flags;
2728 0 0       0 if ( !( $flags & OPf_WANT ) ) {
2729 0 0       0 if ($strict) {
2730 0         0 error("context of range unknown at compile-time\n");
2731             } else {
2732 0         0 warn("Warning: context of range unknown at compile-time\n");
2733 0         0 runtime('warn("context of range unknown at compile-time");');
2734             }
2735 0         0 return default_pp($op);
2736             }
2737 0         0 write_back_lexicals();
2738 0         0 write_back_stack();
2739 0 0       0 unless ( ( $flags & OPf_WANT ) == OPf_WANT_LIST ) {
2740             # We need to save our UNOP structure since pp_flop uses
2741             # it to find and adjust out targ. We don't need it ourselves.
2742 0         0 $op->save;
2743 0         0 save_or_restore_lexical_state( ${ $op->other } );
  0         0  
2744 0         0 runtime sprintf( "if (SvTRUE(PL_curpad[%d])) goto %s;",
2745             $op->targ, label( $op->other ) );
2746 0         0 unshift( @bblock_todo, $op->other );
2747             }
2748 0         0 return $op->next;
2749             }
2750              
2751             # coverage: 17, 30
2752             sub pp_flip {
2753 0     0 0 0 my $op = shift;
2754 0         0 my $flags = $op->flags;
2755 0 0       0 if ( !( $flags & OPf_WANT ) ) {
2756 0 0       0 if ($strict) {
2757 0         0 error("context of flip unknown at compile-time\n");
2758             } else {
2759 0         0 warn("Warning: context of flip unknown at compile-time\n");
2760 0         0 runtime('warn("context of flip unknown at compile-time");');
2761             }
2762 0         0 return default_pp($op);
2763             }
2764 0 0       0 if ( ( $flags & OPf_WANT ) == OPf_WANT_LIST ) {
2765 0         0 return $op->first->other;
2766             }
2767 0         0 write_back_lexicals();
2768 0         0 write_back_stack();
2769             # We need to save our UNOP structure since pp_flop uses
2770             # it to find and adjust out targ. We don't need it ourselves.
2771 0         0 $op->save;
2772 0         0 my $ix = $op->targ;
2773 0         0 my $rangeix = $op->first->targ;
2774 0 0       0 runtime(
2775             ( $op->private & OPpFLIP_LINENUM )
2776             ? "if (PL_last_in_gv && SvIV(TOPs) == IoLINES(GvIOp(PL_last_in_gv))) {"
2777             : "if (SvTRUE(TOPs)) {"
2778             );
2779 0         0 runtime("\tsv_setiv(PL_curpad[$rangeix], 1);");
2780 0 0       0 if ( $op->flags & OPf_SPECIAL ) {
2781 0         0 runtime("sv_setiv(PL_curpad[$ix], 1);");
2782             }
2783             else {
2784 0         0 save_or_restore_lexical_state( ${ $op->first->other } );
  0         0  
2785 0         0 runtime( "\tsv_setiv(PL_curpad[$ix], 0);",
2786             "\tsp--;", sprintf( "\tgoto %s;", label( $op->first->other ) ) );
2787             }
2788 0         0 runtime( "}", qq{sv_setpv(PL_curpad[$ix], "");}, "SETs(PL_curpad[$ix]);" );
2789 0         0 $know_op = 0;
2790 0         0 return $op->next;
2791             }
2792              
2793             # coverage: 17
2794             sub pp_flop {
2795 0     0 0 0 my $op = shift;
2796 0         0 default_pp($op);
2797 0         0 $know_op = 0;
2798 0         0 return $op->next;
2799             }
2800              
2801             sub enterloop {
2802 0     0 0 0 my $op = shift;
2803 0         0 my $nextop = $op->nextop;
2804 0         0 my $lastop = $op->lastop;
2805 0         0 my $redoop = $op->redoop;
2806 0 0       0 $curcop->write_back if $curcop;
2807 0 0       0 debug "enterloop: pushing on cxstack\n" if $debug{cxstack};
2808 0 0       0 push(
2809             @cxstack,
2810             {
2811             type => $PERL512 ? CXt_LOOP_PLAIN : CXt_LOOP,
2812             op => $op,
2813             "label" => $curcop->[0]->label,
2814             nextop => $nextop,
2815             lastop => $lastop,
2816             redoop => $redoop
2817             }
2818             );
2819 0 0       0 debug sprintf("enterloop: cxstack label %s\n", $curcop->[0]->label) if $debug{cxstack};
2820 0         0 $nextop->save;
2821 0         0 $lastop->save;
2822 0         0 $redoop->save;
2823             # We need to compile the corresponding pp_leaveloop even if it's
2824             # never executed. This is needed to get @cxstack right.
2825             # Use case: while(1) { .. }
2826 0         0 unshift @bblock_todo, ($lastop);
2827 0         0 if (0 and $inline_ops and $op->name eq 'enterloop') {
2828             warn "inlining enterloop\n" if $debug{op};
2829             # XXX = GIMME_V fails on freebsd7 5.8.8 (28)
2830             # = block_gimme() fails on the rest, but passes on freebsd7
2831             runtime "gimme = GIMME_V;"; # XXX
2832             if ($PERL512) {
2833             runtime('ENTER_with_name("loop1");',
2834             'SAVETMPS;',
2835             'ENTER_with_name("loop2");',
2836             'PUSHBLOCK(cx, CXt_LOOP_PLAIN, SP);',
2837             'PUSHLOOP_PLAIN(cx, SP);');
2838             } else {
2839             runtime('ENTER;',
2840             'SAVETMPS;',
2841             'ENTER;',
2842             'PUSHBLOCK(cx, CXt_LOOP, SP);',
2843             'PUSHLOOP(cx, 0, SP);');
2844             }
2845             return $op->next;
2846             } else {
2847 0         0 return default_pp($op);
2848             }
2849             }
2850              
2851             # coverage: 6,21,28,30
2852 0     0 0 0 sub pp_enterloop { enterloop(@_) }
2853             # coverage: 2
2854 0     0 0 0 sub pp_enteriter { enterloop(@_) }
2855              
2856             # coverage: 6,21,28,30
2857             sub pp_leaveloop {
2858 0     0 0 0 my $op = shift;
2859 0 0       0 if ( !@cxstack ) {
2860 0         0 die "panic: leaveloop, no cxstack";
2861             }
2862 0 0       0 debug "leaveloop: popping from cxstack\n" if $debug{cxstack};
2863 0         0 pop(@cxstack);
2864 0         0 return default_pp($op);
2865             }
2866              
2867             # coverage: ?
2868             sub pp_next {
2869 0     0 0 0 my $op = shift;
2870 0         0 my $cxix;
2871 0 0       0 if ( $op->flags & OPf_SPECIAL ) {
2872 0         0 $cxix = dopoptoloop();
2873 0 0       0 if ( $cxix < 0 ) {
2874 0         0 warn "Warning: \"next\" used outside loop\n";
2875 0         0 return default_pp($op); # no optimization
2876             }
2877             }
2878             else {
2879 0         0 my $label = $op->pv;
2880 0 0       0 if ($label) {
2881 0         0 $cxix = dopoptolabel( $label );
2882 0 0       0 if ( $cxix < 0 ) {
2883             # coverage: t/testcc 21
2884 0         0 warn(sprintf("Warning: Label not found at compile time for \"next %s\"\n", $label ));
2885 0         0 $labels->{nlabel}->{$label} = $$op;
2886 0         0 return $op->next;
2887             }
2888             }
2889             # Add support to leave non-loop blocks.
2890 0 0       0 if ( CxTYPE_no_LOOP( $cxstack[$cxix] ) ) {
2891 0 0 0     0 if (!$cxstack[$cxix]->{'nextop'} or !$cxstack[$cxix]->{'label'}) {
2892 0         0 error("Use of \"next\" for non-loop and non-label blocks not yet implemented\n");
2893             }
2894             }
2895             }
2896 0         0 default_pp($op);
2897 0         0 my $nextop = $cxstack[$cxix]->{nextop};
2898 0 0       0 if ($nextop) {
2899 0         0 push( @bblock_todo, $nextop );
2900 0         0 save_or_restore_lexical_state($$nextop);
2901 0         0 runtime( sprintf( "goto %s;", label($nextop) ) );
2902             }
2903 0         0 return $op->next;
2904             }
2905              
2906             # coverage: ?
2907             sub pp_redo {
2908 0     0 0 0 my $op = shift;
2909 0         0 my $cxix;
2910 0 0       0 if ( $op->flags & OPf_SPECIAL ) {
2911 0         0 $cxix = dopoptoloop();
2912 0 0       0 if ( $cxix < 0 ) {
2913             #warn("Warning: \"redo\" used outside loop\n");
2914 0         0 return default_pp($op); # no optimization
2915             }
2916             }
2917             else {
2918 0         0 my $label = $op->pv;
2919 0 0       0 if ($label) {
2920 0         0 $cxix = dopoptolabel( $label );
2921 0 0       0 if ( $cxix < 0 ) {
2922 0         0 warn(sprintf("Warning: Label not found at compile time for \"redo %s\"\n", $label ));
2923 0         0 $labels->{nlabel}->{$label} = $$op;
2924 0         0 return $op->next;
2925             }
2926             }
2927             # Add support to leave non-loop blocks.
2928 0 0       0 if ( CxTYPE_no_LOOP( $cxstack[$cxix] ) ) {
2929 0 0 0     0 if (!$cxstack[$cxix]->{'redoop'} or !$cxstack[$cxix]->{'label'}) {
2930 0         0 error("Use of \"redo\" for non-loop and non-label blocks not yet implemented\n");
2931             }
2932             }
2933             }
2934 0         0 default_pp($op);
2935 0         0 my $redoop = $cxstack[$cxix]->{redoop};
2936 0 0       0 if ($redoop) {
2937 0         0 push( @bblock_todo, $redoop );
2938 0         0 save_or_restore_lexical_state($$redoop);
2939 0         0 runtime( sprintf( "goto %s;", label($redoop) ) );
2940             }
2941 0         0 return $op->next;
2942             }
2943              
2944             # coverage: issue36, cc_last.t
2945             sub pp_last {
2946 0     0 0 0 my $op = shift;
2947 0         0 my $cxix;
2948 0 0       0 if ( $op->flags & OPf_SPECIAL ) {
    0          
2949 0         0 $cxix = dopoptoloop();
2950 0 0       0 if ( $cxix < 0 ) {
2951             #warn("Warning: \"last\" used outside loop\n");
2952 0         0 return default_pp($op); # no optimization
2953             }
2954             }
2955             elsif (ref($op) eq 'B::PVOP') { # !OPf_STACKED
2956 0         0 my $label = $op->pv;
2957 0 0       0 if ($label) {
2958 0         0 $cxix = dopoptolabel( $label );
2959 0 0       0 if ( $cxix < 0 ) {
2960             # coverage: cc_last.t 2 (ok) 4 (ok)
2961 0         0 warn( sprintf("Warning: Label not found at compile time for \"last %s\"\n", $label ));
2962             # last does not jump into the future, by name without $$op
2963             # instead it should jump to the block afterwards
2964 0         0 $labels->{nlabel}->{$label} = $$op;
2965 0         0 return $op->next;
2966             }
2967             }
2968             # Add support to leave non-loop blocks. label fixed with 1.11
2969 0 0       0 if ( CxTYPE_no_LOOP( $cxstack[$cxix] ) ) {
2970 0 0 0     0 if (!$cxstack[$cxix]->{'lastop'} or !$cxstack[$cxix]->{'label'}) {
2971 0         0 error("Use of \"last\" for non-loop and non-label blocks not yet implemented\n");
2972             }
2973             }
2974             }
2975 0         0 default_pp($op);
2976 0 0 0     0 if ($cxstack[$cxix]->{lastop} and $cxstack[$cxix]->{lastop}->next) {
2977 0         0 my $lastop = $cxstack[$cxix]->{lastop}->next;
2978 0         0 push( @bblock_todo, $lastop );
2979 0         0 save_or_restore_lexical_state($$lastop);
2980 0         0 runtime( sprintf( "goto %s;", label($lastop) ) );
2981             }
2982 0         0 return $op->next;
2983             }
2984              
2985             # coverage: 3,4
2986             sub pp_subst {
2987 0     0 0 0 my $op = shift;
2988 0         0 write_back_lexicals();
2989 0         0 write_back_stack();
2990 0         0 my $sym = doop($op);
2991 0         0 my $replroot = $op->pmreplroot;
2992 0 0       0 if ($$replroot) {
2993 0         0 save_or_restore_lexical_state($$replroot);
2994 0 0       0 runtime sprintf(
2995             "if (PL_op == ((PMOP*)(%s))%s) goto %s;",
2996             $sym, $PERL510 ? "->op_pmreplrootu.op_pmreplroot" : "->op_pmreplroot",
2997             label($replroot)
2998             );
2999 0         0 $op->pmreplstart->save;
3000 0         0 push( @bblock_todo, $replroot );
3001             }
3002 0         0 invalidate_lexicals();
3003 0         0 return $op->next;
3004             }
3005              
3006             # coverage: 3
3007             sub pp_substcont {
3008 0     0 0 0 my $op = shift;
3009 0         0 write_back_lexicals();
3010 0         0 write_back_stack();
3011 0         0 doop($op);
3012 0         0 my $pmop = $op->other;
3013             #warn sprintf( "substcont: op = %s, pmop = %s\n", peekop($op), peekop($pmop) ) if $verbose;
3014              
3015             # my $pmopsym = objsym($pmop);
3016 0         0 my $pmopsym = $pmop->save; # XXX can this recurse?
3017             # warn "pmopsym = $pmopsym\n" if $verbose;
3018 0         0 save_or_restore_lexical_state( ${ $pmop->pmreplstart } );
  0         0  
3019 0 0       0 runtime sprintf(
3020             "if (PL_op == ((PMOP*)(%s))%s) goto %s;",
3021             $pmopsym,
3022             $PERL510 ? "->op_pmstashstartu.op_pmreplstart" : "->op_pmreplstart",
3023             label( $pmop->pmreplstart )
3024             );
3025 0         0 push( @bblock_todo, $pmop->pmreplstart );
3026 0         0 invalidate_lexicals();
3027 0         0 return $pmop->next;
3028             }
3029              
3030             # coverage: issue24
3031             # resolve the DBM library at compile-time, not at run-time
3032             sub pp_dbmopen {
3033 0     0 0 0 my $op = shift;
3034 0         0 require AnyDBM_File;
3035 0         0 my $dbm = $AnyDBM_File::ISA[0];
3036 0         0 svref_2object( \&{"$dbm\::bootstrap"} )->save;
  0         0  
3037 0         0 return default_pp($op);
3038             }
3039              
3040             sub default_pp {
3041 0     0 0 0 my $op = shift;
3042 0         0 my $ppname = "pp_" . $op->name;
3043             # runtime(sprintf("/* %s */", $ppname)) if $verbose;
3044 0 0 0     0 if ( $curcop and $need_curcop{$ppname} ) {
3045 0         0 $curcop->write_back;
3046             }
3047 0 0       0 write_back_lexicals() unless $skip_lexicals{$ppname};
3048 0 0       0 write_back_stack() unless $skip_stack{$ppname};
3049 0         0 doop($op);
3050              
3051             # XXX If the only way that ops can write to a TEMPORARY lexical is
3052             # when it's named in $op->targ then we could call
3053             # invalidate_lexicals(TEMPORARY) and avoid having to write back all
3054             # the temporaries. For now, we'll play it safe and write back the lot.
3055 0 0       0 invalidate_lexicals() unless $skip_invalidate{$ppname};
3056 0         0 return $op->next;
3057             }
3058              
3059             sub compile_op {
3060 0     0 0 0 my $op = shift;
3061 0         0 my $ppname = "pp_" . $op->name;
3062 0 0       0 if ( exists $ignore_op{$ppname} ) {
3063 0         0 return $op->next;
3064             }
3065 0 0       0 debug peek_stack() if $debug{stack};
3066 0 0       0 if ( $debug{op} ) {
3067 0 0       0 debug sprintf( "%s [%s]\n",
3068             peekop($op), $op->flags & OPf_STACKED ? "OPf_STACKED" : $op->targ );
3069             }
3070 14     14   129 no strict 'refs';
  14         18  
  14         28227  
3071 0 0       0 if ( defined(&$ppname) ) {
3072 0         0 $know_op = 0;
3073 0         0 return &$ppname($op);
3074             }
3075             else {
3076 0         0 return default_pp($op);
3077             }
3078             }
3079              
3080             sub compile_bblock {
3081 0     0 0 0 my $op = shift;
3082 0 0       0 warn "compile_bblock: ", peekop($op), "\n" if $debug{bblock};
3083 0         0 save_or_restore_lexical_state($$op);
3084 0         0 write_label($op);
3085 0         0 $know_op = 0;
3086             do {
3087 0         0 $op = compile_op($op);
3088 0 0 0     0 if ($] < 5.013 and ($opt_slow_signals or ($$op and $async_signals{$op->name}))) {
      0        
3089 0         0 runtime("PERL_ASYNC_CHECK();");
3090             }
3091 0   0     0 } while ( defined($op) && $$op && !exists( $leaders->{$$op} ) );
      0        
3092 0         0 write_back_stack(); # boo hoo: big loss
3093 0         0 reload_lexicals();
3094 0         0 return $op;
3095             }
3096              
3097             sub cc {
3098 0     0 0 0 my ( $name, $root, $start, @padlist ) = @_;
3099 0         0 my $op;
3100 0 0       0 if ( $done{$$start} ) {
3101 0 0       0 warn "repeat=>" . ref($start) . " $name,\n" if $verbose;
3102 0         0 $decl->add( sprintf( "#define $name %s", $done{$$start} ) );
3103 0         0 return;
3104             }
3105 0 0 0     0 return if ref($padlist[0]) !~ /^B::(AV|PADNAMELIST)$/ or ref($padlist[1]) ne 'B::AV';
3106 0 0       0 warn "cc $name\n" if $verbose;
3107 0         0 init_pp($name);
3108 0         0 load_pad(@padlist);
3109 0         0 %lexstate = ();
3110 0         0 B::Pseudoreg->new_scope;
3111 0         0 @cxstack = ();
3112 0 0       0 if ( $debug{timings} ) {
3113 0         0 warn sprintf( "Basic block analysis at %s\n", timing_info );
3114             }
3115 0         0 $leaders = find_leaders( $root, $start );
3116 0         0 my @leaders = keys %$leaders;
3117 0 0       0 if ( $#leaders > -1 ) {
3118             # Don't add basic blocks of dead code.
3119             # It would produce errors when processing $cxstack.
3120             # @bblock_todo = ( values %$leaders );
3121             # Instead, save $root (pp_leavesub) separately,
3122             # because it will not get compiled if located in dead code.
3123 0         0 $root->save;
3124 0 0       0 unshift @bblock_todo, ($start) if $$start;
3125             }
3126             else {
3127 0         0 runtime("return PL_op?PL_op->op_next:0;");
3128             }
3129 0 0       0 if ( $debug{timings} ) {
3130 0         0 warn sprintf( "Compilation at %s\n", timing_info );
3131             }
3132 0         0 while (@bblock_todo) {
3133 0         0 $op = shift @bblock_todo;
3134 0 0       0 warn sprintf( "Considering basic block %s\n", peekop($op) ) if $debug{bblock};
3135 0 0 0     0 next if !defined($op) || !$$op || $done{$$op};
      0        
3136 0 0       0 warn "...compiling it\n" if $debug{bblock};
3137             do {
3138 0         0 $done{$$op} = $name;
3139 0         0 $op = compile_bblock($op);
3140 0 0 0     0 if ( $need_freetmps && $freetmps_each_bblock ) {
3141 0         0 runtime("FREETMPS;");
3142 0         0 $need_freetmps = 0;
3143             }
3144 0   0     0 } while defined($op) && $$op && !$done{$$op};
      0        
3145 0 0 0     0 if ( $need_freetmps && $freetmps_each_loop ) {
3146 0         0 runtime("FREETMPS;");
3147 0         0 $need_freetmps = 0;
3148             }
3149 0 0       0 if ( !$$op ) {
    0          
3150 0         0 runtime( "PUTBACK;",
3151             "return NULL;" );
3152             }
3153             elsif ( $done{$$op} ) {
3154 0         0 save_or_restore_lexical_state($$op);
3155 0         0 runtime( sprintf( "goto %s;", label($op) ) );
3156             }
3157             }
3158 0 0       0 if ( $debug{timings} ) {
3159 0         0 warn sprintf( "Saving runtime at %s\n", timing_info );
3160             }
3161 0         0 declare_pad(@padlist);
3162 0         0 save_runtime();
3163             }
3164              
3165             sub cc_recurse {
3166 0     0 0 0 my ($ccinfo);
3167 0 0       0 my $start = cc_queue(@_) if @_;
3168              
3169 0         0 while ( $ccinfo = shift @cc_todo ) {
3170 0 0       0 if ($ccinfo->[0] eq 'pp_sub_warnings__register_categories') {
3171             # patch broken PADLIST
3172             #warn "cc $ccinfo->[0] patch broken PADLIST (inc-i340)\n" if $verbose;
3173             #debug "cc(ccinfo): @$ccinfo skipped (inc-i340)\n" if $debug{queue};
3174             #$ccinfo->[0] = 'NULL';
3175 0         0 my @empty = ();
3176             #$ccinfo->[3] = $ccinfo->[4] = svref_2object(\@empty);
3177             }
3178 0 0 0     0 if ($DB::deep and $ccinfo->[0] =~ /^pp_sub_(DB|Term__ReadLine)_/) {
    0          
3179 0 0       0 warn "cc $ccinfo->[0] skipped (debugging)\n" if $verbose;
3180 0 0       0 debug "cc(ccinfo): @$ccinfo skipped (debugging)\n" if $debug{queue};
3181             }
3182             elsif (exists $cc_pp_sub{$ccinfo->[0]}) { # skip duplicates
3183 0 0       0 warn "cc $ccinfo->[0] already defined\n" if $verbose;
3184 0 0       0 debug "cc(ccinfo): @$ccinfo already defined\n" if $debug{queue};
3185 0         0 while (exists $cc_pp_sub{$ccinfo->[0]}) {
3186 0 0       0 if ($ccinfo->[0] =~ /^(pp_(?:lex)?sub_.*_)(\d*)$/) {
3187 0         0 my $s = $2;
3188 0         0 $s++;
3189 0         0 $ccinfo->[0] = $1 . $s;
3190             } else {
3191 0         0 $ccinfo->[0] .= '_0';
3192             }
3193             }
3194 0 0       0 warn "cc renamed to $ccinfo->[0]\n" if $verbose;
3195 0         0 cc(@$ccinfo);
3196 0         0 $cc_pp_sub{$ccinfo->[0]}++;
3197             } else {
3198 0 0       0 debug "cc(ccinfo): @$ccinfo\n" if $debug{queue};
3199 0         0 cc(@$ccinfo);
3200 0         0 $cc_pp_sub{$ccinfo->[0]}++;
3201             }
3202             }
3203 0         0 return $start;
3204             }
3205              
3206             sub cc_obj {
3207 0     0 0 0 my ( $name, $cvref ) = @_;
3208 0         0 my $cv = svref_2object($cvref);
3209 0         0 my @padlist = $cv->PADLIST->ARRAY;
3210 0         0 my $curpad_sym = $padlist[1]->save;
3211 0         0 set_curcv $cv;
3212 0         0 cc_recurse( $name, $cv->ROOT, $cv->START, @padlist );
3213             }
3214              
3215             sub cc_main {
3216 0     0 0 0 my @comppadlist = comppadlist->ARRAY;
3217 0         0 my $curpad_nam = $comppadlist[0]->save('curpad_name');
3218 0         0 my $curpad_sym = $comppadlist[1]->save('curpad_syms');;
3219 0         0 my $init_av = init_av->save('INIT');
3220 0         0 set_curcv B::main_cv;
3221 0         0 my $start = cc_recurse( "pp_main", main_root, main_start, @comppadlist );
3222              
3223             # Do save_unused_subs before saving inc_hv
3224 0 0       0 B::C::module($module) if $module;
3225 0         0 save_unused_subs();
3226              
3227 0         0 my $warner = $SIG{__WARN__};
3228 0         0 save_sig($warner);
3229              
3230 0         0 my($inc_hv, $inc_av, $end_av);
3231 0 0       0 if ( !defined($module) ) {
3232             # forbid run-time extends of curpad syms, names and INC
3233 0 0       0 warn "save context:\n" if $verbose;
3234 0         0 $init->add("/* save context */");
3235 0         0 $init->add('/* %INC */');
3236 0         0 inc_cleanup();
3237 0         0 my $inc_gv = svref_2object( \*main::INC );
3238 0         0 $inc_hv = $inc_gv->HV->save('main::INC');
3239 0         0 $init->add( sprintf( "GvHV(%s) = s\\_%x;",
3240             $inc_gv->save('main::INC'), $inc_gv->HV ) );
3241 0         0 local ($B::C::const_strings);
3242 0 0       0 $B::C::const_strings = 1 if $B::C::ro_inc;
3243 0         0 $inc_hv = $inc_gv->HV->save('main::INC');
3244 0         0 $inc_av = $inc_gv->AV->save('main::INC');
3245             }
3246             {
3247             # >=5.10 needs to defer nullifying of all vars in END, not only new ones.
3248 0         0 local ($B::C::const_strings);
  0         0  
3249 0         0 $B::C::in_endav = 1;
3250 0         0 $end_av = end_av->save('END');
3251             }
3252 0         0 cc_recurse();
3253 0 0 0     0 return if $errors or $check;
3254              
3255 0 0       0 if ( !defined($module) ) {
3256             # XXX TODO push BEGIN/END blocks to modules code.
3257             $init->add(
3258 0         0 sprintf( "PL_main_root = s\\_%x;", ${ main_root() } ),
  0         0  
3259             "PL_main_start = $start;",
3260             "PL_curpad = AvARRAY($curpad_sym);",
3261             "PL_comppad = $curpad_sym;");
3262 0 0       0 if ($] < 5.017005) {
3263 0         0 $init->add(
3264             "av_store((AV*)CvPADLIST(PL_main_cv), 0, SvREFCNT_inc($curpad_nam)); /* namepad */",
3265             "av_store((AV*)CvPADLIST(PL_main_cv), 1, SvREFCNT_inc($curpad_sym)); /* curpad */");
3266             } else {
3267 0         0 $init->add(
3268             "PadlistARRAY(CvPADLIST(PL_main_cv))[0] = (PAD*)SvREFCNT_inc($curpad_nam); /* namepad */",
3269             "PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)SvREFCNT_inc($curpad_sym); /* curpad */");
3270             }
3271 0         0 $init->add(
3272             "GvHV(PL_incgv) = $inc_hv;",
3273             "GvAV(PL_incgv) = $inc_av;",
3274             "PL_initav = (AV*)$init_av;",
3275             "PL_endav = (AV*)$end_av;");
3276 0 0       0 if ($] < 5.017) {
3277 0         0 my $amagic_generate = B::amagic_generation;
3278 0         0 $init->add("PL_amagic_generation = $amagic_generate;");
3279             };
3280             }
3281              
3282 0         0 seek( STDOUT, 0, 0 ); #prevent print statements from BEGIN{} into the output
3283 0         0 fixup_ppaddr();
3284 0         0 print "/* using B::CC $B::CC::VERSION backend */\n";
3285 0         0 output_boilerplate();
3286 0         0 print "\n";
3287 0         0 output_all("perl_init");
3288 0         0 output_runtime();
3289 0         0 print "\n";
3290 0         0 output_main_rest();
3291              
3292 0 0       0 if ( defined($module) ) {
3293 0   0     0 my $cmodule = $module ||= 'main';
3294 0         0 $cmodule =~ s/::/__/g;
3295 0         0 print <<"EOT";
3296              
3297             #include "XSUB.h"
3298             XS(boot_$cmodule)
3299             {
3300             dXSARGS;
3301             perl_init();
3302             ENTER;
3303             SAVETMPS;
3304             SAVEVPTR(PL_curpad);
3305             SAVEVPTR(PL_op);
3306             PL_curpad = AvARRAY($curpad_sym);
3307             PL_op = $start;
3308             pp_main(aTHX);
3309             FREETMPS;
3310             LEAVE;
3311             ST(0) = &PL_sv_yes;
3312             XSRETURN(1);
3313             }
3314             EOT
3315             } else {
3316 0         0 output_main();
3317             }
3318 0 0       0 if ( $debug{timings} ) {
3319 0         0 warn sprintf( "Done at %s\n", timing_info );
3320             }
3321             }
3322              
3323             sub compile_stats {
3324 0     0 0 0 my $s = "Total number of OPs processed: $op_count\n";
3325 0 0       0 $s .= "Total number of unresolved symbols: $B::C::unresolved_count\n"
3326             if $B::C::unresolved_count;
3327 0         0 return $s;
3328             }
3329              
3330             # Accessible via use B::CC '-ftype-attr'; in user code, or -MB::CC=-O2 on the cmdline
3331             sub import {
3332 15     15   29675 my @options = @_;
3333             # Allow debugging in CHECK blocks without Od
3334 15 50       54 $DB::single = 1 if defined &DB::DB;
3335 15         19 my ( $option, $opt, $arg );
3336             # init with -O0
3337 15         47 foreach my $ref ( values %optimise ) {
3338 165         129 $$ref = 0;
3339             }
3340 15 50       50 $B::C::fold = 0 if $] >= 5.013009; # utf8::Cased tables
3341 15 50       39 $B::C::warnings = 0 if $] >= 5.013005; # Carp warnings categories and B
3342 15 50       39 $B::C::destruct = 0 unless $] < 5.008; # fast_destruct
3343 15         18 $opt_taint = 1;
3344 15         15 $opt_magic = 1; # only makes sense with -fno-magic
3345 15         17 $opt_autovivify = 1; # only makes sense with -fno-autovivify
3346             OPTION:
3347 15         43 while ( $option = shift @options ) {
3348 15 50       51 if ( $option =~ /^-(.)(.*)/ ) {
3349 0         0 $opt = $1;
3350 0         0 $arg = $2;
3351             }
3352             else {
3353 15         23 unshift @options, $option;
3354 15         38 last OPTION;
3355             }
3356 0 0 0     0 if ( $opt eq "-" && $arg eq "-" ) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3357 0         0 shift @options;
3358 0         0 last OPTION;
3359             }
3360             elsif ( $opt eq "o" ) {
3361 0   0     0 $arg ||= shift @options;
3362 0 0       0 open( STDOUT, ">$arg" ) or return "open '>$arg': $!\n";
3363             }
3364             elsif ( $opt eq "c" ) {
3365 0         0 $check = 1;
3366 0         0 $B::C::check = 1;
3367             }
3368             elsif ( $opt eq "v" ) {
3369 0         0 $verbose = 1;
3370 0         0 B::C::verbose(1); # crashed in C _save_common_middle(B::FAKEOP)
3371             }
3372             elsif ( $opt eq "u" ) {
3373 0   0     0 $arg ||= shift @options;
3374 0         0 eval "require $arg;";
3375 0         0 mark_unused( $arg, 1 );
3376             }
3377             elsif ( $opt eq "U" ) {
3378 0   0     0 $arg ||= shift @options;
3379 0         0 mark_skip( $arg );
3380             }
3381             elsif ( $opt eq "strict" ) {
3382 0   0     0 $arg ||= shift @options;
3383 0         0 $strict++;
3384             }
3385             elsif ( $opt eq "f" ) {
3386 0   0     0 $arg ||= shift @options;
3387 0         0 my $value = $arg !~ s/^no-//;
3388 0         0 $arg =~ s/-/_/g;
3389 0         0 my $ref = $optimise{$arg};
3390 0 0       0 if ( defined($ref) ) {
3391 0         0 $$ref = $value;
3392             }
3393             else {
3394             # Pass down to B::C
3395 0         0 my $ref = $B::C::option_map{$arg};
3396 0 0       0 if ( defined($ref) ) {
3397 0         0 $$ref = $value;
3398 0         0 $c_optimise{$ref}++;
3399             }
3400             else {
3401 0         0 warn qq(Warning: ignoring unknown optimisation "$arg"\n);
3402             }
3403             }
3404             }
3405             elsif ( $opt eq "O" ) {
3406 0 0       0 $arg = 1 if $arg eq "";
3407 0         0 foreach my $ref ( values %optimise ) {
3408 0         0 $$ref = 0;
3409             }
3410 0 0       0 if ($arg >= 2) {
3411 0         0 $freetmps_each_loop = 1;
3412 0 0       0 if (!$ITHREADS) {
3413             #warn qq(Warning: ignoring -faelem with threaded perl\n);
3414 0         0 $opt_aelem = 1; # unstable, test: 68 pp_padhv targ assert
3415             }
3416             }
3417 0 0       0 if ( $arg >= 1 ) {
3418 0         0 $opt_type_attr = 1;
3419 0 0       0 $freetmps_each_bblock = 1 unless $freetmps_each_loop;
3420             }
3421             }
3422             elsif ( $opt eq "n" ) {
3423 0   0     0 $arg ||= shift @options;
3424 0         0 $init_name = $arg;
3425             }
3426             elsif ( $opt eq "m" ) {
3427 0         0 $module = $arg;
3428 0         0 mark_unused( $arg, undef );
3429             }
3430             #elsif ( $opt eq "p" ) {
3431             # $arg ||= shift @options;
3432             # $patchlevel = $arg;
3433             #}
3434             elsif ( $opt eq "D" ) {
3435 0   0     0 $arg ||= shift @options;
3436 0         0 $verbose++;
3437             # note that we should not clash too much with the B::C debug map
3438             # because we set theirs also
3439 0         0 my %debug_map = (O => 'op',
3440             T => 'stack', # was S
3441             c => 'cxstack',
3442             a => 'pad', # was p
3443             r => 'runtime',
3444             w => 'shadow', # was s
3445             q => 'queue',
3446             l => 'lineno',
3447             t => 'timings',
3448             b => 'bblock');
3449 0 0       0 $arg = join('',keys %debug_map).'Fsp' if $arg eq 'full';
3450 0         0 foreach $arg ( split( //, $arg ) ) {
3451 0 0 0     0 if ( $arg eq "o" ) {
    0          
    0          
    0          
3452 0         0 B->debug(1);
3453             }
3454             elsif ( $debug_map{$arg} ) {
3455 0         0 $debug{ $debug_map{$arg} }++;
3456             }
3457             elsif ( $arg eq "F" and eval "require B::Flags;" ) {
3458 0         0 $debug{flags}++;
3459 0         0 $B::C::debug{flags}++;
3460             }
3461             elsif ( exists $B::C::debug_map{$arg} ) {
3462 0         0 $B::C::verbose++;
3463 0         0 $B::C::debug{ $B::C::debug_map{$arg} }++;
3464             }
3465             else {
3466 0         0 warn qq(Warning: ignoring unknown -D option "$arg"\n);
3467             }
3468             }
3469             }
3470             }
3471 15 50 66     87 $strict++ if !$strict and $Config{ccflags} !~ m/-DDEBUGGING/;
3472 15 50       34 if ($opt_omit_taint) {
3473 0         0 $opt_taint = 0;
3474 0         0 warn "Warning: -fomit_taint is deprecated. Use -fno-taint instead.\n";
3475             }
3476              
3477             # rgs didn't want opcodes to be added to Opcode. So I had to add it to a
3478             # seperate Opcodes package.
3479 15         34 eval { require Opcodes; };
  15         6865  
3480 15 50 33     26981 if (!$@ and $Opcodes::VERSION) {
3481 15         37 my $MAXO = Opcodes::opcodes();
3482 15         53 for (0..$MAXO-1) {
3483 14     14   77 no strict 'refs';
  14         25  
  14         1545  
3484 5940         1200269 my $ppname = "pp_".Opcodes::opname($_);
3485             # opflags n: no args, no return values. don't need save/restore stack
3486             # But pp_enter, pp_leave use/change global stack.
3487 5940 100 100     24407 next if $ppname eq 'pp_enter' || $ppname eq 'pp_leave';
3488 5910 100       7144 $no_stack{$ppname} = 1
3489             if Opcodes::opflags($_) & 512;
3490             # XXX More Opcodes options to be added later
3491             }
3492             }
3493             #if ($debug{op}) {
3494             # warn "no_stack: ",join(" ",sort keys %no_stack),"\n";
3495             #}
3496              
3497 15         428 mark_skip(qw(B::C B::C::Config B::CC B::Asmdata B::FAKEOP
3498             B::Pseudoreg B::Shadow B::C::InitSection
3499             O B::Stackobj B::Stackobj::Bool B::Stackobj::Padsv
3500             B::Stackobj::Const B::Stackobj::Aelem B::Bblock));
3501 15         209 $B::C::all_bc_deps{$_}++ for qw(Opcodes Opcode B::Concise attributes double int num str string subs);
3502 15 50       79 mark_skip(qw(DB Term::ReadLine)) if defined &DB::DB;
3503              
3504             # Set some B::C optimizations.
3505             # optimize_ppaddr is not needed with B::CC as CC does it even better.
3506 15         36 for (qw(optimize_warn_sv save_data_fh av_init save_sig destruct const_strings)) {
3507 14     14   56 no strict 'refs';
  14         19  
  14         6842  
3508 90 50       145 ${"B::C::$_"} = 1 unless $c_optimise{$_};
  90         277  
3509             }
3510 15 50 33     202 $B::C::destruct = 0 unless $c_optimise{destruct} and $] > 5.008;
3511 15 50       62 $B::C::stash = 0 unless $c_optimise{stash};
3512 15 50       62 if (!$B::C::Config::have_independent_comalloc) {
3513 15 50       52 $B::C::av_init = 1 unless $c_optimise{av_init};
3514 15 50       61 $B::C::av_init2 = 0 unless $c_optimise{av_init2};
3515             } else {
3516 0 0       0 $B::C::av_init = 0 unless $c_optimise{av_init};
3517 0 0       0 $B::C::av_init2 = 1 unless $c_optimise{av_init2};
3518             }
3519 15 50       54 init_type_attrs() if $opt_type_attr; # but too late for -MB::CC=-O2 on import. attrs are checked before
3520 15         22726 @options;
3521             }
3522              
3523             # -MO=CC entry point
3524             sub compile {
3525 0     0 0   my @options = @_;
3526 0           @options = import(@options);
3527              
3528 0           init_sections();
3529 0           $init = B::C::Section->get("init");
3530 0           $decl = B::C::Section->get("decl");
3531              
3532             # just some subs or main?
3533 0 0         if (@options) {
3534             return sub {
3535 0     0     my ( $objname, $ppname );
3536 0           foreach $objname (@options) {
3537 0 0         $objname = "main::$objname" unless $objname =~ /::/;
3538 0           ( $ppname = $objname ) =~ s/^.*?:://;
3539 0           eval "cc_obj(qq(pp_sub_$ppname), \\&$objname)";
3540 0 0         die "cc_obj(qq(pp_sub_$ppname, \\&$objname) failed: $@" if $@;
3541 0 0         return if $errors;
3542             }
3543 0           my $warner = $SIG{__WARN__};
3544 0           save_sig($warner);
3545 0           fixup_ppaddr();
3546 0 0         return if $check;
3547 0           output_boilerplate();
3548 0           print "\n";
3549 0   0       output_all( $init_name || "init_module" );
3550 0           output_runtime();
3551 0           output_main_rest();
3552             }
3553 0           }
3554             else {
3555 0     0     return sub { cc_main() };
  0            
3556             }
3557             }
3558              
3559             1;
3560              
3561             __END__