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