Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / 5.8.0 / sun4-solaris / B / Bytecode.pm
CommitLineData
86530b38
AT
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;
9
10our $VERSION = '1.00';
11
12use strict;
13use Carp;
14use B qw(main_cv main_root main_start comppadlist
15 class peekop walkoptree svref_2object cstring walksymtable
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
20 );
21use B::Asmdata qw(@optype @specialsv_name);
22use B::Assembler qw(newasm endasm assemble);
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
32sub POK () { SVf_POK|SVp_POK }
33
34# Following is SVf_IOK|SVp_IOK
35# XXX Shouldn't be hardwired
36sub IOK () { SVf_IOK|SVp_IOK }
37
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}
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.
71my ($compress_nullops, $omit_seq, $bypass_nullops);
72my %optimise = (compress_nullops => \$compress_nullops,
73 omit_sequence_numbers => \$omit_seq,
74 bypass_nullops => \$bypass_nullops);
75
76my $strip_syntree; # this is left here in case stripping the
77 # syntree ever becomes safe again
78 # -- BKS, June 2000
79
80my $nextix = 0;
81my %symtable; # maps object addresses to object indices.
82 # Filled in at allocation (newsv/newop) time.
83
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
88my %strtable; # maps shared strings to object indices
89 # Filled in at allocation (pvix) time
90
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.
94
95my $opix = -1; # Ditto for the op register.
96
97sub ldsv {
98 my $ix = shift;
99 if ($ix != $svix) {
100 asm "ldsv $ix\n";
101 $svix = $ix;
102 }
103}
104
105sub stsv {
106 my $ix = shift;
107 asm "stsv $ix\n";
108 $svix = $ix;
109}
110
111sub set_svix {
112 $svix = shift;
113}
114
115sub ldop {
116 my $ix = shift;
117 if ($ix != $opix) {
118 asm "ldop $ix\n";
119 $opix = $ix;
120 }
121}
122
123sub stop {
124 my $ix = shift;
125 asm "stop $ix\n";
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
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
150sub saved { $saved{${$_[0]}} }
151sub mark_saved { $saved{${$_[0]}} = 1 }
152sub unmark_saved { $saved{${$_[0]}} = 0 }
153
154sub debug { $debug_bc = shift }
155
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
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) = @_;
188 asmf "newsv %d\t# %s\n", $sv->FLAGS & SVTYPEMASK, class($sv);
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);
196 asm "gv_fetchpv $name\n";
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
205 asmf "gv_stashpv %s\n", cstring($name);
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.
217 asmf "ldspecsv $$sv\t# %s\n", $specialsv_name[$$sv];
218 stsv($ix);
219}
220
221sub B::OP::newix {
222 my ($op, $ix) = @_;
223 my $class = class($op);
224 my $typenum = $optype_enum{$class};
225 croak("OP::newix: can't understand class $class") unless defined($typenum);
226 asm "newop $typenum\t# $class\n";
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;
239 my $sibix = $op->sibling->objix unless $strip_syntree;
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
248 asmf "# %s\n", peekop($op) if $debug_bc;
249 ldop($ix);
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;
254 if ($type || !$compress_nullops) {
255 asmf "op_targ %d\nop_flags 0x%x\nop_private 0x%x\n",
256 $op->targ, $op->flags, $op->private;
257 }
258}
259
260sub B::UNOP::bytecode {
261 my $op = shift;
262 my $firstix = $op->first->objix unless $strip_syntree;
263 $op->B::OP::bytecode;
264 if (($op->type || !$compress_nullops) && !$strip_syntree) {
265 asm "op_first $firstix\n";
266 }
267}
268
269sub B::LOGOP::bytecode {
270 my $op = shift;
271 my $otherix = $op->other->objix;
272 $op->B::UNOP::bytecode;
273 asm "op_other $otherix\n";
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;
281 asm "op_sv $svix\n";
282 $sv->bytecode;
283}
284
285sub B::PADOP::bytecode {
286 my $op = shift;
287 my $padix = $op->padix;
288 $op->B::OP::bytecode;
289 asm "op_padix $padix\n";
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 #
300 if ($op->name eq "trans") {
301 my @shorts = unpack("s256", $pv); # assembler handles endianness
302 asm "op_pv_tr ", join(",", @shorts), "\n";
303 } else {
304 asmf "newpv %s\nop_pv\n", pvstring($pv);
305 }
306}
307
308sub B::BINOP::bytecode {
309 my $op = shift;
310 my $lastix = $op->last->objix unless $strip_syntree;
311 $op->B::UNOP::bytecode;
312 if (($op->type || !$compress_nullops) && !$strip_syntree) {
313 asm "op_last $lastix\n";
314 }
315}
316
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;
323 asm "op_redoop $redoopix\nop_nextop $nextopix\nop_lastop $lastopix\n";
324}
325
326sub B::COP::bytecode {
327 my $op = shift;
328 my $file = $op->file;
329 my $line = $op->line;
330 if ($debug_bc) { # do this early to aid debugging
331 asmf "# line %s:%d\n", $file, $line;
332 }
333 my $stashpv = $op->stashpv;
334 my $warnings = $op->warnings;
335 my $warningsix = $warnings->objix;
336 my $labelix = pvix($op->label);
337 my $stashix = pvix($stashpv);
338 my $fileix = pvix($file);
339 $warnings->bytecode;
340 $op->B::OP::bytecode;
341 asmf <<"EOT", $labelix, $stashix, $op->cop_seq, $fileix, $op->arybase;
342cop_label %d
343cop_stashpv %d
344cop_seq %d
345cop_file %d
346cop_arybase %d
347cop_line $line
348cop_warnings $warningsix
349EOT
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;
357 my $opname = $op->name;
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...
365 if ($opname eq "pushre") {
366 $replroot->bytecode;
367 } else {
368 walkoptree($replroot, "bytecode");
369 }
370 }
371 $op->B::LISTOP::bytecode;
372 if ($opname eq "pushre") {
373 asmf "op_pmreplrootgv $replrootix\n";
374 } else {
375 asm "op_pmreplroot $replrootix\nop_pmreplstart $replstartix\n";
376 }
377 my $re = pvstring($op->precomp);
378 # op_pmnext omitted since a perl bug means it's sometime corrupt
379 asmf <<"EOT", $op->pmflags, $op->pmpermflags;
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);
394 asm "sv_refcnt $refcnt\nsv_flags $flags\n";
395 mark_saved($sv);
396}
397
398sub B::PV::bytecode {
399 my $sv = shift;
400 return if saved($sv);
401 $sv->B::SV::bytecode;
402 asmf("newpv %s\nxpv\n", pvstring($sv->PV)) if $sv->FLAGS & POK;
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;
410 asmf "%s $iv\n", $sv->needs64bits ? "xiv64" : "xiv32" if $sv->FLAGS & IOK; # could be PVNV
411}
412
413sub B::NV::bytecode {
414 my $sv = shift;
415 return if saved($sv);
416 $sv->B::SV::bytecode;
417 asmf "xnv %s\n", nv($sv->NVX);
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;
427 asm "xrv $rvix\n";
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;
435 asmf "%s $iv\n", $sv->needs64bits ? "xiv64" : "xiv32";
436}
437
438sub B::PVNV::bytecode {
439 my $sv = shift;
440 my $flag = shift || 0;
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;
455 asmf "xnv %s\n", nv($sv->NVX);
456 if ($flag == 1) {
457 $pv .= "\0" . $sv->TABLE;
458 asmf "newpv %s\npv_cur %d\nxpv\n", pvstring($pv),length($pv)-257;
459 } else {
460 asmf("newpv %s\nxpv\n", pvstring($pv)) if $sv->FLAGS & POK;
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);
482 asm "xmg_stash $stashix\n";
483 foreach $mg (@mgchain) {
484 asmf "sv_magic %s\nmg_obj %d\nnewpv %s\nmg_pv\n",
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;
493 asmf <<'EOT', $sv->TARGOFF, $sv->TARGLEN, cstring($sv->TYPE);
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);
505 asmf "xbm_useful %d\nxbm_previous %d\nxbm_rare %d\n",
506 $sv->USEFUL, $sv->PREVIOUS, $sv->RARE;
507}
508
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
521sub B::GV::bytecode {
522 my $gv = shift;
523 return if saved($gv);
524 return unless grep { $_ eq $gv->STASH->NAME; } @packages;
525 return if $gv->NAME =~ m/^\(/; # ignore overloads - they'll be rebuilt
526 my $ix = $gv->objix;
527 mark_saved($gv);
528 ldsv($ix);
529 asmf <<"EOT", $gv->FLAGS, $gv->GvFLAGS;
530sv_flags 0x%x
531xgv_flags 0x%x
532EOT
533 my $refcnt = $gv->REFCNT;
534 asmf("sv_refcnt_add %d\n", $refcnt - 1) if $refcnt > 1;
535 return if $gv->is_empty;
536 asmf <<"EOT", $gv->LINE, pvix($gv->FILE);
537gp_line %d
538gp_file %d
539EOT
540 my $gvname = $gv->NAME;
541 my $name = cstring($gv->STASH->NAME . "::" . $gvname);
542 my $egv = $gv->EGV;
543 my $egvix = $egv->objix;
544 my $gvrefcnt = $gv->GvREFCNT;
545 asmf("gp_refcnt_add %d\n", $gvrefcnt - 1) if $gvrefcnt > 1;
546 if ($gvrefcnt > 1 && $ix != $egvix) {
547 asm "gp_share $egvix\n";
548 } else {
549 if ($gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/) {
550 my $i;
551 my @subfield_names = qw(SV AV HV CV FORM IO);
552 @subfield_names = grep {;
553 no strict 'refs';
554 !($gv->GvFLAGS & ${\"GVf_IMPORTED_$_"}->());
555 } @subfield_names;
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++) {
561 asmf "gp_%s %d\n", lc($subfield_names[$i]), $ixes[$i];
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) {
591 asmf("newpv %s\nhv_store %d\n",
592 pvstring($contents[$i]), $ixes[$i / 2]);
593 }
594 asmf "sv_refcnt %d\nsv_flags 0x%x\n", $hv->REFCNT, $hv->FLAGS;
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);
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;
621 if ($fill > -1) {
622 my $elix;
623 foreach $elix (@ixes) {
624 asm "av_push $elix\n";
625 }
626 } else {
627 if ($max > -1) {
628 asm "av_extend $max\n";
629 }
630 }
631 asmf "sv_flags 0x%x\n", $av->FLAGS; # restore flags from above
632}
633
634sub B::CV::bytecode {
635 my $cv = shift;
636 return if saved($cv);
637 return if ${$cv->GV} && ($cv->GV->GvFLAGS & GVf_IMPORTED_CV);
638 my $fileix = pvix($cv->FILE);
639 my $ix = $cv->objix;
640 $cv->B::PVMG::bytecode;
641 my $i;
642 my @subfield_names = qw(ROOT START STASH GV PADLIST OUTSIDE);
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++) {
653 asmf "xcv_%s %d\n", lc($subfield_names[$i]), $ixes[$i];
654 }
655 asmf "xcv_depth %d\nxcv_flags 0x%x\n", $cv->DEPTH, $cv->CvFLAGS;
656 asmf "xcv_file %d\n", $fileix;
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);
679 asm "xio_top_gv $top_gvix\n";
680 asm "xio_fmt_gv $fmt_gvix\n";
681 asm "xio_bottom_gv $bottom_gvix\n";
682 my $field;
683 foreach $field (qw(TOP_NAME FMT_NAME BOTTOM_NAME)) {
684 asmf "newpv %s\nxio_%s\n", pvstring($io->$field()), lc($field);
685 }
686 foreach $field (qw(LINES PAGE PAGE_LEN LINES_LEFT SUBPROCESS)) {
687 asmf "xio_%s %d\n", lc($field), $io->$field();
688 }
689 asmf "xio_type %s\nxio_flags 0x%x\n", cstring($io->IoTYPE), $io->IoFLAGS;
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 {
700 for my $sv (@_) {
701 svref_2object($sv)->bytecode;
702 }
703}
704
705sub B::GV::bytecodecv {
706 my $gv = shift;
707 my $cv = $gv->CV;
708 if ($$cv && !saved($cv) && !($gv->FLAGS & GVf_IMPORTED_CV)) {
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
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 }
732 }
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 }
746 }
747}
748
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;
758}
759
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?
777}
778
779sub compile {
780 my @options = @_;
781 my ($option, $opt, $arg);
782 open(OUT, ">&STDOUT");
783 binmode OUT;
784 select OUT;
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;
801 } elsif ($opt eq "a") {
802 $arg ||= shift @options;
803 open(OUT, ">>$arg") or return "$arg: $!\n";
804 binmode OUT;
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;
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 }
839 if ($arg >= 2) {
840 $bypass_nullops = 1;
841 }
842 if ($arg >= 1) {
843 $compress_nullops = 1;
844 $omit_seq = 1;
845 }
846 } elsif ($opt eq "u") {
847 $arg ||= shift @options;
848 push @packages, $arg;
849 } else {
850 warn qq(ignoring unknown option "$opt$arg"\n);
851 }
852 }
853 if (! @packages) {
854 warn "No package specified for compilation, assuming main::\n";
855 @packages = qw(main);
856 }
857 if (@options) {
858 die "Extraneous options left on B::Bytecode commandline: @options\n";
859 } else {
860 return sub {
861 newasm(\&apr) unless $no_assemble;
862 bytecompile_main();
863 endasm() unless $no_assemble;
864 };
865 }
866}
867
868sub apr { print @_; }
869
8701;
871
872__END__
873
874=head1 NAME
875
876B::Bytecode - Perl compiler's bytecode backend
877
878=head1 SYNOPSIS
879
880 perl -MO=Bytecode[,OPTIONS] foo.pl
881
882=head1 DESCRIPTION
883
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
911=item B<-afilename>
912
913Append output to filename.
914
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
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>.
943B<-O2> adds B<-fbypass-nullops>.
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
971=item B<-upackage>
972
973Stores package in the output.
974
975=back
976
977=head1 EXAMPLES
978
979 perl -MO=Bytecode,-O6,-ofoo.plc,-umain foo.pl
980
981 perl -MO=Bytecode,-S,-umain foo.pl > foo.S
982 assemble foo.S > foo.plc
983
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
988 perl -MO=Bytecode,-uFoo,-oFoo.pmc Foo.pm
989
990=head1 BUGS
991
992Output is still huge and there are still occasional crashes during
993either compilation or ByteLoading. Current status: experimental.
994
995=head1 AUTHORS
996
997Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>
998Benjamin Stuhl, C<sho_pi@hotmail.com>
999
1000=cut