fix change#2602 to not used hard coded constants
[p5sagit/p5-mst-13.2.git] / ext / B / B / Bytecode.pm
CommitLineData
a798dbf2 1# Bytecode.pm
2#
3# Copyright (c) 1996-1998 Malcolm Beattie
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::Bytecode;
9use strict;
10use Carp;
11use IO::File;
12
13use B qw(minus_c main_cv main_root main_start comppadlist
4c1f658f 14 class peekop walkoptree svref_2object cstring walksymtable
15 SVf_POK SVp_POK SVf_IOK SVp_IOK
16 );
a798dbf2 17use B::Asmdata qw(@optype @specialsv_name);
18use B::Assembler qw(assemble_fh);
19
20my %optype_enum;
21my $i;
22for ($i = 0; $i < @optype; $i++) {
23 $optype_enum{$optype[$i]} = $i;
24}
25
26# Following is SVf_POK|SVp_POK
27# XXX Shouldn't be hardwired
4c1f658f 28sub POK () { SVf_POK|SVp_POK }
a798dbf2 29
4c1f658f 30# Following is SVf_IOK|SVp_IOK
a798dbf2 31# XXX Shouldn't be hardwired
4c1f658f 32sub IOK () { SVf_IOK|SVp_IOK }
a798dbf2 33
34my ($verbose, $module_only, $no_assemble, $debug_bc, $debug_cv);
35my $assembler_pid;
36
37# Optimisation options. On the command line, use hyphens instead of
38# underscores for compatibility with gcc-style options. We use
39# underscores here because they are OK in (strict) barewords.
40my ($strip_syntree, $compress_nullops, $omit_seq, $bypass_nullops);
41my %optimise = (strip_syntax_tree => \$strip_syntree,
42 compress_nullops => \$compress_nullops,
43 omit_sequence_numbers => \$omit_seq,
44 bypass_nullops => \$bypass_nullops);
45
46my $nextix = 0;
47my %symtable; # maps object addresses to object indices.
48 # Filled in at allocation (newsv/newop) time.
49my %saved; # maps object addresses (for SVish classes) to "saved yet?"
50 # flag. Set at FOO::bytecode time usually by SV::bytecode.
51 # Manipulated via saved(), mark_saved(), unmark_saved().
52
53my $svix = -1; # we keep track of when the sv register contains an element
54 # of the object table to avoid unnecessary repeated
55 # consecutive ldsv instructions.
56my $opix = -1; # Ditto for the op register.
57
58sub ldsv {
59 my $ix = shift;
60 if ($ix != $svix) {
61 print "ldsv $ix\n";
62 $svix = $ix;
63 }
64}
65
66sub stsv {
67 my $ix = shift;
68 print "stsv $ix\n";
69 $svix = $ix;
70}
71
72sub set_svix {
73 $svix = shift;
74}
75
76sub ldop {
77 my $ix = shift;
78 if ($ix != $opix) {
79 print "ldop $ix\n";
80 $opix = $ix;
81 }
82}
83
84sub stop {
85 my $ix = shift;
86 print "stop $ix\n";
87 $opix = $ix;
88}
89
90sub set_opix {
91 $opix = shift;
92}
93
94sub pvstring {
95 my $str = shift;
96 if (defined($str)) {
97 return cstring($str . "\0");
98 } else {
99 return '""';
100 }
101}
102
103sub saved { $saved{${$_[0]}} }
104sub mark_saved { $saved{${$_[0]}} = 1 }
105sub unmark_saved { $saved{${$_[0]}} = 0 }
106
107sub debug { $debug_bc = shift }
108
109sub B::OBJECT::nyi {
110 my $obj = shift;
111 warn sprintf("bytecode save method for %s (0x%x) not yet implemented\n",
112 class($obj), $$obj);
113}
114
115#
116# objix may stomp on the op register (for op objects)
117# or the sv register (for SV objects)
118#
119sub B::OBJECT::objix {
120 my $obj = shift;
121 my $ix = $symtable{$$obj};
122 if (defined($ix)) {
123 return $ix;
124 } else {
125 $obj->newix($nextix);
126 return $symtable{$$obj} = $nextix++;
127 }
128}
129
130sub B::SV::newix {
131 my ($sv, $ix) = @_;
132 printf "newsv %d\t# %s\n", $sv->FLAGS & 0xf, class($sv);
133 stsv($ix);
134}
135
136sub B::GV::newix {
137 my ($gv, $ix) = @_;
138 my $gvname = $gv->NAME;
139 my $name = cstring($gv->STASH->NAME . "::" . $gvname);
140 print "gv_fetchpv $name\n";
141 stsv($ix);
142}
143
144sub B::HV::newix {
145 my ($hv, $ix) = @_;
146 my $name = $hv->NAME;
147 if ($name) {
148 # It's a stash
149 printf "gv_stashpv %s\n", cstring($name);
150 stsv($ix);
151 } else {
152 # It's an ordinary HV. Fall back to ordinary newix method
153 $hv->B::SV::newix($ix);
154 }
155}
156
157sub B::SPECIAL::newix {
158 my ($sv, $ix) = @_;
159 # Special case. $$sv is not the address of the SV but an
160 # index into svspecialsv_list.
161 printf "ldspecsv $$sv\t# %s\n", $specialsv_name[$$sv];
162 stsv($ix);
163}
164
165sub B::OP::newix {
166 my ($op, $ix) = @_;
167 my $class = class($op);
168 my $typenum = $optype_enum{$class};
169 croak "OP::newix: can't understand class $class" unless defined($typenum);
170 print "newop $typenum\t# $class\n";
171 stop($ix);
172}
173
174sub B::OP::walkoptree_debug {
175 my $op = shift;
176 warn(sprintf("walkoptree: %s\n", peekop($op)));
177}
178
179sub B::OP::bytecode {
180 my $op = shift;
181 my $next = $op->next;
182 my $nextix;
183 my $sibix = $op->sibling->objix;
184 my $ix = $op->objix;
185 my $type = $op->type;
186
187 if ($bypass_nullops) {
188 $next = $next->next while $$next && $next->type == 0;
189 }
190 $nextix = $next->objix;
191
192 printf "# %s\n", peekop($op) if $debug_bc;
193 ldop($ix);
194 print "op_next $nextix\n";
195 print "op_sibling $sibix\n" unless $strip_syntree;
196 printf "op_type %s\t# %d\n", $op->ppaddr, $type;
197 printf("op_seq %d\n", $op->seq) unless $omit_seq;
198 if ($type || !$compress_nullops) {
199 printf "op_targ %d\nop_flags 0x%x\nop_private 0x%x\n",
200 $op->targ, $op->flags, $op->private;
201 }
202}
203
204sub B::UNOP::bytecode {
205 my $op = shift;
206 my $firstix = $op->first->objix;
207 $op->B::OP::bytecode;
208 if (($op->type || !$compress_nullops) && !$strip_syntree) {
209 print "op_first $firstix\n";
210 }
211}
212
213sub B::LOGOP::bytecode {
214 my $op = shift;
215 my $otherix = $op->other->objix;
216 $op->B::UNOP::bytecode;
217 print "op_other $otherix\n";
218}
219
220sub B::SVOP::bytecode {
221 my $op = shift;
222 my $sv = $op->sv;
223 my $svix = $sv->objix;
224 $op->B::OP::bytecode;
225 print "op_sv $svix\n";
226 $sv->bytecode;
227}
228
229sub B::GVOP::bytecode {
230 my $op = shift;
231 my $gv = $op->gv;
232 my $gvix = $gv->objix;
233 $op->B::OP::bytecode;
234 print "op_gv $gvix\n";
235 $gv->bytecode;
236}
237
238sub B::PVOP::bytecode {
239 my $op = shift;
240 my $pv = $op->pv;
241 $op->B::OP::bytecode;
242 #
243 # This would be easy except that OP_TRANS uses a PVOP to store an
244 # endian-dependent array of 256 shorts instead of a plain string.
245 #
246 if ($op->ppaddr eq "pp_trans") {
247 my @shorts = unpack("s256", $pv); # assembler handles endianness
248 print "op_pv_tr ", join(",", @shorts), "\n";
249 } else {
250 printf "newpv %s\nop_pv\n", pvstring($pv);
251 }
252}
253
254sub B::BINOP::bytecode {
255 my $op = shift;
256 my $lastix = $op->last->objix;
257 $op->B::UNOP::bytecode;
258 if (($op->type || !$compress_nullops) && !$strip_syntree) {
259 print "op_last $lastix\n";
260 }
261}
262
263sub B::CONDOP::bytecode {
264 my $op = shift;
265 my $trueix = $op->true->objix;
266 my $falseix = $op->false->objix;
267 $op->B::UNOP::bytecode;
268 print "op_true $trueix\nop_false $falseix\n";
269}
270
271sub B::LISTOP::bytecode {
272 my $op = shift;
273 my $children = $op->children;
274 $op->B::BINOP::bytecode;
275 if (($op->type || !$compress_nullops) && !$strip_syntree) {
276 print "op_children $children\n";
277 }
278}
279
280sub B::LOOP::bytecode {
281 my $op = shift;
282 my $redoopix = $op->redoop->objix;
283 my $nextopix = $op->nextop->objix;
284 my $lastopix = $op->lastop->objix;
285 $op->B::LISTOP::bytecode;
286 print "op_redoop $redoopix\nop_nextop $nextopix\nop_lastop $lastopix\n";
287}
288
289sub B::COP::bytecode {
290 my $op = shift;
291 my $stash = $op->stash;
292 my $stashix = $stash->objix;
293 my $filegv = $op->filegv;
294 my $filegvix = $filegv->objix;
295 my $line = $op->line;
296 if ($debug_bc) {
297 printf "# line %s:%d\n", $filegv->SV->PV, $line;
298 }
299 $op->B::OP::bytecode;
300 printf <<"EOT", pvstring($op->label), $op->cop_seq, $op->arybase;
301newpv %s
302cop_label
303cop_stash $stashix
304cop_seq %d
305cop_filegv $filegvix
306cop_arybase %d
307cop_line $line
308EOT
309 $filegv->bytecode;
310 $stash->bytecode;
311}
312
313sub B::PMOP::bytecode {
314 my $op = shift;
315 my $replroot = $op->pmreplroot;
316 my $replrootix = $replroot->objix;
317 my $replstartix = $op->pmreplstart->objix;
318 my $ppaddr = $op->ppaddr;
319 # pmnext is corrupt in some PMOPs (see misc.t for example)
320 #my $pmnextix = $op->pmnext->objix;
321
322 if ($$replroot) {
323 # OP_PUSHRE (a mutated version of OP_MATCH for the regexp
324 # argument to a split) stores a GV in op_pmreplroot instead
325 # of a substitution syntax tree. We don't want to walk that...
326 if ($ppaddr eq "pp_pushre") {
327 $replroot->bytecode;
328 } else {
329 walkoptree($replroot, "bytecode");
330 }
331 }
332 $op->B::LISTOP::bytecode;
333 if ($ppaddr eq "pp_pushre") {
334 printf "op_pmreplrootgv $replrootix\n";
335 } else {
336 print "op_pmreplroot $replrootix\nop_pmreplstart $replstartix\n";
337 }
338 my $re = pvstring($op->precomp);
339 # op_pmnext omitted since a perl bug means it's sometime corrupt
340 printf <<"EOT", $op->pmflags, $op->pmpermflags;
341op_pmflags 0x%x
342op_pmpermflags 0x%x
343newpv $re
344pregcomp
345EOT
346}
347
348sub B::SV::bytecode {
349 my $sv = shift;
350 return if saved($sv);
351 my $ix = $sv->objix;
352 my $refcnt = $sv->REFCNT;
353 my $flags = sprintf("0x%x", $sv->FLAGS);
354 ldsv($ix);
355 print "sv_refcnt $refcnt\nsv_flags $flags\n";
356 mark_saved($sv);
357}
358
359sub B::PV::bytecode {
360 my $sv = shift;
361 return if saved($sv);
362 $sv->B::SV::bytecode;
363 printf("newpv %s\nxpv\n", pvstring($sv->PV)) if $sv->FLAGS & POK;
364}
365
366sub B::IV::bytecode {
367 my $sv = shift;
368 return if saved($sv);
369 my $iv = $sv->IVX;
370 $sv->B::SV::bytecode;
371 printf "%s $iv\n", $sv->needs64bits ? "xiv64" : "xiv32";
372}
373
374sub B::NV::bytecode {
375 my $sv = shift;
376 return if saved($sv);
377 $sv->B::SV::bytecode;
378 printf "xnv %s\n", $sv->NVX;
379}
380
381sub B::RV::bytecode {
382 my $sv = shift;
383 return if saved($sv);
384 my $rv = $sv->RV;
385 my $rvix = $rv->objix;
386 $rv->bytecode;
387 $sv->B::SV::bytecode;
388 print "xrv $rvix\n";
389}
390
391sub B::PVIV::bytecode {
392 my $sv = shift;
393 return if saved($sv);
394 my $iv = $sv->IVX;
395 $sv->B::PV::bytecode;
396 printf "%s $iv\n", $sv->needs64bits ? "xiv64" : "xiv32";
397}
398
399sub B::PVNV::bytecode {
400 my ($sv, $flag) = @_;
401 # The $flag argument is passed through PVMG::bytecode by BM::bytecode
402 # and AV::bytecode and indicates special handling. $flag = 1 is used by
403 # BM::bytecode and means that we should ensure we save the whole B-M
404 # table. It consists of 257 bytes (256 char array plus a final \0)
405 # which follow the ordinary PV+\0 and the 257 bytes are *not* reflected
406 # in SvCUR. $flag = 2 is used by AV::bytecode and means that we only
407 # call SV::bytecode instead of saving PV and calling NV::bytecode since
408 # PV/NV/IV stuff is different for AVs.
409 return if saved($sv);
410 if ($flag == 2) {
411 $sv->B::SV::bytecode;
412 } else {
413 my $pv = $sv->PV;
414 $sv->B::IV::bytecode;
415 printf "xnv %s\n", $sv->NVX;
416 if ($flag == 1) {
417 $pv .= "\0" . $sv->TABLE;
418 printf "newpv %s\npv_cur %d\nxpv\n", pvstring($pv),length($pv)-257;
419 } else {
420 printf("newpv %s\nxpv\n", pvstring($pv)) if $sv->FLAGS & POK;
421 }
422 }
423}
424
425sub B::PVMG::bytecode {
426 my ($sv, $flag) = @_;
427 # See B::PVNV::bytecode for an explanation of $flag.
428 return if saved($sv);
429 # XXX We assume SvSTASH is already saved and don't save it later ourselves
430 my $stashix = $sv->SvSTASH->objix;
431 my @mgchain = $sv->MAGIC;
432 my (@mgobjix, $mg);
433 #
434 # We need to traverse the magic chain and get objix for each OBJ
435 # field *before* we do B::PVNV::bytecode since objix overwrites
436 # the sv register. However, we need to write the magic-saving
437 # bytecode *after* B::PVNV::bytecode since sv isn't initialised
438 # to refer to $sv until then.
439 #
440 @mgobjix = map($_->OBJ->objix, @mgchain);
441 $sv->B::PVNV::bytecode($flag);
442 print "xmg_stash $stashix\n";
443 foreach $mg (@mgchain) {
444 printf "sv_magic %s\nmg_obj %d\nnewpv %s\nmg_pv\n",
445 cstring($mg->TYPE), shift(@mgobjix), pvstring($mg->PTR);
446 }
447}
448
449sub B::PVLV::bytecode {
450 my $sv = shift;
451 return if saved($sv);
452 $sv->B::PVMG::bytecode;
453 printf <<'EOT', $sv->TARGOFF, $sv->TARGLEN, cstring($sv->TYPE);
454xlv_targoff %d
455xlv_targlen %d
456xlv_type %s
457EOT
458}
459
460sub B::BM::bytecode {
461 my $sv = shift;
462 return if saved($sv);
463 # See PVNV::bytecode for an explanation of what the argument does
464 $sv->B::PVMG::bytecode(1);
465 printf "xbm_useful %d\nxbm_previous %d\nxbm_rare %d\n",
466 $sv->USEFUL, $sv->PREVIOUS, $sv->RARE;
467}
468
469sub B::GV::bytecode {
470 my $gv = shift;
471 return if saved($gv);
472 my $ix = $gv->objix;
473 mark_saved($gv);
474 my $gvname = $gv->NAME;
475 my $name = cstring($gv->STASH->NAME . "::" . $gvname);
476 my $egv = $gv->EGV;
477 my $egvix = $egv->objix;
478 ldsv($ix);
479 printf <<"EOT", $gv->FLAGS, $gv->GvFLAGS, $gv->LINE;
480sv_flags 0x%x
481xgv_flags 0x%x
482gp_line %d
483EOT
484 my $refcnt = $gv->REFCNT;
485 printf("sv_refcnt_add %d\n", $refcnt - 1) if $refcnt > 1;
486 my $gvrefcnt = $gv->GvREFCNT;
487 printf("gp_refcnt_add %d\n", $gvrefcnt - 1) if $gvrefcnt > 1;
488 if ($gvrefcnt > 1 && $ix != $egvix) {
489 print "gp_share $egvix\n";
490 } else {
491 if ($gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/) {
492 my $i;
493 my @subfield_names = qw(SV AV HV CV FILEGV FORM IO);
494 my @subfields = map($gv->$_(), @subfield_names);
495 my @ixes = map($_->objix, @subfields);
496 # Reset sv register for $gv
497 ldsv($ix);
498 for ($i = 0; $i < @ixes; $i++) {
499 printf "gp_%s %d\n", lc($subfield_names[$i]), $ixes[$i];
500 }
501 # Now save all the subfields
502 my $sv;
503 foreach $sv (@subfields) {
504 $sv->bytecode;
505 }
506 }
507 }
508}
509
510sub B::HV::bytecode {
511 my $hv = shift;
512 return if saved($hv);
513 mark_saved($hv);
514 my $name = $hv->NAME;
515 my $ix = $hv->objix;
516 if (!$name) {
517 # It's an ordinary HV. Stashes have NAME set and need no further
518 # saving beyond the gv_stashpv that $hv->objix already ensures.
519 my @contents = $hv->ARRAY;
520 my ($i, @ixes);
521 for ($i = 1; $i < @contents; $i += 2) {
522 push(@ixes, $contents[$i]->objix);
523 }
524 for ($i = 1; $i < @contents; $i += 2) {
525 $contents[$i]->bytecode;
526 }
527 ldsv($ix);
528 for ($i = 0; $i < @contents; $i += 2) {
529 printf("newpv %s\nhv_store %d\n",
530 pvstring($contents[$i]), $ixes[$i / 2]);
531 }
532 printf "sv_refcnt %d\nsv_flags 0x%x\n", $hv->REFCNT, $hv->FLAGS;
533 }
534}
535
536sub B::AV::bytecode {
537 my $av = shift;
538 return if saved($av);
539 my $ix = $av->objix;
540 my $fill = $av->FILL;
541 my $max = $av->MAX;
542 my (@array, @ixes);
543 if ($fill > -1) {
544 @array = $av->ARRAY;
545 @ixes = map($_->objix, @array);
546 my $sv;
547 foreach $sv (@array) {
548 $sv->bytecode;
549 }
550 }
551 # See PVNV::bytecode for the meaning of the flag argument of 2.
552 $av->B::PVMG::bytecode(2);
553 # Recover sv register and set AvMAX and AvFILL to -1 (since we
554 # create an AV with NEWSV and SvUPGRADE rather than doing newAV
555 # which is what sets AvMAX and AvFILL.
556 ldsv($ix);
557 printf "xav_flags 0x%x\nxav_max -1\nxav_fill -1\n", $av->AvFLAGS;
558 if ($fill > -1) {
559 my $elix;
560 foreach $elix (@ixes) {
561 print "av_push $elix\n";
562 }
563 } else {
564 if ($max > -1) {
565 print "av_extend $max\n";
566 }
567 }
568}
569
570sub B::CV::bytecode {
571 my $cv = shift;
572 return if saved($cv);
573 my $ix = $cv->objix;
574 $cv->B::PVMG::bytecode;
575 my $i;
576 my @subfield_names = qw(ROOT START STASH GV FILEGV PADLIST OUTSIDE);
577 my @subfields = map($cv->$_(), @subfield_names);
578 my @ixes = map($_->objix, @subfields);
579 # Save OP tree from CvROOT (first element of @subfields)
580 my $root = shift @subfields;
581 if ($$root) {
582 walkoptree($root, "bytecode");
583 }
584 # Reset sv register for $cv (since above ->objix calls stomped on it)
585 ldsv($ix);
586 for ($i = 0; $i < @ixes; $i++) {
587 printf "xcv_%s %d\n", lc($subfield_names[$i]), $ixes[$i];
588 }
589 printf "xcv_depth %d\nxcv_flags 0x%x\n", $cv->DEPTH, $cv->FLAGS;
590 # Now save all the subfields (except for CvROOT which was handled
591 # above) and CvSTART (now the initial element of @subfields).
592 shift @subfields; # bye-bye CvSTART
593 my $sv;
594 foreach $sv (@subfields) {
595 $sv->bytecode;
596 }
597}
598
599sub B::IO::bytecode {
600 my $io = shift;
601 return if saved($io);
602 my $ix = $io->objix;
603 my $top_gv = $io->TOP_GV;
604 my $top_gvix = $top_gv->objix;
605 my $fmt_gv = $io->FMT_GV;
606 my $fmt_gvix = $fmt_gv->objix;
607 my $bottom_gv = $io->BOTTOM_GV;
608 my $bottom_gvix = $bottom_gv->objix;
609
610 $io->B::PVMG::bytecode;
611 ldsv($ix);
612 print "xio_top_gv $top_gvix\n";
613 print "xio_fmt_gv $fmt_gvix\n";
614 print "xio_bottom_gv $bottom_gvix\n";
615 my $field;
616 foreach $field (qw(TOP_NAME FMT_NAME BOTTOM_NAME)) {
617 printf "newpv %s\nxio_%s\n", pvstring($io->$field()), lc($field);
618 }
619 foreach $field (qw(LINES PAGE PAGE_LEN LINES_LEFT SUBPROCESS)) {
620 printf "xio_%s %d\n", lc($field), $io->$field();
621 }
622 printf "xio_type %s\nxio_flags 0x%x\n", cstring($io->IoTYPE), $io->IoFLAGS;
623 $top_gv->bytecode;
624 $fmt_gv->bytecode;
625 $bottom_gv->bytecode;
626}
627
628sub B::SPECIAL::bytecode {
629 # nothing extra needs doing
630}
631
632sub bytecompile_object {
633 my $sv;
634 foreach $sv (@_) {
635 svref_2object($sv)->bytecode;
636 }
637}
638
639sub B::GV::bytecodecv {
640 my $gv = shift;
641 my $cv = $gv->CV;
642 if ($$cv && !saved($cv)) {
643 if ($debug_cv) {
644 warn sprintf("saving extra CV &%s::%s (0x%x) from GV 0x%x\n",
645 $gv->STASH->NAME, $gv->NAME, $$cv, $$gv);
646 }
647 $gv->bytecode;
648 }
649}
650
651sub bytecompile_main {
652 my $curpad = (comppadlist->ARRAY)[1];
653 my $curpadix = $curpad->objix;
654 $curpad->bytecode;
655 walkoptree(main_root, "bytecode");
656 warn "done main program, now walking symbol table\n" if $debug_bc;
657 my ($pack, %exclude);
658 foreach $pack (qw(B O AutoLoader DynaLoader Config DB VMS strict vars
659 FileHandle Exporter Carp UNIVERSAL IO Fcntl Symbol
660 SelectSaver blib Cwd))
661 {
662 $exclude{$pack."::"} = 1;
663 }
664 no strict qw(vars refs);
665 walksymtable(\%{"main::"}, "bytecodecv", sub {
666 warn "considering $_[0]\n" if $debug_bc;
667 return !defined($exclude{$_[0]});
668 });
669 if (!$module_only) {
670 printf "main_root %d\n", main_root->objix;
671 printf "main_start %d\n", main_start->objix;
672 printf "curpad $curpadix\n";
673 # XXX Do min_intro_pending and max_intro_pending matter?
674 }
675}
676
677sub prepare_assemble {
678 my $newfh = IO::File->new_tmpfile;
679 select($newfh);
680 binmode $newfh;
681 return $newfh;
682}
683
684sub do_assemble {
685 my $fh = shift;
686 seek($fh, 0, 0); # rewind the temporary file
687 assemble_fh($fh, sub { print OUT @_ });
688}
689
690sub compile {
691 my @options = @_;
692 my ($option, $opt, $arg);
693 open(OUT, ">&STDOUT");
694 binmode OUT;
695 select(OUT);
696 OPTION:
697 while ($option = shift @options) {
698 if ($option =~ /^-(.)(.*)/) {
699 $opt = $1;
700 $arg = $2;
701 } else {
702 unshift @options, $option;
703 last OPTION;
704 }
705 if ($opt eq "-" && $arg eq "-") {
706 shift @options;
707 last OPTION;
708 } elsif ($opt eq "o") {
709 $arg ||= shift @options;
710 open(OUT, ">$arg") or return "$arg: $!\n";
711 binmode OUT;
712 } elsif ($opt eq "D") {
713 $arg ||= shift @options;
714 foreach $arg (split(//, $arg)) {
715 if ($arg eq "b") {
716 $| = 1;
717 debug(1);
718 } elsif ($arg eq "o") {
719 B->debug(1);
720 } elsif ($arg eq "a") {
721 B::Assembler::debug(1);
722 } elsif ($arg eq "C") {
723 $debug_cv = 1;
724 }
725 }
726 } elsif ($opt eq "v") {
727 $verbose = 1;
728 } elsif ($opt eq "m") {
729 $module_only = 1;
730 } elsif ($opt eq "S") {
731 $no_assemble = 1;
732 } elsif ($opt eq "f") {
733 $arg ||= shift @options;
734 my $value = $arg !~ s/^no-//;
735 $arg =~ s/-/_/g;
736 my $ref = $optimise{$arg};
737 if (defined($ref)) {
738 $$ref = $value;
739 } else {
740 warn qq(ignoring unknown optimisation option "$arg"\n);
741 }
742 } elsif ($opt eq "O") {
743 $arg = 1 if $arg eq "";
744 my $ref;
745 foreach $ref (values %optimise) {
746 $$ref = 0;
747 }
748 if ($arg >= 6) {
749 $strip_syntree = 1;
750 }
751 if ($arg >= 2) {
752 $bypass_nullops = 1;
753 }
754 if ($arg >= 1) {
755 $compress_nullops = 1;
756 $omit_seq = 1;
757 }
758 }
759 }
760 if (@options) {
761 return sub {
762 my $objname;
763 my $newfh;
764 $newfh = prepare_assemble() unless $no_assemble;
765 foreach $objname (@options) {
766 eval "bytecompile_object(\\$objname)";
767 }
768 do_assemble($newfh) unless $no_assemble;
769 }
770 } else {
771 return sub {
772 my $newfh;
773 $newfh = prepare_assemble() unless $no_assemble;
774 bytecompile_main();
775 do_assemble($newfh) unless $no_assemble;
776 }
777 }
778}
779
7801;
7f20e9dd 781
782__END__
783
784=head1 NAME
785
786B::Bytecode - Perl compiler's bytecode backend
787
788=head1 SYNOPSIS
789
1a52ab62 790 perl -MO=Bytecode[,OPTIONS] foo.pl
7f20e9dd 791
792=head1 DESCRIPTION
793
1a52ab62 794This compiler backend takes Perl source and generates a
795platform-independent bytecode encapsulating code to load the
796internal structures perl uses to run your program. When the
797generated bytecode is loaded in, your program is ready to run,
798reducing the time which perl would have taken to load and parse
799your program into its internal semi-compiled form. That means that
800compiling with this backend will not help improve the runtime
801execution speed of your program but may improve the start-up time.
802Depending on the environment in which your program runs this may
803or may not be a help.
804
805The resulting bytecode can be run with a special byteperl executable
806or (for non-main programs) be loaded via the C<byteload_fh> function
807in the F<B> module.
808
809=head1 OPTIONS
810
811If there are any non-option arguments, they are taken to be names of
812objects to be saved (probably doesn't work properly yet). Without
813extra arguments, it saves the main program.
814
815=over 4
816
817=item B<-ofilename>
818
819Output to filename instead of STDOUT.
820
821=item B<-->
822
823Force end of options.
824
825=item B<-f>
826
827Force optimisations on or off one at a time. Each can be preceded
828by B<no-> to turn the option off (e.g. B<-fno-compress-nullops>).
829
830=item B<-fcompress-nullops>
831
832Only fills in the necessary fields of ops which have
833been optimised away by perl's internal compiler.
834
835=item B<-fomit-sequence-numbers>
836
837Leaves out code to fill in the op_seq field of all ops
838which is only used by perl's internal compiler.
839
840=item B<-fbypass-nullops>
841
842If op->op_next ever points to a NULLOP, replaces the op_next field
843with the first non-NULLOP in the path of execution.
844
845=item B<-fstrip-syntax-tree>
846
847Leaves out code to fill in the pointers which link the internal syntax
848tree together. They're not needed at run-time but leaving them out
849will make it impossible to recompile or disassemble the resulting
850program. It will also stop C<goto label> statements from working.
851
852=item B<-On>
853
854Optimisation level (n = 0, 1, 2, ...). B<-O> means B<-O1>.
855B<-O1> sets B<-fcompress-nullops> B<-fomit-sequence numbers>.
856B<-O6> adds B<-fstrip-syntax-tree>.
857
858=item B<-D>
859
860Debug options (concatenated or separate flags like C<perl -D>).
861
862=item B<-Do>
863
864Prints each OP as it's processed.
865
866=item B<-Db>
867
868Print debugging information about bytecompiler progress.
869
870=item B<-Da>
871
872Tells the (bytecode) assembler to include source assembler lines
873in its output as bytecode comments.
874
875=item B<-DC>
876
877Prints each CV taken from the final symbol tree walk.
878
879=item B<-S>
880
881Output (bytecode) assembler source rather than piping it
882through the assembler and outputting bytecode.
883
884=item B<-m>
885
886Compile as a module rather than a standalone program. Currently this
887just means that the bytecodes for initialising C<main_start>,
888C<main_root> and C<curpad> are omitted.
889
890=back
891
707102d0 892=head1 EXAMPLES
1a52ab62 893
894 perl -MO=Bytecode,-O6,-o,foo.plc foo.pl
895
896 perl -MO=Bytecode,-S foo.pl > foo.S
897 assemble foo.S > foo.plc
898 byteperl foo.plc
899
900 perl -MO=Bytecode,-m,-oFoo.pmc Foo.pm
901
902=head1 BUGS
903
904Plenty. Current status: experimental.
7f20e9dd 905
906=head1 AUTHOR
907
908Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>
909
910=cut