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