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