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