B::CC::pp_rv2cv problem
[p5sagit/p5-mst-13.2.git] / ext / B / B / CC.pm
CommitLineData
a798dbf2 1# CC.pm
2#
1a52ab62 3# Copyright (c) 1996, 1997, 1998 Malcolm Beattie
a798dbf2 4#
5# You may distribute under the terms of either the GNU General Public
6# License or the Artistic License, as specified in the README file.
7#
8package B::CC;
9use strict;
10use B qw(main_start main_root class comppadlist peekop svref_2object
44887cfa 11 timing_info init_av);
0cc1d052 12use B::C qw(save_unused_subs objsym init_sections mark_unused
a798dbf2 13 output_all output_boilerplate output_main);
14use B::Bblock qw(find_leaders);
15use B::Stackobj qw(:types :flags);
16
17# These should probably be elsewhere
18# Flags for $op->flags
19sub OPf_LIST () { 1 }
20sub OPf_KNOW () { 2 }
21sub OPf_MOD () { 32 }
22sub OPf_STACKED () { 64 }
23sub OPf_SPECIAL () { 128 }
24# op-specific flags for $op->private
25sub OPpASSIGN_BACKWARDS () { 64 }
26sub OPpLVAL_INTRO () { 128 }
27sub OPpDEREF_AV () { 32 }
28sub OPpDEREF_HV () { 64 }
29sub OPpDEREF () { OPpDEREF_AV|OPpDEREF_HV }
30sub OPpFLIP_LINENUM () { 64 }
31sub G_ARRAY () { 1 }
32# cop.h
33sub CXt_NULL () { 0 }
34sub CXt_SUB () { 1 }
35sub CXt_EVAL () { 2 }
36sub CXt_LOOP () { 3 }
37sub CXt_SUBST () { 4 }
38sub CXt_BLOCK () { 5 }
39
40my $module; # module name (when compiled with -m)
41my %done; # hash keyed by $$op of leaders of basic blocks
42 # which have already been done.
43my $leaders; # ref to hash of basic block leaders. Keys are $$op
44 # addresses, values are the $op objects themselves.
45my @bblock_todo; # list of leaders of basic blocks that need visiting
46 # sometime.
47my @cc_todo; # list of tuples defining what PP code needs to be
48 # saved (e.g. CV, main or PMOP repl code). Each tuple
49 # is [$name, $root, $start, @padlist]. PMOP repl code
50 # tuples inherit padlist.
51my @stack; # shadows perl's stack when contents are known.
52 # Values are objects derived from class B::Stackobj
53my @pad; # Lexicals in current pad as Stackobj-derived objects
54my @padlist; # Copy of current padlist so PMOP repl code can find it
55my @cxstack; # Shadows the (compile-time) cxstack for next,last,redo
56my $jmpbuf_ix = 0; # Next free index for dynamically allocated jmpbufs
57my %constobj; # OP_CONST constants as Stackobj-derived objects
58 # keyed by $$sv.
59my $need_freetmps = 0; # We may postpone FREETMPS to the end of each basic
60 # block or even to the end of each loop of blocks,
61 # depending on optimisation options.
62my $know_op = 0; # Set when C variable op already holds the right op
63 # (from an immediately preceding DOOP(ppname)).
64my $errors = 0; # Number of errors encountered
65my %skip_stack; # Hash of PP names which don't need write_back_stack
66my %skip_lexicals; # Hash of PP names which don't need write_back_lexicals
67my %skip_invalidate; # Hash of PP names which don't need invalidate_lexicals
68my %ignore_op; # Hash of ops which do nothing except returning op_next
df2464c8 69my %need_curcop; # Hash of ops which need PL_curcop
a798dbf2 70
71BEGIN {
72 foreach (qw(pp_scalar pp_regcmaybe pp_lineseq pp_scope pp_null)) {
73 $ignore_op{$_} = 1;
74 }
75}
76
a798dbf2 77my ($module_name);
78my ($debug_op, $debug_stack, $debug_cxstack, $debug_pad, $debug_runtime,
79 $debug_shadow, $debug_queue, $debug_lineno, $debug_timings);
80
81# Optimisation options. On the command line, use hyphens instead of
82# underscores for compatibility with gcc-style options. We use
83# underscores here because they are OK in (strict) barewords.
84my ($freetmps_each_bblock, $freetmps_each_loop, $omit_taint);
85my %optimise = (freetmps_each_bblock => \$freetmps_each_bblock,
86 freetmps_each_loop => \$freetmps_each_loop,
87 omit_taint => \$omit_taint);
88# perl patchlevel to generate code for (defaults to current patchlevel)
89my $patchlevel = int(0.5 + 1000 * ($] - 5));
90
91# Could rewrite push_runtime() and output_runtime() to use a
92# temporary file if memory is at a premium.
93my $ppname; # name of current fake PP function
94my $runtime_list_ref;
95my $declare_ref; # Hash ref keyed by C variable type of declarations.
96
97my @pp_list; # list of [$ppname, $runtime_list_ref, $declare_ref]
98 # tuples to be written out.
99
100my ($init, $decl);
101
102sub init_hash { map { $_ => 1 } @_ }
103
104#
105# Initialise the hashes for the default PP functions where we can avoid
106# either write_back_stack, write_back_lexicals or invalidate_lexicals.
107#
108%skip_lexicals = init_hash qw(pp_enter pp_enterloop);
109%skip_invalidate = init_hash qw(pp_enter pp_enterloop);
df2464c8 110%need_curcop = init_hash qw(pp_rv2gv pp_bless pp_repeat pp_sort pp_caller pp_reset pp_rv2cv pp_entereval pp_require pp_dofile pp_entertry pp_enterloop pp_enteriter );
a798dbf2 111
112sub debug {
113 if ($debug_runtime) {
114 warn(@_);
115 } else {
116 runtime(map { chomp; "/* $_ */"} @_);
117 }
118}
119
120sub declare {
121 my ($type, $var) = @_;
122 push(@{$declare_ref->{$type}}, $var);
123}
124
125sub push_runtime {
126 push(@$runtime_list_ref, @_);
127 warn join("\n", @_) . "\n" if $debug_runtime;
128}
129
130sub save_runtime {
131 push(@pp_list, [$ppname, $runtime_list_ref, $declare_ref]);
132}
133
134sub output_runtime {
135 my $ppdata;
136 print qq(#include "cc_runtime.h"\n);
137 foreach $ppdata (@pp_list) {
138 my ($name, $runtime, $declare) = @$ppdata;
139 print "\nstatic\nPP($name)\n{\n";
140 my ($type, $varlist, $line);
141 while (($type, $varlist) = each %$declare) {
142 print "\t$type ", join(", ", @$varlist), ";\n";
143 }
144 foreach $line (@$runtime) {
145 print $line, "\n";
146 }
147 print "}\n";
148 }
149}
150
151sub runtime {
152 my $line;
153 foreach $line (@_) {
154 push_runtime("\t$line");
155 }
156}
157
158sub init_pp {
159 $ppname = shift;
160 $runtime_list_ref = [];
161 $declare_ref = {};
162 runtime("djSP;");
163 declare("I32", "oldsave");
164 declare("SV", "**svp");
165 map { declare("SV", "*$_") } qw(sv src dst left right);
166 declare("MAGIC", "*mg");
167 $decl->add("static OP * $ppname _((ARGSproto));");
168 debug "init_pp: $ppname\n" if $debug_queue;
169}
170
171# Initialise runtime_callback function for Stackobj class
172BEGIN { B::Stackobj::set_callback(\&runtime) }
173
174# Initialise saveoptree_callback for B::C class
175sub cc_queue {
176 my ($name, $root, $start, @pl) = @_;
177 debug "cc_queue: name $name, root $root, start $start, padlist (@pl)\n"
178 if $debug_queue;
179 if ($name eq "*ignore*") {
180 $name = 0;
181 } else {
182 push(@cc_todo, [$name, $root, $start, (@pl ? @pl : @padlist)]);
183 }
184 my $fakeop = new B::FAKEOP ("next" => 0, sibling => 0, ppaddr => $name);
185 $start = $fakeop->save;
186 debug "cc_queue: name $name returns $start\n" if $debug_queue;
187 return $start;
188}
189BEGIN { B::C::set_callback(\&cc_queue) }
190
191sub valid_int { $_[0]->{flags} & VALID_INT }
192sub valid_double { $_[0]->{flags} & VALID_DOUBLE }
193sub valid_numeric { $_[0]->{flags} & (VALID_INT | VALID_DOUBLE) }
194sub valid_sv { $_[0]->{flags} & VALID_SV }
195
196sub top_int { @stack ? $stack[-1]->as_int : "TOPi" }
197sub top_double { @stack ? $stack[-1]->as_double : "TOPn" }
198sub top_numeric { @stack ? $stack[-1]->as_numeric : "TOPn" }
199sub top_sv { @stack ? $stack[-1]->as_sv : "TOPs" }
ff144d38 200sub top_bool { @stack ? $stack[-1]->as_bool : "SvTRUE(TOPs)" }
a798dbf2 201
202sub pop_int { @stack ? (pop @stack)->as_int : "POPi" }
203sub pop_double { @stack ? (pop @stack)->as_double : "POPn" }
204sub pop_numeric { @stack ? (pop @stack)->as_numeric : "POPn" }
205sub pop_sv { @stack ? (pop @stack)->as_sv : "POPs" }
206sub pop_bool {
207 if (@stack) {
ff144d38 208 return ((pop @stack)->as_bool);
a798dbf2 209 } else {
210 # Careful: POPs has an auto-decrement and SvTRUE evaluates
211 # its argument more than once.
212 runtime("sv = POPs;");
213 return "SvTRUE(sv)";
214 }
215}
216
217sub write_back_lexicals {
218 my $avoid = shift || 0;
219 debug "write_back_lexicals($avoid) called from @{[(caller(1))[3]]}\n"
220 if $debug_shadow;
221 my $lex;
222 foreach $lex (@pad) {
223 next unless ref($lex);
224 $lex->write_back unless $lex->{flags} & $avoid;
225 }
226}
227
228sub write_back_stack {
229 my $obj;
230 return unless @stack;
231 runtime(sprintf("EXTEND(sp, %d);", scalar(@stack)));
232 foreach $obj (@stack) {
233 runtime(sprintf("PUSHs((SV*)%s);", $obj->as_sv));
234 }
235 @stack = ();
236}
237
238sub invalidate_lexicals {
239 my $avoid = shift || 0;
240 debug "invalidate_lexicals($avoid) called from @{[(caller(1))[3]]}\n"
241 if $debug_shadow;
242 my $lex;
243 foreach $lex (@pad) {
244 next unless ref($lex);
245 $lex->invalidate unless $lex->{flags} & $avoid;
246 }
247}
248
249sub reload_lexicals {
250 my $lex;
251 foreach $lex (@pad) {
252 next unless ref($lex);
253 my $type = $lex->{type};
254 if ($type == T_INT) {
255 $lex->as_int;
256 } elsif ($type == T_DOUBLE) {
257 $lex->as_double;
258 } else {
259 $lex->as_sv;
260 }
261 }
262}
263
264{
265 package B::Pseudoreg;
266 #
267 # This class allocates pseudo-registers (OK, so they're C variables).
268 #
269 my %alloc; # Keyed by variable name. A value of 1 means the
270 # variable has been declared. A value of 2 means
271 # it's in use.
272
273 sub new_scope { %alloc = () }
274
275 sub new ($$$) {
276 my ($class, $type, $prefix) = @_;
277 my ($ptr, $i, $varname, $status, $obj);
278 $prefix =~ s/^(\**)//;
279 $ptr = $1;
280 $i = 0;
281 do {
282 $varname = "$prefix$i";
283 $status = $alloc{$varname};
284 } while $status == 2;
285 if ($status != 1) {
286 # Not declared yet
287 B::CC::declare($type, "$ptr$varname");
288 $alloc{$varname} = 2; # declared and in use
289 }
290 $obj = bless \$varname, $class;
291 return $obj;
292 }
293 sub DESTROY {
294 my $obj = shift;
295 $alloc{$$obj} = 1; # no longer in use but still declared
296 }
297}
298{
299 package B::Shadow;
300 #
301 # This class gives a standard API for a perl object to shadow a
302 # C variable and only generate reloads/write-backs when necessary.
303 #
304 # Use $obj->load($foo) instead of runtime("shadowed_c_var = foo").
305 # Use $obj->write_back whenever shadowed_c_var needs to be up to date.
306 # Use $obj->invalidate whenever an unknown function may have
307 # set shadow itself.
308
309 sub new {
310 my ($class, $write_back) = @_;
311 # Object fields are perl shadow variable, validity flag
312 # (for *C* variable) and callback sub for write_back
313 # (passed perl shadow variable as argument).
314 bless [undef, 1, $write_back], $class;
315 }
316 sub load {
317 my ($obj, $newval) = @_;
318 $obj->[1] = 0; # C variable no longer valid
319 $obj->[0] = $newval;
320 }
321 sub write_back {
322 my $obj = shift;
323 if (!($obj->[1])) {
324 $obj->[1] = 1; # C variable will now be valid
325 &{$obj->[2]}($obj->[0]);
326 }
327 }
328 sub invalidate { $_[0]->[1] = 0 } # force C variable to be invalid
329}
330my $curcop = new B::Shadow (sub {
331 my $opsym = shift->save;
81009501 332 runtime("PL_curcop = (COP*)$opsym;");
a798dbf2 333});
334
335#
336# Context stack shadowing. Mimics stuff in pp_ctl.c, cop.h and so on.
337#
338sub dopoptoloop {
339 my $cxix = $#cxstack;
340 while ($cxix >= 0 && $cxstack[$cxix]->{type} != CXt_LOOP) {
341 $cxix--;
342 }
343 debug "dopoptoloop: returning $cxix" if $debug_cxstack;
344 return $cxix;
345}
346
347sub dopoptolabel {
348 my $label = shift;
349 my $cxix = $#cxstack;
2e51e4c9 350 while ($cxix >= 0 &&
351 ($cxstack[$cxix]->{type} != CXt_LOOP ||
352 $cxstack[$cxix]->{label} ne $label)) {
a798dbf2 353 $cxix--;
354 }
355 debug "dopoptolabel: returning $cxix" if $debug_cxstack;
356 return $cxix;
357}
358
359sub error {
360 my $format = shift;
361 my $file = $curcop->[0]->filegv->SV->PV;
362 my $line = $curcop->[0]->line;
363 $errors++;
364 if (@_) {
365 warn sprintf("%s:%d: $format\n", $file, $line, @_);
366 } else {
367 warn sprintf("%s:%d: %s\n", $file, $line, $format);
368 }
369}
370
371#
372# Load pad takes (the elements of) a PADLIST as arguments and loads
373# up @pad with Stackobj-derived objects which represent those lexicals.
374# If/when perl itself can generate type information (my int $foo) then
375# we'll take advantage of that here. Until then, we'll use various hacks
376# to tell the compiler when we want a lexical to be a particular type
377# or to be a register.
378#
379sub load_pad {
380 my ($namelistav, $valuelistav) = @_;
381 @padlist = @_;
382 my @namelist = $namelistav->ARRAY;
383 my @valuelist = $valuelistav->ARRAY;
384 my $ix;
385 @pad = ();
386 debug "load_pad: $#namelist names, $#valuelist values\n" if $debug_pad;
387 # Temporary lexicals don't get named so it's possible for @valuelist
388 # to be strictly longer than @namelist. We count $ix up to the end of
389 # @valuelist but index into @namelist for the name. Any temporaries which
390 # run off the end of @namelist will make $namesv undefined and we treat
391 # that the same as having an explicit SPECIAL sv_undef object in @namelist.
392 # [XXX If/when @_ becomes a lexical, we must start at 0 here.]
393 for ($ix = 1; $ix < @valuelist; $ix++) {
394 my $namesv = $namelist[$ix];
395 my $type = T_UNKNOWN;
396 my $flags = 0;
397 my $name = "tmp$ix";
398 my $class = class($namesv);
399 if (!defined($namesv) || $class eq "SPECIAL") {
81009501 400 # temporaries have &PL_sv_undef instead of a PVNV for a name
a798dbf2 401 $flags = VALID_SV|TEMPORARY|REGISTER;
402 } else {
403 if ($namesv->PV =~ /^\$(.*)_([di])(r?)$/) {
404 $name = $1;
405 if ($2 eq "i") {
406 $type = T_INT;
407 $flags = VALID_SV|VALID_INT;
408 } elsif ($2 eq "d") {
409 $type = T_DOUBLE;
410 $flags = VALID_SV|VALID_DOUBLE;
411 }
412 $flags |= REGISTER if $3;
413 }
414 }
415 $pad[$ix] = new B::Stackobj::Padsv ($type, $flags, $ix,
416 "i_$name", "d_$name");
417 declare("IV", $type == T_INT ? "i_$name = 0" : "i_$name");
418 declare("double", $type == T_DOUBLE ? "d_$name = 0" : "d_$name");
81009501 419 debug sprintf("PL_curpad[$ix] = %s\n", $pad[$ix]->peek) if $debug_pad;
a798dbf2 420 }
421}
422
423#
424# Debugging stuff
425#
426sub peek_stack { sprintf "stack = %s\n", join(" ", map($_->minipeek, @stack)) }
427
428#
429# OP stuff
430#
431
432sub label {
433 my $op = shift;
434 # XXX Preserve original label name for "real" labels?
435 return sprintf("lab_%x", $$op);
436}
437
438sub write_label {
439 my $op = shift;
440 push_runtime(sprintf(" %s:", label($op)));
441}
442
443sub loadop {
444 my $op = shift;
445 my $opsym = $op->save;
81009501 446 runtime("PL_op = $opsym;") unless $know_op;
a798dbf2 447 return $opsym;
448}
449
450sub doop {
451 my $op = shift;
452 my $ppname = $op->ppaddr;
453 my $sym = loadop($op);
454 runtime("DOOP($ppname);");
455 $know_op = 1;
456 return $sym;
457}
458
459sub gimme {
460 my $op = shift;
461 my $flags = $op->flags;
462 return (($flags & OPf_KNOW) ? ($flags & OPf_LIST) : "dowantarray()");
463}
464
465#
466# Code generation for PP code
467#
468
469sub pp_null {
470 my $op = shift;
471 return $op->next;
472}
473
474sub pp_stub {
475 my $op = shift;
476 my $gimme = gimme($op);
477 if ($gimme != 1) {
478 # XXX Change to push a constant sv_undef Stackobj onto @stack
479 write_back_stack();
81009501 480 runtime("if ($gimme != G_ARRAY) XPUSHs(&PL_sv_undef);");
a798dbf2 481 }
482 return $op->next;
483}
484
485sub pp_unstack {
486 my $op = shift;
487 @stack = ();
488 runtime("PP_UNSTACK;");
489 return $op->next;
490}
491
492sub pp_and {
493 my $op = shift;
494 my $next = $op->next;
495 reload_lexicals();
496 unshift(@bblock_todo, $next);
497 if (@stack >= 1) {
498 my $bool = pop_bool();
499 write_back_stack();
44887cfa 500 runtime(sprintf("if (!$bool) {XPUSHs(&PL_sv_no); goto %s;}", label($next)));
a798dbf2 501 } else {
502 runtime(sprintf("if (!%s) goto %s;", top_bool(), label($next)),
503 "*sp--;");
504 }
505 return $op->other;
506}
507
508sub pp_or {
509 my $op = shift;
510 my $next = $op->next;
511 reload_lexicals();
512 unshift(@bblock_todo, $next);
513 if (@stack >= 1) {
44887cfa 514 my $bool = pop_bool @stack;
a798dbf2 515 write_back_stack();
44887cfa 516 runtime(sprintf("if (%s) { XPUSHs(&PL_sv_yes); goto %s; }",
517 $bool, label($next)));
a798dbf2 518 } else {
519 runtime(sprintf("if (%s) goto %s;", top_bool(), label($next)),
520 "*sp--;");
521 }
522 return $op->other;
523}
524
525sub pp_cond_expr {
526 my $op = shift;
527 my $false = $op->false;
528 unshift(@bblock_todo, $false);
529 reload_lexicals();
530 my $bool = pop_bool();
531 write_back_stack();
532 runtime(sprintf("if (!$bool) goto %s;", label($false)));
533 return $op->true;
534}
535
536sub pp_padsv {
537 my $op = shift;
538 my $ix = $op->targ;
539 push(@stack, $pad[$ix]);
540 if ($op->flags & OPf_MOD) {
541 my $private = $op->private;
542 if ($private & OPpLVAL_INTRO) {
81009501 543 runtime("SAVECLEARSV(PL_curpad[$ix]);");
a798dbf2 544 } elsif ($private & OPpDEREF) {
81009501 545 runtime(sprintf("vivify_ref(PL_curpad[%d], %d);",
a798dbf2 546 $ix, $private & OPpDEREF));
547 $pad[$ix]->invalidate;
548 }
549 }
550 return $op->next;
551}
552
553sub pp_const {
554 my $op = shift;
555 my $sv = $op->sv;
556 my $obj = $constobj{$$sv};
557 if (!defined($obj)) {
558 $obj = $constobj{$$sv} = new B::Stackobj::Const ($sv);
559 }
560 push(@stack, $obj);
561 return $op->next;
562}
563
564sub pp_nextstate {
565 my $op = shift;
566 $curcop->load($op);
567 @stack = ();
568 debug(sprintf("%s:%d\n", $op->filegv->SV->PV, $op->line)) if $debug_lineno;
569 runtime("TAINT_NOT;") unless $omit_taint;
81009501 570 runtime("sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;");
a798dbf2 571 if ($freetmps_each_bblock || $freetmps_each_loop) {
572 $need_freetmps = 1;
573 } else {
574 runtime("FREETMPS;");
575 }
576 return $op->next;
577}
578
579sub pp_dbstate {
580 my $op = shift;
581 $curcop->invalidate; # XXX?
582 return default_pp($op);
583}
584
df2464c8 585#default_pp will handle this:
586#sub pp_rv2gv { $curcop->write_back; default_pp(@_) }
587#sub pp_bless { $curcop->write_back; default_pp(@_) }
588#sub pp_repeat { $curcop->write_back; default_pp(@_) }
a798dbf2 589# The following subs need $curcop->write_back if we decide to support arybase:
590# pp_pos, pp_substr, pp_index, pp_rindex, pp_aslice, pp_lslice, pp_splice
df2464c8 591#sub pp_sort { $curcop->write_back; default_pp(@_) }
592#sub pp_caller { $curcop->write_back; default_pp(@_) }
593#sub pp_reset { $curcop->write_back; default_pp(@_) }
a798dbf2 594
595sub pp_gv {
596 my $op = shift;
597 my $gvsym = $op->gv->save;
598 write_back_stack();
599 runtime("XPUSHs((SV*)$gvsym);");
600 return $op->next;
601}
602
603sub pp_gvsv {
604 my $op = shift;
605 my $gvsym = $op->gv->save;
606 write_back_stack();
607 if ($op->private & OPpLVAL_INTRO) {
608 runtime("XPUSHs(save_scalar($gvsym));");
609 } else {
610 runtime("XPUSHs(GvSV($gvsym));");
611 }
612 return $op->next;
613}
614
615sub pp_aelemfast {
616 my $op = shift;
617 my $gvsym = $op->gv->save;
618 my $ix = $op->private;
619 my $flag = $op->flags & OPf_MOD;
620 write_back_stack();
621 runtime("svp = av_fetch(GvAV($gvsym), $ix, $flag);",
81009501 622 "PUSHs(svp ? *svp : &PL_sv_undef);");
a798dbf2 623 return $op->next;
624}
625
626sub int_binop {
627 my ($op, $operator) = @_;
628 if ($op->flags & OPf_STACKED) {
629 my $right = pop_int();
630 if (@stack >= 1) {
631 my $left = top_int();
632 $stack[-1]->set_int(&$operator($left, $right));
633 } else {
634 runtime(sprintf("sv_setiv(TOPs, %s);",&$operator("TOPi", $right)));
635 }
636 } else {
637 my $targ = $pad[$op->targ];
638 my $right = new B::Pseudoreg ("IV", "riv");
639 my $left = new B::Pseudoreg ("IV", "liv");
640 runtime(sprintf("$$right = %s; $$left = %s;", pop_int(), pop_int));
641 $targ->set_int(&$operator($$left, $$right));
642 push(@stack, $targ);
643 }
644 return $op->next;
645}
646
647sub INTS_CLOSED () { 0x1 }
648sub INT_RESULT () { 0x2 }
649sub NUMERIC_RESULT () { 0x4 }
650
651sub numeric_binop {
652 my ($op, $operator, $flags) = @_;
653 my $force_int = 0;
654 $force_int ||= ($flags & INT_RESULT);
655 $force_int ||= ($flags & INTS_CLOSED && @stack >= 2
656 && valid_int($stack[-2]) && valid_int($stack[-1]));
657 if ($op->flags & OPf_STACKED) {
658 my $right = pop_numeric();
659 if (@stack >= 1) {
660 my $left = top_numeric();
661 if ($force_int) {
662 $stack[-1]->set_int(&$operator($left, $right));
663 } else {
664 $stack[-1]->set_numeric(&$operator($left, $right));
665 }
666 } else {
667 if ($force_int) {
9c7139f2 668 my $rightruntime = new B::Pseudoreg ("IV", "riv");
669 runtime(sprintf("$$rightruntime = %s;",$right));
a798dbf2 670 runtime(sprintf("sv_setiv(TOPs, %s);",
9c7139f2 671 &$operator("TOPi", $$rightruntime)));
a798dbf2 672 } else {
9c7139f2 673 my $rightruntime = new B::Pseudoreg ("double", "rnv");
674 runtime(sprintf("$$rightruntime = %s;",$right));
a798dbf2 675 runtime(sprintf("sv_setnv(TOPs, %s);",
9c7139f2 676 &$operator("TOPn",$$rightruntime)));
a798dbf2 677 }
678 }
679 } else {
680 my $targ = $pad[$op->targ];
681 $force_int ||= ($targ->{type} == T_INT);
682 if ($force_int) {
683 my $right = new B::Pseudoreg ("IV", "riv");
684 my $left = new B::Pseudoreg ("IV", "liv");
685 runtime(sprintf("$$right = %s; $$left = %s;",
686 pop_numeric(), pop_numeric));
687 $targ->set_int(&$operator($$left, $$right));
688 } else {
689 my $right = new B::Pseudoreg ("double", "rnv");
690 my $left = new B::Pseudoreg ("double", "lnv");
691 runtime(sprintf("$$right = %s; $$left = %s;",
692 pop_numeric(), pop_numeric));
693 $targ->set_numeric(&$operator($$left, $$right));
694 }
695 push(@stack, $targ);
696 }
697 return $op->next;
698}
699
700sub sv_binop {
701 my ($op, $operator, $flags) = @_;
702 if ($op->flags & OPf_STACKED) {
703 my $right = pop_sv();
704 if (@stack >= 1) {
705 my $left = top_sv();
706 if ($flags & INT_RESULT) {
707 $stack[-1]->set_int(&$operator($left, $right));
708 } elsif ($flags & NUMERIC_RESULT) {
709 $stack[-1]->set_numeric(&$operator($left, $right));
710 } else {
711 # XXX Does this work?
712 runtime(sprintf("sv_setsv($left, %s);",
713 &$operator($left, $right)));
714 $stack[-1]->invalidate;
715 }
716 } else {
717 my $f;
718 if ($flags & INT_RESULT) {
719 $f = "sv_setiv";
720 } elsif ($flags & NUMERIC_RESULT) {
721 $f = "sv_setnv";
722 } else {
723 $f = "sv_setsv";
724 }
725 runtime(sprintf("%s(TOPs, %s);", $f, &$operator("TOPs", $right)));
726 }
727 } else {
728 my $targ = $pad[$op->targ];
729 runtime(sprintf("right = %s; left = %s;", pop_sv(), pop_sv));
730 if ($flags & INT_RESULT) {
731 $targ->set_int(&$operator("left", "right"));
732 } elsif ($flags & NUMERIC_RESULT) {
733 $targ->set_numeric(&$operator("left", "right"));
734 } else {
735 # XXX Does this work?
736 runtime(sprintf("sv_setsv(%s, %s);",
737 $targ->as_sv, &$operator("left", "right")));
738 $targ->invalidate;
739 }
740 push(@stack, $targ);
741 }
742 return $op->next;
743}
744
745sub bool_int_binop {
746 my ($op, $operator) = @_;
747 my $right = new B::Pseudoreg ("IV", "riv");
748 my $left = new B::Pseudoreg ("IV", "liv");
749 runtime(sprintf("$$right = %s; $$left = %s;", pop_int(), pop_int()));
750 my $bool = new B::Stackobj::Bool (new B::Pseudoreg ("int", "b"));
751 $bool->set_int(&$operator($$left, $$right));
752 push(@stack, $bool);
753 return $op->next;
754}
755
756sub bool_numeric_binop {
757 my ($op, $operator) = @_;
758 my $right = new B::Pseudoreg ("double", "rnv");
759 my $left = new B::Pseudoreg ("double", "lnv");
760 runtime(sprintf("$$right = %s; $$left = %s;",
761 pop_numeric(), pop_numeric()));
762 my $bool = new B::Stackobj::Bool (new B::Pseudoreg ("int", "b"));
763 $bool->set_numeric(&$operator($$left, $$right));
764 push(@stack, $bool);
765 return $op->next;
766}
767
768sub bool_sv_binop {
769 my ($op, $operator) = @_;
770 runtime(sprintf("right = %s; left = %s;", pop_sv(), pop_sv()));
771 my $bool = new B::Stackobj::Bool (new B::Pseudoreg ("int", "b"));
772 $bool->set_numeric(&$operator("left", "right"));
773 push(@stack, $bool);
774 return $op->next;
775}
776
777sub infix_op {
778 my $opname = shift;
779 return sub { "$_[0] $opname $_[1]" }
780}
781
782sub prefix_op {
783 my $opname = shift;
784 return sub { sprintf("%s(%s)", $opname, join(", ", @_)) }
785}
786
787BEGIN {
788 my $plus_op = infix_op("+");
789 my $minus_op = infix_op("-");
790 my $multiply_op = infix_op("*");
791 my $divide_op = infix_op("/");
792 my $modulo_op = infix_op("%");
793 my $lshift_op = infix_op("<<");
a0d31f98 794 my $rshift_op = infix_op(">>");
a798dbf2 795 my $ncmp_op = sub { "($_[0] > $_[1] ? 1 : ($_[0] < $_[1]) ? -1 : 0)" };
796 my $scmp_op = prefix_op("sv_cmp");
797 my $seq_op = prefix_op("sv_eq");
798 my $sne_op = prefix_op("!sv_eq");
799 my $slt_op = sub { "sv_cmp($_[0], $_[1]) < 0" };
800 my $sgt_op = sub { "sv_cmp($_[0], $_[1]) > 0" };
801 my $sle_op = sub { "sv_cmp($_[0], $_[1]) <= 0" };
802 my $sge_op = sub { "sv_cmp($_[0], $_[1]) >= 0" };
803 my $eq_op = infix_op("==");
804 my $ne_op = infix_op("!=");
805 my $lt_op = infix_op("<");
806 my $gt_op = infix_op(">");
807 my $le_op = infix_op("<=");
808 my $ge_op = infix_op(">=");
809
810 #
811 # XXX The standard perl PP code has extra handling for
812 # some special case arguments of these operators.
813 #
814 sub pp_add { numeric_binop($_[0], $plus_op, INTS_CLOSED) }
815 sub pp_subtract { numeric_binop($_[0], $minus_op, INTS_CLOSED) }
816 sub pp_multiply { numeric_binop($_[0], $multiply_op, INTS_CLOSED) }
817 sub pp_divide { numeric_binop($_[0], $divide_op) }
818 sub pp_modulo { int_binop($_[0], $modulo_op) } # differs from perl's
819 sub pp_ncmp { numeric_binop($_[0], $ncmp_op, INT_RESULT) }
820
821 sub pp_left_shift { int_binop($_[0], $lshift_op) }
822 sub pp_right_shift { int_binop($_[0], $rshift_op) }
823 sub pp_i_add { int_binop($_[0], $plus_op) }
824 sub pp_i_subtract { int_binop($_[0], $minus_op) }
825 sub pp_i_multiply { int_binop($_[0], $multiply_op) }
826 sub pp_i_divide { int_binop($_[0], $divide_op) }
827 sub pp_i_modulo { int_binop($_[0], $modulo_op) }
828
829 sub pp_eq { bool_numeric_binop($_[0], $eq_op) }
830 sub pp_ne { bool_numeric_binop($_[0], $ne_op) }
831 sub pp_lt { bool_numeric_binop($_[0], $lt_op) }
832 sub pp_gt { bool_numeric_binop($_[0], $gt_op) }
833 sub pp_le { bool_numeric_binop($_[0], $le_op) }
834 sub pp_ge { bool_numeric_binop($_[0], $ge_op) }
835
836 sub pp_i_eq { bool_int_binop($_[0], $eq_op) }
837 sub pp_i_ne { bool_int_binop($_[0], $ne_op) }
838 sub pp_i_lt { bool_int_binop($_[0], $lt_op) }
839 sub pp_i_gt { bool_int_binop($_[0], $gt_op) }
840 sub pp_i_le { bool_int_binop($_[0], $le_op) }
841 sub pp_i_ge { bool_int_binop($_[0], $ge_op) }
842
843 sub pp_scmp { sv_binop($_[0], $scmp_op, INT_RESULT) }
844 sub pp_slt { bool_sv_binop($_[0], $slt_op) }
845 sub pp_sgt { bool_sv_binop($_[0], $sgt_op) }
846 sub pp_sle { bool_sv_binop($_[0], $sle_op) }
847 sub pp_sge { bool_sv_binop($_[0], $sge_op) }
848 sub pp_seq { bool_sv_binop($_[0], $seq_op) }
849 sub pp_sne { bool_sv_binop($_[0], $sne_op) }
850}
851
852
853sub pp_sassign {
854 my $op = shift;
855 my $backwards = $op->private & OPpASSIGN_BACKWARDS;
856 my ($dst, $src);
857 if (@stack >= 2) {
858 $dst = pop @stack;
859 $src = pop @stack;
860 ($src, $dst) = ($dst, $src) if $backwards;
861 my $type = $src->{type};
862 if ($type == T_INT) {
863 $dst->set_int($src->as_int);
864 } elsif ($type == T_DOUBLE) {
865 $dst->set_numeric($src->as_numeric);
866 } else {
867 $dst->set_sv($src->as_sv);
868 }
869 push(@stack, $dst);
870 } elsif (@stack == 1) {
871 if ($backwards) {
872 my $src = pop @stack;
873 my $type = $src->{type};
81009501 874 runtime("if (PL_tainting && PL_tainted) TAINT_NOT;");
a798dbf2 875 if ($type == T_INT) {
876 runtime sprintf("sv_setiv(TOPs, %s);", $src->as_int);
877 } elsif ($type == T_DOUBLE) {
878 runtime sprintf("sv_setnv(TOPs, %s);", $src->as_double);
879 } else {
880 runtime sprintf("sv_setsv(TOPs, %s);", $src->as_sv);
881 }
882 runtime("SvSETMAGIC(TOPs);");
883 } else {
b8f1fa48 884 my $dst = $stack[-1];
a798dbf2 885 my $type = $dst->{type};
886 runtime("sv = POPs;");
887 runtime("MAYBE_TAINT_SASSIGN_SRC(sv);");
888 if ($type == T_INT) {
889 $dst->set_int("SvIV(sv)");
890 } elsif ($type == T_DOUBLE) {
891 $dst->set_double("SvNV(sv)");
892 } else {
893 runtime("SvSetSV($dst->{sv}, sv);");
894 $dst->invalidate;
895 }
896 }
897 } else {
898 if ($backwards) {
899 runtime("src = POPs; dst = TOPs;");
900 } else {
901 runtime("dst = POPs; src = TOPs;");
902 }
903 runtime("MAYBE_TAINT_SASSIGN_SRC(src);",
904 "SvSetSV(dst, src);",
905 "SvSETMAGIC(dst);",
906 "SETs(dst);");
907 }
908 return $op->next;
909}
910
911sub pp_preinc {
912 my $op = shift;
913 if (@stack >= 1) {
914 my $obj = $stack[-1];
915 my $type = $obj->{type};
916 if ($type == T_INT || $type == T_DOUBLE) {
917 $obj->set_int($obj->as_int . " + 1");
918 } else {
919 runtime sprintf("PP_PREINC(%s);", $obj->as_sv);
920 $obj->invalidate();
921 }
922 } else {
923 runtime sprintf("PP_PREINC(TOPs);");
924 }
925 return $op->next;
926}
927
928sub pp_pushmark {
929 my $op = shift;
930 write_back_stack();
931 runtime("PUSHMARK(sp);");
932 return $op->next;
933}
934
935sub pp_list {
936 my $op = shift;
937 write_back_stack();
938 my $gimme = gimme($op);
939 if ($gimme == 1) { # sic
940 runtime("POPMARK;"); # need this even though not a "full" pp_list
941 } else {
942 runtime("PP_LIST($gimme);");
943 }
944 return $op->next;
945}
946
947sub pp_entersub {
948 my $op = shift;
949 write_back_lexicals(REGISTER|TEMPORARY);
950 write_back_stack();
951 my $sym = doop($op);
5cfd8ad4 952 runtime("while (PL_op != ($sym)->op_next && PL_op != (OP*)0 ){");
953 runtime("PL_op = (*PL_op->op_ppaddr)(ARGS);");
954 runtime("SPAGAIN;}");
a798dbf2 955 $know_op = 0;
956 invalidate_lexicals(REGISTER|TEMPORARY);
957 return $op->next;
958}
959
5cfd8ad4 960sub pp_goto{
961
962 my $op = shift;
963 my $ppname = $op->ppaddr;
964 write_back_lexicals() unless $skip_lexicals{$ppname};
965 write_back_stack() unless $skip_stack{$ppname};
966 my $sym=doop($op);
967 runtime("if (PL_op != ($sym)->op_next && PL_op != (OP*)0){return PL_op;}");
968 invalidate_lexicals() unless $skip_invalidate{$ppname};
969 return $op->next;
970}
a798dbf2 971sub pp_enterwrite {
972 my $op = shift;
973 pp_entersub($op);
974}
975
976sub pp_leavewrite {
977 my $op = shift;
978 write_back_lexicals(REGISTER|TEMPORARY);
979 write_back_stack();
980 my $sym = doop($op);
981 # XXX Is this the right way to distinguish between it returning
982 # CvSTART(cv) (via doform) and pop_return()?
81009501 983 runtime("if (PL_op) PL_op = (*PL_op->op_ppaddr)(ARGS);");
a798dbf2 984 runtime("SPAGAIN;");
985 $know_op = 0;
986 invalidate_lexicals(REGISTER|TEMPORARY);
987 return $op->next;
988}
989
990sub doeval {
991 my $op = shift;
992 $curcop->write_back;
993 write_back_lexicals(REGISTER|TEMPORARY);
994 write_back_stack();
995 my $sym = loadop($op);
996 my $ppaddr = $op->ppaddr;
997 runtime("PP_EVAL($ppaddr, ($sym)->op_next);");
998 $know_op = 1;
999 invalidate_lexicals(REGISTER|TEMPORARY);
1000 return $op->next;
1001}
1002
1003sub pp_entereval { doeval(@_) }
1004sub pp_require { doeval(@_) }
1005sub pp_dofile { doeval(@_) }
1006
1007sub pp_entertry {
1008 my $op = shift;
1009 $curcop->write_back;
1010 write_back_lexicals(REGISTER|TEMPORARY);
1011 write_back_stack();
1012 my $sym = doop($op);
1013 my $jmpbuf = sprintf("jmpbuf%d", $jmpbuf_ix++);
1014 declare("Sigjmp_buf", $jmpbuf);
1015 runtime(sprintf("PP_ENTERTRY(%s,%s);", $jmpbuf, label($op->other->next)));
1016 invalidate_lexicals(REGISTER|TEMPORARY);
1017 return $op->next;
1018}
1019
1020sub pp_grepstart {
1021 my $op = shift;
1022 if ($need_freetmps && $freetmps_each_loop) {
1023 runtime("FREETMPS;"); # otherwise the grepwhile loop messes things up
1024 $need_freetmps = 0;
1025 }
1026 write_back_stack();
1027 doop($op);
1028 return $op->next->other;
1029}
1030
1031sub pp_mapstart {
1032 my $op = shift;
1033 if ($need_freetmps && $freetmps_each_loop) {
1034 runtime("FREETMPS;"); # otherwise the mapwhile loop messes things up
1035 $need_freetmps = 0;
1036 }
1037 write_back_stack();
1038 doop($op);
1039 return $op->next->other;
1040}
1041
1042sub pp_grepwhile {
1043 my $op = shift;
1044 my $next = $op->next;
1045 unshift(@bblock_todo, $next);
1046 write_back_lexicals();
1047 write_back_stack();
1048 my $sym = doop($op);
1049 # pp_grepwhile can return either op_next or op_other and we need to
1050 # be able to distinguish the two at runtime. Since it's possible for
1051 # both ops to be "inlined", the fields could both be zero. To get
1052 # around that, we hack op_next to be our own op (purely because we
1053 # know it's a non-NULL pointer and can't be the same as op_other).
1054 $init->add("((LOGOP*)$sym)->op_next = $sym;");
81009501 1055 runtime(sprintf("if (PL_op == ($sym)->op_next) goto %s;", label($next)));
a798dbf2 1056 $know_op = 0;
1057 return $op->other;
1058}
1059
1060sub pp_mapwhile {
1061 pp_grepwhile(@_);
1062}
1063
1064sub pp_return {
1065 my $op = shift;
1066 write_back_lexicals(REGISTER|TEMPORARY);
1067 write_back_stack();
1068 doop($op);
7dbaefaf 1069 runtime("PUTBACK;", "return PL_op;");
a798dbf2 1070 $know_op = 0;
1071 return $op->next;
1072}
1073
1074sub nyi {
1075 my $op = shift;
1076 warn sprintf("%s not yet implemented properly\n", $op->ppaddr);
1077 return default_pp($op);
1078}
1079
1080sub pp_range {
1081 my $op = shift;
1082 my $flags = $op->flags;
1083 if (!($flags & OPf_KNOW)) {
1084 error("context of range unknown at compile-time");
1085 }
1086 write_back_lexicals();
1087 write_back_stack();
1088 if (!($flags & OPf_LIST)) {
1089 # We need to save our UNOP structure since pp_flop uses
1090 # it to find and adjust out targ. We don't need it ourselves.
1091 $op->save;
81009501 1092 runtime sprintf("if (SvTRUE(PL_curpad[%d])) goto %s;",
a798dbf2 1093 $op->targ, label($op->false));
1094 unshift(@bblock_todo, $op->false);
1095 }
1096 return $op->true;
1097}
1098
1099sub pp_flip {
1100 my $op = shift;
1101 my $flags = $op->flags;
1102 if (!($flags & OPf_KNOW)) {
1103 error("context of flip unknown at compile-time");
1104 }
1105 if ($flags & OPf_LIST) {
1106 return $op->first->false;
1107 }
1108 write_back_lexicals();
1109 write_back_stack();
1110 # We need to save our UNOP structure since pp_flop uses
1111 # it to find and adjust out targ. We don't need it ourselves.
1112 $op->save;
1113 my $ix = $op->targ;
1114 my $rangeix = $op->first->targ;
1115 runtime(($op->private & OPpFLIP_LINENUM) ?
81009501 1116 "if (PL_last_in_gv && SvIV(TOPs) == IoLINES(GvIOp(PL_last_in_gv))) {"
a798dbf2 1117 : "if (SvTRUE(TOPs)) {");
81009501 1118 runtime("\tsv_setiv(PL_curpad[$rangeix], 1);");
a798dbf2 1119 if ($op->flags & OPf_SPECIAL) {
81009501 1120 runtime("sv_setiv(PL_curpad[$ix], 1);");
a798dbf2 1121 } else {
81009501 1122 runtime("\tsv_setiv(PL_curpad[$ix], 0);",
a798dbf2 1123 "\tsp--;",
1124 sprintf("\tgoto %s;", label($op->first->false)));
1125 }
1126 runtime("}",
81009501 1127 qq{sv_setpv(PL_curpad[$ix], "");},
1128 "SETs(PL_curpad[$ix]);");
a798dbf2 1129 $know_op = 0;
1130 return $op->next;
1131}
1132
1133sub pp_flop {
1134 my $op = shift;
1135 default_pp($op);
1136 $know_op = 0;
1137 return $op->next;
1138}
1139
1140sub enterloop {
1141 my $op = shift;
1142 my $nextop = $op->nextop;
1143 my $lastop = $op->lastop;
1144 my $redoop = $op->redoop;
1145 $curcop->write_back;
1146 debug "enterloop: pushing on cxstack" if $debug_cxstack;
1147 push(@cxstack, {
1148 type => CXt_LOOP,
1149 op => $op,
1150 "label" => $curcop->[0]->label,
1151 nextop => $nextop,
1152 lastop => $lastop,
1153 redoop => $redoop
1154 });
1155 $nextop->save;
1156 $lastop->save;
1157 $redoop->save;
1158 return default_pp($op);
1159}
1160
1161sub pp_enterloop { enterloop(@_) }
1162sub pp_enteriter { enterloop(@_) }
1163
1164sub pp_leaveloop {
1165 my $op = shift;
1166 if (!@cxstack) {
1167 die "panic: leaveloop";
1168 }
1169 debug "leaveloop: popping from cxstack" if $debug_cxstack;
1170 pop(@cxstack);
1171 return default_pp($op);
1172}
1173
1174sub pp_next {
1175 my $op = shift;
1176 my $cxix;
1177 if ($op->flags & OPf_SPECIAL) {
1178 $cxix = dopoptoloop();
1179 if ($cxix < 0) {
1180 error('"next" used outside loop');
1181 return $op->next; # ignore the op
1182 }
1183 } else {
1184 $cxix = dopoptolabel($op->pv);
1185 if ($cxix < 0) {
1186 error('Label not found at compile time for "next %s"', $op->pv);
1187 return $op->next; # ignore the op
1188 }
1189 }
1190 default_pp($op);
1191 my $nextop = $cxstack[$cxix]->{nextop};
1192 push(@bblock_todo, $nextop);
1193 runtime(sprintf("goto %s;", label($nextop)));
1194 return $op->next;
1195}
1196
1197sub pp_redo {
1198 my $op = shift;
1199 my $cxix;
1200 if ($op->flags & OPf_SPECIAL) {
1201 $cxix = dopoptoloop();
1202 if ($cxix < 0) {
1203 error('"redo" used outside loop');
1204 return $op->next; # ignore the op
1205 }
1206 } else {
1207 $cxix = dopoptolabel($op->pv);
1208 if ($cxix < 0) {
1209 error('Label not found at compile time for "redo %s"', $op->pv);
1210 return $op->next; # ignore the op
1211 }
1212 }
1213 default_pp($op);
1214 my $redoop = $cxstack[$cxix]->{redoop};
1215 push(@bblock_todo, $redoop);
1216 runtime(sprintf("goto %s;", label($redoop)));
1217 return $op->next;
1218}
1219
1220sub pp_last {
1221 my $op = shift;
1222 my $cxix;
1223 if ($op->flags & OPf_SPECIAL) {
1224 $cxix = dopoptoloop();
1225 if ($cxix < 0) {
1226 error('"last" used outside loop');
1227 return $op->next; # ignore the op
1228 }
1229 } else {
1230 $cxix = dopoptolabel($op->pv);
1231 if ($cxix < 0) {
1232 error('Label not found at compile time for "last %s"', $op->pv);
1233 return $op->next; # ignore the op
1234 }
1235 # XXX Add support for "last" to leave non-loop blocks
1236 if ($cxstack[$cxix]->{type} != CXt_LOOP) {
1237 error('Use of "last" for non-loop blocks is not yet implemented');
1238 return $op->next; # ignore the op
1239 }
1240 }
1241 default_pp($op);
1242 my $lastop = $cxstack[$cxix]->{lastop}->next;
1243 push(@bblock_todo, $lastop);
1244 runtime(sprintf("goto %s;", label($lastop)));
1245 return $op->next;
1246}
1247
1248sub pp_subst {
1249 my $op = shift;
1250 write_back_lexicals();
1251 write_back_stack();
1252 my $sym = doop($op);
1253 my $replroot = $op->pmreplroot;
1254 if ($$replroot) {
81009501 1255 runtime sprintf("if (PL_op == ((PMOP*)(%s))->op_pmreplroot) goto %s;",
a798dbf2 1256 $sym, label($replroot));
1257 $op->pmreplstart->save;
1258 push(@bblock_todo, $replroot);
1259 }
1260 invalidate_lexicals();
1261 return $op->next;
1262}
1263
1264sub pp_substcont {
1265 my $op = shift;
1266 write_back_lexicals();
1267 write_back_stack();
1268 doop($op);
1269 my $pmop = $op->other;
0cc1d052 1270 # warn sprintf("substcont: op = %s, pmop = %s\n",
1271 # peekop($op), peekop($pmop));#debug
1272# my $pmopsym = objsym($pmop);
a798dbf2 1273 my $pmopsym = $pmop->save; # XXX can this recurse?
0cc1d052 1274# warn "pmopsym = $pmopsym\n";#debug
81009501 1275 runtime sprintf("if (PL_op == ((PMOP*)(%s))->op_pmreplstart) goto %s;",
a798dbf2 1276 $pmopsym, label($pmop->pmreplstart));
1277 invalidate_lexicals();
1278 return $pmop->next;
1279}
1280
1281sub default_pp {
1282 my $op = shift;
1283 my $ppname = $op->ppaddr;
df2464c8 1284 if ($curcop and $need_curcop{$ppname}){
1285 $curcop->write_back;
1286 }
a798dbf2 1287 write_back_lexicals() unless $skip_lexicals{$ppname};
1288 write_back_stack() unless $skip_stack{$ppname};
1289 doop($op);
1290 # XXX If the only way that ops can write to a TEMPORARY lexical is
1291 # when it's named in $op->targ then we could call
1292 # invalidate_lexicals(TEMPORARY) and avoid having to write back all
1293 # the temporaries. For now, we'll play it safe and write back the lot.
1294 invalidate_lexicals() unless $skip_invalidate{$ppname};
1295 return $op->next;
1296}
1297
1298sub compile_op {
1299 my $op = shift;
1300 my $ppname = $op->ppaddr;
1301 if (exists $ignore_op{$ppname}) {
1302 return $op->next;
1303 }
1304 debug peek_stack() if $debug_stack;
1305 if ($debug_op) {
1306 debug sprintf("%s [%s]\n",
1307 peekop($op),
1308 $op->flags & OPf_STACKED ? "OPf_STACKED" : $op->targ);
1309 }
1310 no strict 'refs';
1311 if (defined(&$ppname)) {
1312 $know_op = 0;
1313 return &$ppname($op);
1314 } else {
1315 return default_pp($op);
1316 }
1317}
1318
1319sub compile_bblock {
1320 my $op = shift;
1321 #warn "compile_bblock: ", peekop($op), "\n"; # debug
1322 write_label($op);
1323 $know_op = 0;
1324 do {
1325 $op = compile_op($op);
1326 } while (defined($op) && $$op && !exists($leaders->{$$op}));
1327 write_back_stack(); # boo hoo: big loss
1328 reload_lexicals();
1329 return $op;
1330}
1331
1332sub cc {
1333 my ($name, $root, $start, @padlist) = @_;
1334 my $op;
1335 init_pp($name);
1336 load_pad(@padlist);
1337 B::Pseudoreg->new_scope;
1338 @cxstack = ();
1339 if ($debug_timings) {
1340 warn sprintf("Basic block analysis at %s\n", timing_info);
1341 }
1342 $leaders = find_leaders($root, $start);
1343 @bblock_todo = ($start, values %$leaders);
1344 if ($debug_timings) {
1345 warn sprintf("Compilation at %s\n", timing_info);
1346 }
1347 while (@bblock_todo) {
1348 $op = shift @bblock_todo;
1349 #warn sprintf("Considering basic block %s\n", peekop($op)); # debug
1350 next if !defined($op) || !$$op || $done{$$op};
1351 #warn "...compiling it\n"; # debug
1352 do {
1353 $done{$$op} = 1;
1354 $op = compile_bblock($op);
1355 if ($need_freetmps && $freetmps_each_bblock) {
1356 runtime("FREETMPS;");
1357 $need_freetmps = 0;
1358 }
1359 } while defined($op) && $$op && !$done{$$op};
1360 if ($need_freetmps && $freetmps_each_loop) {
1361 runtime("FREETMPS;");
1362 $need_freetmps = 0;
1363 }
1364 if (!$$op) {
7dbaefaf 1365 runtime("PUTBACK;","return PL_op;");
a798dbf2 1366 } elsif ($done{$$op}) {
1367 runtime(sprintf("goto %s;", label($op)));
1368 }
1369 }
1370 if ($debug_timings) {
1371 warn sprintf("Saving runtime at %s\n", timing_info);
1372 }
1373 save_runtime();
1374}
1375
1376sub cc_recurse {
1377 my $ccinfo;
1378 my $start;
1379 $start = cc_queue(@_) if @_;
1380 while ($ccinfo = shift @cc_todo) {
1381 cc(@$ccinfo);
1382 }
1383 return $start;
1384}
1385
1386sub cc_obj {
1387 my ($name, $cvref) = @_;
1388 my $cv = svref_2object($cvref);
1389 my @padlist = $cv->PADLIST->ARRAY;
1390 my $curpad_sym = $padlist[1]->save;
1391 cc_recurse($name, $cv->ROOT, $cv->START, @padlist);
1392}
1393
1394sub cc_main {
1395 my @comppadlist = comppadlist->ARRAY;
0cc1d052 1396 my $curpad_nam = $comppadlist[0]->save;
1397 my $curpad_sym = $comppadlist[1]->save;
1398 my $init_av = init_av->save;
1399 my $inc_hv = svref_2object(\%INC)->save;
1400 my $inc_av = svref_2object(\@INC)->save;
a798dbf2 1401 my $start = cc_recurse("pp_main", main_root, main_start, @comppadlist);
0cc1d052 1402 save_unused_subs();
a798dbf2 1403 cc_recurse();
1404
1405 return if $errors;
1406 if (!defined($module)) {
81009501 1407 $init->add(sprintf("PL_main_root = s\\_%x;", ${main_root()}),
1408 "PL_main_start = $start;",
5cfd8ad4 1409 "PL_curpad = AvARRAY($curpad_sym);",
0cc1d052 1410 "PL_initav = $init_av;",
1411 "GvHV(PL_incgv) = $inc_hv;",
1412 "GvAV(PL_incgv) = $inc_av;",
5cfd8ad4 1413 "av_store(CvPADLIST(PL_main_cv),0,SvREFCNT_inc($curpad_nam));",
44887cfa 1414 "av_store(CvPADLIST(PL_main_cv),1,SvREFCNT_inc($curpad_sym));",
1415 );
1416
a798dbf2 1417 }
9c7139f2 1418 seek(STDOUT,0,0); #prevent print statements from BEGIN{} into the output
a798dbf2 1419 output_boilerplate();
1420 print "\n";
1421 output_all("perl_init");
1422 output_runtime();
1423 print "\n";
1424 output_main();
1425 if (defined($module)) {
1426 my $cmodule = $module;
1427 $cmodule =~ s/::/__/g;
1428 print <<"EOT";
1429
1430#include "XSUB.h"
1431XS(boot_$cmodule)
1432{
1433 dXSARGS;
1434 perl_init();
1435 ENTER;
1436 SAVETMPS;
81009501 1437 SAVESPTR(PL_curpad);
1438 SAVESPTR(PL_op);
1439 PL_curpad = AvARRAY($curpad_sym);
1440 PL_op = $start;
a798dbf2 1441 pp_main(ARGS);
1442 FREETMPS;
1443 LEAVE;
81009501 1444 ST(0) = &PL_sv_yes;
a798dbf2 1445 XSRETURN(1);
1446}
1447EOT
1448 }
1449 if ($debug_timings) {
1450 warn sprintf("Done at %s\n", timing_info);
1451 }
1452}
1453
1454sub compile {
1455 my @options = @_;
1456 my ($option, $opt, $arg);
1457 OPTION:
1458 while ($option = shift @options) {
1459 if ($option =~ /^-(.)(.*)/) {
1460 $opt = $1;
1461 $arg = $2;
1462 } else {
1463 unshift @options, $option;
1464 last OPTION;
1465 }
1466 if ($opt eq "-" && $arg eq "-") {
1467 shift @options;
1468 last OPTION;
1469 } elsif ($opt eq "o") {
1470 $arg ||= shift @options;
ff06c60c 1471 open(STDOUT, ">$arg") or return "open '>$arg': $!\n";
a798dbf2 1472 } elsif ($opt eq "n") {
1473 $arg ||= shift @options;
1474 $module_name = $arg;
1475 } elsif ($opt eq "u") {
1476 $arg ||= shift @options;
0cc1d052 1477 mark_unused($arg,undef);
a798dbf2 1478 } elsif ($opt eq "f") {
1479 $arg ||= shift @options;
1480 my $value = $arg !~ s/^no-//;
1481 $arg =~ s/-/_/g;
1482 my $ref = $optimise{$arg};
1483 if (defined($ref)) {
1484 $$ref = $value;
1485 } else {
1486 warn qq(ignoring unknown optimisation option "$arg"\n);
1487 }
1488 } elsif ($opt eq "O") {
1489 $arg = 1 if $arg eq "";
1490 my $ref;
1491 foreach $ref (values %optimise) {
1492 $$ref = 0;
1493 }
1494 if ($arg >= 2) {
1495 $freetmps_each_loop = 1;
1496 }
1497 if ($arg >= 1) {
1498 $freetmps_each_bblock = 1 unless $freetmps_each_loop;
1499 }
1500 } elsif ($opt eq "m") {
1501 $arg ||= shift @options;
1502 $module = $arg;
ff144d38 1503 mark_unused($arg,undef);
a798dbf2 1504 } elsif ($opt eq "p") {
1505 $arg ||= shift @options;
1506 $patchlevel = $arg;
1507 } elsif ($opt eq "D") {
1508 $arg ||= shift @options;
1509 foreach $arg (split(//, $arg)) {
1510 if ($arg eq "o") {
1511 B->debug(1);
1512 } elsif ($arg eq "O") {
1513 $debug_op = 1;
1514 } elsif ($arg eq "s") {
1515 $debug_stack = 1;
1516 } elsif ($arg eq "c") {
1517 $debug_cxstack = 1;
1518 } elsif ($arg eq "p") {
1519 $debug_pad = 1;
1520 } elsif ($arg eq "r") {
1521 $debug_runtime = 1;
1522 } elsif ($arg eq "S") {
1523 $debug_shadow = 1;
1524 } elsif ($arg eq "q") {
1525 $debug_queue = 1;
1526 } elsif ($arg eq "l") {
1527 $debug_lineno = 1;
1528 } elsif ($arg eq "t") {
1529 $debug_timings = 1;
1530 }
1531 }
1532 }
1533 }
1534 init_sections();
1535 $init = B::Section->get("init");
1536 $decl = B::Section->get("decl");
1537
1538 if (@options) {
1539 return sub {
1540 my ($objname, $ppname);
1541 foreach $objname (@options) {
1542 $objname = "main::$objname" unless $objname =~ /::/;
1543 ($ppname = $objname) =~ s/^.*?:://;
1544 eval "cc_obj(qq(pp_sub_$ppname), \\&$objname)";
1545 die "cc_obj(qq(pp_sub_$ppname, \\&$objname) failed: $@" if $@;
1546 return if $errors;
1547 }
1548 output_boilerplate();
1549 print "\n";
1550 output_all($module_name || "init_module");
1551 output_runtime();
1552 }
1553 } else {
1554 return sub { cc_main() };
1555 }
1556}
1557
15581;
7f20e9dd 1559
1560__END__
1561
1562=head1 NAME
1563
1564B::CC - Perl compiler's optimized C translation backend
1565
1566=head1 SYNOPSIS
1567
1568 perl -MO=CC[,OPTIONS] foo.pl
1569
1570=head1 DESCRIPTION
1571
1a52ab62 1572This compiler backend takes Perl source and generates C source code
1573corresponding to the flow of your program. In other words, this
1574backend is somewhat a "real" compiler in the sense that many people
1575think about compilers. Note however that, currently, it is a very
1576poor compiler in that although it generates (mostly, or at least
1577sometimes) correct code, it performs relatively few optimisations.
1578This will change as the compiler develops. The result is that
1579running an executable compiled with this backend may start up more
1580quickly than running the original Perl program (a feature shared
1581by the B<C> compiler backend--see F<B::C>) and may also execute
1582slightly faster. This is by no means a good optimising compiler--yet.
1583
1584=head1 OPTIONS
1585
1586If there are any non-option arguments, they are taken to be
1587names of objects to be saved (probably doesn't work properly yet).
1588Without extra arguments, it saves the main program.
1589
1590=over 4
1591
1592=item B<-ofilename>
1593
1594Output to filename instead of STDOUT
1595
1596=item B<-v>
1597
1598Verbose compilation (currently gives a few compilation statistics).
1599
1600=item B<-->
1601
1602Force end of options
1603
1604=item B<-uPackname>
1605
1606Force apparently unused subs from package Packname to be compiled.
1607This allows programs to use eval "foo()" even when sub foo is never
1608seen to be used at compile time. The down side is that any subs which
1609really are never used also have code generated. This option is
1610necessary, for example, if you have a signal handler foo which you
1611initialise with C<$SIG{BAR} = "foo">. A better fix, though, is just
1612to change it to C<$SIG{BAR} = \&foo>. You can have multiple B<-u>
1613options. The compiler tries to figure out which packages may possibly
1614have subs in which need compiling but the current version doesn't do
1615it very well. In particular, it is confused by nested packages (i.e.
1616of the form C<A::B>) where package C<A> does not contain any subs.
1617
1618=item B<-mModulename>
1619
1620Instead of generating source for a runnable executable, generate
1621source for an XSUB module. The boot_Modulename function (which
1622DynaLoader can look for) does the appropriate initialisation and runs
1623the main part of the Perl source that is being compiled.
1624
1625
1626=item B<-D>
1627
1628Debug options (concatenated or separate flags like C<perl -D>).
1629
1630=item B<-Dr>
1631
1632Writes debugging output to STDERR just as it's about to write to the
1633program's runtime (otherwise writes debugging info as comments in
1634its C output).
1635
1636=item B<-DO>
1637
1638Outputs each OP as it's compiled
1639
1640=item B<-Ds>
1641
1642Outputs the contents of the shadow stack at each OP
1643
1644=item B<-Dp>
1645
1646Outputs the contents of the shadow pad of lexicals as it's loaded for
1647each sub or the main program.
1648
1649=item B<-Dq>
1650
1651Outputs the name of each fake PP function in the queue as it's about
1652to process it.
1653
1654=item B<-Dl>
1655
1656Output the filename and line number of each original line of Perl
1657code as it's processed (C<pp_nextstate>).
1658
1659=item B<-Dt>
1660
1661Outputs timing information of compilation stages.
1662
1663=item B<-f>
1664
1665Force optimisations on or off one at a time.
1666
1667=item B<-ffreetmps-each-bblock>
1668
1669Delays FREETMPS from the end of each statement to the end of the each
1670basic block.
1671
1672=item B<-ffreetmps-each-loop>
1673
1674Delays FREETMPS from the end of each statement to the end of the group
1675of basic blocks forming a loop. At most one of the freetmps-each-*
1676options can be used.
1677
1678=item B<-fomit-taint>
1679
1680Omits generating code for handling perl's tainting mechanism.
1681
1682=item B<-On>
1683
1684Optimisation level (n = 0, 1, 2, ...). B<-O> means B<-O1>.
1685Currently, B<-O1> sets B<-ffreetmps-each-bblock> and B<-O2>
1686sets B<-ffreetmps-each-loop>.
1687
1688=back
1689
1690=head1 EXAMPLES
1691
1692 perl -MO=CC,-O2,-ofoo.c foo.pl
1693 perl cc_harness -o foo foo.c
1694
1695Note that C<cc_harness> lives in the C<B> subdirectory of your perl
1696library directory. The utility called C<perlcc> may also be used to
1697help make use of this compiler.
1698
1699 perl -MO=CC,-mFoo,-oFoo.c Foo.pm
1700 perl cc_harness -shared -c -o Foo.so Foo.c
1701
1702=head1 BUGS
1703
1704Plenty. Current status: experimental.
1705
1706=head1 DIFFERENCES
1707
1708These aren't really bugs but they are constructs which are heavily
1709tied to perl's compile-and-go implementation and with which this
1710compiler backend cannot cope.
1711
1712=head2 Loops
1713
1714Standard perl calculates the target of "next", "last", and "redo"
1715at run-time. The compiler calculates the targets at compile-time.
1716For example, the program
1717
1718 sub skip_on_odd { next NUMBER if $_[0] % 2 }
1719 NUMBER: for ($i = 0; $i < 5; $i++) {
1720 skip_on_odd($i);
1721 print $i;
1722 }
1723
1724produces the output
1725
1726 024
1727
1728with standard perl but gives a compile-time error with the compiler.
1729
1730=head2 Context of ".."
1731
1732The context (scalar or array) of the ".." operator determines whether
1733it behaves as a range or a flip/flop. Standard perl delays until
1734runtime the decision of which context it is in but the compiler needs
1735to know the context at compile-time. For example,
1736
1737 @a = (4,6,1,0,0,1);
1738 sub range { (shift @a)..(shift @a) }
1739 print range();
1740 while (@a) { print scalar(range()) }
1741
1742generates the output
1743
1744 456123E0
1745
1746with standard Perl but gives a compile-time error with compiled Perl.
1747
1748=head2 Arithmetic
1749
1750Compiled Perl programs use native C arithemtic much more frequently
1751than standard perl. Operations on large numbers or on boundary
1752cases may produce different behaviour.
1753
1754=head2 Deprecated features
1755
1756Features of standard perl such as C<$[> which have been deprecated
1757in standard perl since Perl5 was released have not been implemented
1758in the compiler.
7f20e9dd 1759
1760=head1 AUTHOR
1761
1762Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>
1763
1764=cut