avoid stash pointers in optree under USE_ITHREADS
[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;
3f872cb9 196 printf "op_type %s\t# %d\n", "pp_" . $op->name, $type;
a798dbf2 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
7934575e 229sub B::PADOP::bytecode {
a798dbf2 230 my $op = shift;
7934575e 231 my $padix = $op->padix;
a798dbf2 232 $op->B::OP::bytecode;
7934575e 233 print "op_padix $padix\n";
a798dbf2 234}
235
236sub B::PVOP::bytecode {
237 my $op = shift;
238 my $pv = $op->pv;
239 $op->B::OP::bytecode;
240 #
241 # This would be easy except that OP_TRANS uses a PVOP to store an
242 # endian-dependent array of 256 shorts instead of a plain string.
243 #
3f872cb9 244 if ($op->name eq "trans") {
a798dbf2 245 my @shorts = unpack("s256", $pv); # assembler handles endianness
246 print "op_pv_tr ", join(",", @shorts), "\n";
247 } else {
248 printf "newpv %s\nop_pv\n", pvstring($pv);
249 }
250}
251
252sub B::BINOP::bytecode {
253 my $op = shift;
254 my $lastix = $op->last->objix;
255 $op->B::UNOP::bytecode;
256 if (($op->type || !$compress_nullops) && !$strip_syntree) {
257 print "op_last $lastix\n";
258 }
259}
260
a798dbf2 261sub B::LISTOP::bytecode {
262 my $op = shift;
263 my $children = $op->children;
264 $op->B::BINOP::bytecode;
265 if (($op->type || !$compress_nullops) && !$strip_syntree) {
266 print "op_children $children\n";
267 }
268}
269
270sub B::LOOP::bytecode {
271 my $op = shift;
272 my $redoopix = $op->redoop->objix;
273 my $nextopix = $op->nextop->objix;
274 my $lastopix = $op->lastop->objix;
275 $op->B::LISTOP::bytecode;
276 print "op_redoop $redoopix\nop_nextop $nextopix\nop_lastop $lastopix\n";
277}
278
279sub B::COP::bytecode {
280 my $op = shift;
11faa288 281 my $stashpv = $op->stashpv;
57843af0 282 my $file = $op->file;
a798dbf2 283 my $line = $op->line;
b295d113 284 my $warnings = $op->warnings;
285 my $warningsix = $warnings->objix;
a798dbf2 286 if ($debug_bc) {
57843af0 287 printf "# line %s:%d\n", $file, $line;
a798dbf2 288 }
289 $op->B::OP::bytecode;
11faa288 290 printf <<"EOT", pvstring($op->label), pvstring($stashpv), $op->cop_seq, pvstring($file), $op->arybase;
a798dbf2 291newpv %s
292cop_label
11faa288 293newpv %s
294cop_stashpv
a798dbf2 295cop_seq %d
57843af0 296newpv %s
297cop_file
a798dbf2 298cop_arybase %d
299cop_line $line
b295d113 300cop_warnings $warningsix
a798dbf2 301EOT
a798dbf2 302 $stash->bytecode;
303}
304
305sub B::PMOP::bytecode {
306 my $op = shift;
307 my $replroot = $op->pmreplroot;
308 my $replrootix = $replroot->objix;
309 my $replstartix = $op->pmreplstart->objix;
3f872cb9 310 my $opname = $op->name;
a798dbf2 311 # pmnext is corrupt in some PMOPs (see misc.t for example)
312 #my $pmnextix = $op->pmnext->objix;
313
314 if ($$replroot) {
315 # OP_PUSHRE (a mutated version of OP_MATCH for the regexp
316 # argument to a split) stores a GV in op_pmreplroot instead
317 # of a substitution syntax tree. We don't want to walk that...
3f872cb9 318 if ($opname eq "pushre") {
a798dbf2 319 $replroot->bytecode;
320 } else {
321 walkoptree($replroot, "bytecode");
322 }
323 }
324 $op->B::LISTOP::bytecode;
3f872cb9 325 if ($opname eq "pushre") {
a798dbf2 326 printf "op_pmreplrootgv $replrootix\n";
327 } else {
328 print "op_pmreplroot $replrootix\nop_pmreplstart $replstartix\n";
329 }
330 my $re = pvstring($op->precomp);
331 # op_pmnext omitted since a perl bug means it's sometime corrupt
332 printf <<"EOT", $op->pmflags, $op->pmpermflags;
333op_pmflags 0x%x
334op_pmpermflags 0x%x
335newpv $re
336pregcomp
337EOT
338}
339
340sub B::SV::bytecode {
341 my $sv = shift;
342 return if saved($sv);
343 my $ix = $sv->objix;
344 my $refcnt = $sv->REFCNT;
345 my $flags = sprintf("0x%x", $sv->FLAGS);
346 ldsv($ix);
347 print "sv_refcnt $refcnt\nsv_flags $flags\n";
348 mark_saved($sv);
349}
350
351sub B::PV::bytecode {
352 my $sv = shift;
353 return if saved($sv);
354 $sv->B::SV::bytecode;
355 printf("newpv %s\nxpv\n", pvstring($sv->PV)) if $sv->FLAGS & POK;
356}
357
358sub B::IV::bytecode {
359 my $sv = shift;
360 return if saved($sv);
361 my $iv = $sv->IVX;
362 $sv->B::SV::bytecode;
363 printf "%s $iv\n", $sv->needs64bits ? "xiv64" : "xiv32";
364}
365
366sub B::NV::bytecode {
367 my $sv = shift;
368 return if saved($sv);
369 $sv->B::SV::bytecode;
370 printf "xnv %s\n", $sv->NVX;
371}
372
373sub B::RV::bytecode {
374 my $sv = shift;
375 return if saved($sv);
376 my $rv = $sv->RV;
377 my $rvix = $rv->objix;
378 $rv->bytecode;
379 $sv->B::SV::bytecode;
380 print "xrv $rvix\n";
381}
382
383sub B::PVIV::bytecode {
384 my $sv = shift;
385 return if saved($sv);
386 my $iv = $sv->IVX;
387 $sv->B::PV::bytecode;
388 printf "%s $iv\n", $sv->needs64bits ? "xiv64" : "xiv32";
389}
390
391sub B::PVNV::bytecode {
9636a016 392 my $sv = shift;
393 my $flag = shift || 0;
a798dbf2 394 # The $flag argument is passed through PVMG::bytecode by BM::bytecode
395 # and AV::bytecode and indicates special handling. $flag = 1 is used by
396 # BM::bytecode and means that we should ensure we save the whole B-M
397 # table. It consists of 257 bytes (256 char array plus a final \0)
398 # which follow the ordinary PV+\0 and the 257 bytes are *not* reflected
399 # in SvCUR. $flag = 2 is used by AV::bytecode and means that we only
400 # call SV::bytecode instead of saving PV and calling NV::bytecode since
401 # PV/NV/IV stuff is different for AVs.
402 return if saved($sv);
403 if ($flag == 2) {
404 $sv->B::SV::bytecode;
405 } else {
406 my $pv = $sv->PV;
407 $sv->B::IV::bytecode;
408 printf "xnv %s\n", $sv->NVX;
409 if ($flag == 1) {
410 $pv .= "\0" . $sv->TABLE;
411 printf "newpv %s\npv_cur %d\nxpv\n", pvstring($pv),length($pv)-257;
412 } else {
413 printf("newpv %s\nxpv\n", pvstring($pv)) if $sv->FLAGS & POK;
414 }
415 }
416}
417
418sub B::PVMG::bytecode {
419 my ($sv, $flag) = @_;
420 # See B::PVNV::bytecode for an explanation of $flag.
421 return if saved($sv);
422 # XXX We assume SvSTASH is already saved and don't save it later ourselves
423 my $stashix = $sv->SvSTASH->objix;
424 my @mgchain = $sv->MAGIC;
425 my (@mgobjix, $mg);
426 #
427 # We need to traverse the magic chain and get objix for each OBJ
428 # field *before* we do B::PVNV::bytecode since objix overwrites
429 # the sv register. However, we need to write the magic-saving
430 # bytecode *after* B::PVNV::bytecode since sv isn't initialised
431 # to refer to $sv until then.
432 #
433 @mgobjix = map($_->OBJ->objix, @mgchain);
434 $sv->B::PVNV::bytecode($flag);
435 print "xmg_stash $stashix\n";
436 foreach $mg (@mgchain) {
437 printf "sv_magic %s\nmg_obj %d\nnewpv %s\nmg_pv\n",
438 cstring($mg->TYPE), shift(@mgobjix), pvstring($mg->PTR);
439 }
440}
441
442sub B::PVLV::bytecode {
443 my $sv = shift;
444 return if saved($sv);
445 $sv->B::PVMG::bytecode;
446 printf <<'EOT', $sv->TARGOFF, $sv->TARGLEN, cstring($sv->TYPE);
447xlv_targoff %d
448xlv_targlen %d
449xlv_type %s
450EOT
451}
452
453sub B::BM::bytecode {
454 my $sv = shift;
455 return if saved($sv);
456 # See PVNV::bytecode for an explanation of what the argument does
457 $sv->B::PVMG::bytecode(1);
458 printf "xbm_useful %d\nxbm_previous %d\nxbm_rare %d\n",
459 $sv->USEFUL, $sv->PREVIOUS, $sv->RARE;
460}
461
462sub B::GV::bytecode {
463 my $gv = shift;
464 return if saved($gv);
465 my $ix = $gv->objix;
466 mark_saved($gv);
467 my $gvname = $gv->NAME;
468 my $name = cstring($gv->STASH->NAME . "::" . $gvname);
469 my $egv = $gv->EGV;
470 my $egvix = $egv->objix;
471 ldsv($ix);
86162ee8 472 printf <<"EOT", $gv->FLAGS, $gv->GvFLAGS, $gv->LINE, pvstring($gv->FILE);
a798dbf2 473sv_flags 0x%x
474xgv_flags 0x%x
475gp_line %d
86162ee8 476newpv %s
477gp_file
a798dbf2 478EOT
479 my $refcnt = $gv->REFCNT;
480 printf("sv_refcnt_add %d\n", $refcnt - 1) if $refcnt > 1;
481 my $gvrefcnt = $gv->GvREFCNT;
482 printf("gp_refcnt_add %d\n", $gvrefcnt - 1) if $gvrefcnt > 1;
483 if ($gvrefcnt > 1 && $ix != $egvix) {
484 print "gp_share $egvix\n";
485 } else {
486 if ($gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/) {
487 my $i;
b195d487 488 my @subfield_names = qw(SV AV HV CV FORM IO);
a798dbf2 489 my @subfields = map($gv->$_(), @subfield_names);
490 my @ixes = map($_->objix, @subfields);
491 # Reset sv register for $gv
492 ldsv($ix);
493 for ($i = 0; $i < @ixes; $i++) {
494 printf "gp_%s %d\n", lc($subfield_names[$i]), $ixes[$i];
495 }
496 # Now save all the subfields
497 my $sv;
498 foreach $sv (@subfields) {
499 $sv->bytecode;
500 }
501 }
502 }
503}
504
505sub B::HV::bytecode {
506 my $hv = shift;
507 return if saved($hv);
508 mark_saved($hv);
509 my $name = $hv->NAME;
510 my $ix = $hv->objix;
511 if (!$name) {
512 # It's an ordinary HV. Stashes have NAME set and need no further
513 # saving beyond the gv_stashpv that $hv->objix already ensures.
514 my @contents = $hv->ARRAY;
515 my ($i, @ixes);
516 for ($i = 1; $i < @contents; $i += 2) {
517 push(@ixes, $contents[$i]->objix);
518 }
519 for ($i = 1; $i < @contents; $i += 2) {
520 $contents[$i]->bytecode;
521 }
522 ldsv($ix);
523 for ($i = 0; $i < @contents; $i += 2) {
524 printf("newpv %s\nhv_store %d\n",
525 pvstring($contents[$i]), $ixes[$i / 2]);
526 }
527 printf "sv_refcnt %d\nsv_flags 0x%x\n", $hv->REFCNT, $hv->FLAGS;
528 }
529}
530
531sub B::AV::bytecode {
532 my $av = shift;
533 return if saved($av);
534 my $ix = $av->objix;
535 my $fill = $av->FILL;
536 my $max = $av->MAX;
537 my (@array, @ixes);
538 if ($fill > -1) {
539 @array = $av->ARRAY;
540 @ixes = map($_->objix, @array);
541 my $sv;
542 foreach $sv (@array) {
543 $sv->bytecode;
544 }
545 }
546 # See PVNV::bytecode for the meaning of the flag argument of 2.
547 $av->B::PVMG::bytecode(2);
548 # Recover sv register and set AvMAX and AvFILL to -1 (since we
549 # create an AV with NEWSV and SvUPGRADE rather than doing newAV
550 # which is what sets AvMAX and AvFILL.
551 ldsv($ix);
552 printf "xav_flags 0x%x\nxav_max -1\nxav_fill -1\n", $av->AvFLAGS;
553 if ($fill > -1) {
554 my $elix;
555 foreach $elix (@ixes) {
556 print "av_push $elix\n";
557 }
558 } else {
559 if ($max > -1) {
560 print "av_extend $max\n";
561 }
562 }
563}
564
565sub B::CV::bytecode {
566 my $cv = shift;
567 return if saved($cv);
568 my $ix = $cv->objix;
569 $cv->B::PVMG::bytecode;
570 my $i;
b195d487 571 my @subfield_names = qw(ROOT START STASH GV PADLIST OUTSIDE);
a798dbf2 572 my @subfields = map($cv->$_(), @subfield_names);
573 my @ixes = map($_->objix, @subfields);
574 # Save OP tree from CvROOT (first element of @subfields)
575 my $root = shift @subfields;
576 if ($$root) {
577 walkoptree($root, "bytecode");
578 }
579 # Reset sv register for $cv (since above ->objix calls stomped on it)
580 ldsv($ix);
581 for ($i = 0; $i < @ixes; $i++) {
582 printf "xcv_%s %d\n", lc($subfield_names[$i]), $ixes[$i];
583 }
584 printf "xcv_depth %d\nxcv_flags 0x%x\n", $cv->DEPTH, $cv->FLAGS;
57843af0 585 printf "newpv %s\nxcv_file\n", pvstring($cv->FILE);
a798dbf2 586 # Now save all the subfields (except for CvROOT which was handled
587 # above) and CvSTART (now the initial element of @subfields).
588 shift @subfields; # bye-bye CvSTART
589 my $sv;
590 foreach $sv (@subfields) {
591 $sv->bytecode;
592 }
593}
594
595sub B::IO::bytecode {
596 my $io = shift;
597 return if saved($io);
598 my $ix = $io->objix;
599 my $top_gv = $io->TOP_GV;
600 my $top_gvix = $top_gv->objix;
601 my $fmt_gv = $io->FMT_GV;
602 my $fmt_gvix = $fmt_gv->objix;
603 my $bottom_gv = $io->BOTTOM_GV;
604 my $bottom_gvix = $bottom_gv->objix;
605
606 $io->B::PVMG::bytecode;
607 ldsv($ix);
608 print "xio_top_gv $top_gvix\n";
609 print "xio_fmt_gv $fmt_gvix\n";
610 print "xio_bottom_gv $bottom_gvix\n";
611 my $field;
612 foreach $field (qw(TOP_NAME FMT_NAME BOTTOM_NAME)) {
613 printf "newpv %s\nxio_%s\n", pvstring($io->$field()), lc($field);
614 }
615 foreach $field (qw(LINES PAGE PAGE_LEN LINES_LEFT SUBPROCESS)) {
616 printf "xio_%s %d\n", lc($field), $io->$field();
617 }
618 printf "xio_type %s\nxio_flags 0x%x\n", cstring($io->IoTYPE), $io->IoFLAGS;
619 $top_gv->bytecode;
620 $fmt_gv->bytecode;
621 $bottom_gv->bytecode;
622}
623
624sub B::SPECIAL::bytecode {
625 # nothing extra needs doing
626}
627
628sub bytecompile_object {
629 my $sv;
630 foreach $sv (@_) {
631 svref_2object($sv)->bytecode;
632 }
633}
634
635sub B::GV::bytecodecv {
636 my $gv = shift;
637 my $cv = $gv->CV;
638 if ($$cv && !saved($cv)) {
639 if ($debug_cv) {
640 warn sprintf("saving extra CV &%s::%s (0x%x) from GV 0x%x\n",
641 $gv->STASH->NAME, $gv->NAME, $$cv, $$gv);
642 }
643 $gv->bytecode;
644 }
645}
646
647sub bytecompile_main {
648 my $curpad = (comppadlist->ARRAY)[1];
649 my $curpadix = $curpad->objix;
650 $curpad->bytecode;
651 walkoptree(main_root, "bytecode");
652 warn "done main program, now walking symbol table\n" if $debug_bc;
653 my ($pack, %exclude);
654 foreach $pack (qw(B O AutoLoader DynaLoader Config DB VMS strict vars
655 FileHandle Exporter Carp UNIVERSAL IO Fcntl Symbol
656 SelectSaver blib Cwd))
657 {
658 $exclude{$pack."::"} = 1;
659 }
660 no strict qw(vars refs);
661 walksymtable(\%{"main::"}, "bytecodecv", sub {
662 warn "considering $_[0]\n" if $debug_bc;
663 return !defined($exclude{$_[0]});
664 });
665 if (!$module_only) {
666 printf "main_root %d\n", main_root->objix;
667 printf "main_start %d\n", main_start->objix;
668 printf "curpad $curpadix\n";
669 # XXX Do min_intro_pending and max_intro_pending matter?
670 }
671}
672
673sub prepare_assemble {
674 my $newfh = IO::File->new_tmpfile;
675 select($newfh);
676 binmode $newfh;
677 return $newfh;
678}
679
680sub do_assemble {
681 my $fh = shift;
682 seek($fh, 0, 0); # rewind the temporary file
683 assemble_fh($fh, sub { print OUT @_ });
684}
685
686sub compile {
687 my @options = @_;
688 my ($option, $opt, $arg);
689 open(OUT, ">&STDOUT");
690 binmode OUT;
691 select(OUT);
692 OPTION:
693 while ($option = shift @options) {
694 if ($option =~ /^-(.)(.*)/) {
695 $opt = $1;
696 $arg = $2;
697 } else {
698 unshift @options, $option;
699 last OPTION;
700 }
701 if ($opt eq "-" && $arg eq "-") {
702 shift @options;
703 last OPTION;
704 } elsif ($opt eq "o") {
705 $arg ||= shift @options;
706 open(OUT, ">$arg") or return "$arg: $!\n";
707 binmode OUT;
708 } elsif ($opt eq "D") {
709 $arg ||= shift @options;
710 foreach $arg (split(//, $arg)) {
711 if ($arg eq "b") {
712 $| = 1;
713 debug(1);
714 } elsif ($arg eq "o") {
715 B->debug(1);
716 } elsif ($arg eq "a") {
717 B::Assembler::debug(1);
718 } elsif ($arg eq "C") {
719 $debug_cv = 1;
720 }
721 }
722 } elsif ($opt eq "v") {
723 $verbose = 1;
724 } elsif ($opt eq "m") {
725 $module_only = 1;
726 } elsif ($opt eq "S") {
727 $no_assemble = 1;
728 } elsif ($opt eq "f") {
729 $arg ||= shift @options;
730 my $value = $arg !~ s/^no-//;
731 $arg =~ s/-/_/g;
732 my $ref = $optimise{$arg};
733 if (defined($ref)) {
734 $$ref = $value;
735 } else {
736 warn qq(ignoring unknown optimisation option "$arg"\n);
737 }
738 } elsif ($opt eq "O") {
739 $arg = 1 if $arg eq "";
740 my $ref;
741 foreach $ref (values %optimise) {
742 $$ref = 0;
743 }
744 if ($arg >= 6) {
745 $strip_syntree = 1;
746 }
747 if ($arg >= 2) {
748 $bypass_nullops = 1;
749 }
750 if ($arg >= 1) {
751 $compress_nullops = 1;
752 $omit_seq = 1;
753 }
754 }
755 }
756 if (@options) {
757 return sub {
758 my $objname;
759 my $newfh;
760 $newfh = prepare_assemble() unless $no_assemble;
761 foreach $objname (@options) {
762 eval "bytecompile_object(\\$objname)";
763 }
764 do_assemble($newfh) unless $no_assemble;
765 }
766 } else {
767 return sub {
768 my $newfh;
769 $newfh = prepare_assemble() unless $no_assemble;
770 bytecompile_main();
771 do_assemble($newfh) unless $no_assemble;
772 }
773 }
774}
775
7761;
7f20e9dd 777
778__END__
779
780=head1 NAME
781
782B::Bytecode - Perl compiler's bytecode backend
783
784=head1 SYNOPSIS
785
1a52ab62 786 perl -MO=Bytecode[,OPTIONS] foo.pl
7f20e9dd 787
788=head1 DESCRIPTION
789
1a52ab62 790This compiler backend takes Perl source and generates a
791platform-independent bytecode encapsulating code to load the
792internal structures perl uses to run your program. When the
793generated bytecode is loaded in, your program is ready to run,
794reducing the time which perl would have taken to load and parse
795your program into its internal semi-compiled form. That means that
796compiling with this backend will not help improve the runtime
797execution speed of your program but may improve the start-up time.
798Depending on the environment in which your program runs this may
799or may not be a help.
800
801The resulting bytecode can be run with a special byteperl executable
802or (for non-main programs) be loaded via the C<byteload_fh> function
803in the F<B> module.
804
805=head1 OPTIONS
806
807If there are any non-option arguments, they are taken to be names of
808objects to be saved (probably doesn't work properly yet). Without
809extra arguments, it saves the main program.
810
811=over 4
812
813=item B<-ofilename>
814
815Output to filename instead of STDOUT.
816
817=item B<-->
818
819Force end of options.
820
821=item B<-f>
822
823Force optimisations on or off one at a time. Each can be preceded
824by B<no-> to turn the option off (e.g. B<-fno-compress-nullops>).
825
826=item B<-fcompress-nullops>
827
828Only fills in the necessary fields of ops which have
829been optimised away by perl's internal compiler.
830
831=item B<-fomit-sequence-numbers>
832
833Leaves out code to fill in the op_seq field of all ops
834which is only used by perl's internal compiler.
835
836=item B<-fbypass-nullops>
837
838If op->op_next ever points to a NULLOP, replaces the op_next field
839with the first non-NULLOP in the path of execution.
840
841=item B<-fstrip-syntax-tree>
842
843Leaves out code to fill in the pointers which link the internal syntax
844tree together. They're not needed at run-time but leaving them out
845will make it impossible to recompile or disassemble the resulting
846program. It will also stop C<goto label> statements from working.
847
848=item B<-On>
849
850Optimisation level (n = 0, 1, 2, ...). B<-O> means B<-O1>.
851B<-O1> sets B<-fcompress-nullops> B<-fomit-sequence numbers>.
852B<-O6> adds B<-fstrip-syntax-tree>.
853
854=item B<-D>
855
856Debug options (concatenated or separate flags like C<perl -D>).
857
858=item B<-Do>
859
860Prints each OP as it's processed.
861
862=item B<-Db>
863
864Print debugging information about bytecompiler progress.
865
866=item B<-Da>
867
868Tells the (bytecode) assembler to include source assembler lines
869in its output as bytecode comments.
870
871=item B<-DC>
872
873Prints each CV taken from the final symbol tree walk.
874
875=item B<-S>
876
877Output (bytecode) assembler source rather than piping it
878through the assembler and outputting bytecode.
879
880=item B<-m>
881
882Compile as a module rather than a standalone program. Currently this
883just means that the bytecodes for initialising C<main_start>,
884C<main_root> and C<curpad> are omitted.
885
886=back
887
707102d0 888=head1 EXAMPLES
1a52ab62 889
e8edd1e6 890 perl -MO=Bytecode,-O6,-o,foo.plc foo.pl
1a52ab62 891
e8edd1e6 892 perl -MO=Bytecode,-S foo.pl > foo.S
893 assemble foo.S > foo.plc
1a52ab62 894
e8edd1e6 895Note that C<assemble> lives in the C<B> subdirectory of your perl
896library directory. The utility called perlcc may also be used to
897help make use of this compiler.
898
899 perl -MO=Bytecode,-m,-oFoo.pmc Foo.pm
1a52ab62 900
901=head1 BUGS
902
903Plenty. Current status: experimental.
7f20e9dd 904
905=head1 AUTHOR
906
907Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>
908
909=cut