3 # Copyright (c) 1996, 1997, 1998 Malcolm Beattie
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.
11 our $VERSION = '1.04';
13 package B::C::Section;
21 my $o = $class->SUPER::new(@_);
22 push @$o, { values => [] };
29 push(@{$section->[-1]{values}},@_);
35 return scalar(@{$section->[-1]{values}})-1;
40 my ($section, $fh, $format) = @_;
41 my $sym = $section->symtable || {};
42 my $default = $section->default;
44 foreach (@{$section->[-1]{values}})
46 s{(s\\_[0-9a-f]+)}{ exists($sym->{$1}) ? $sym->{$1} : $default; }ge;
47 printf $fh $format, $_, $i;
52 package B::C::InitSection;
55 @B::C::InitSection::ISA = qw(B::C::Section);
59 my $max_lines = 10000; #pop;
60 my $section = $class->SUPER::new( @_ );
62 $section->[-1]{evals} = [];
63 $section->[-1]{chunks} = [];
64 $section->[-1]{nosplit} = 0;
65 $section->[-1]{current} = [];
66 $section->[-1]{count} = 0;
67 $section->[-1]{max_lines} = $max_lines;
74 $section->[-1]{nosplit}--
75 if $section->[-1]{nosplit} > 0;
79 shift->[-1]{nosplit}++;
85 $section->[-1]{count} += $_[0];
91 my $section = shift->[-1];
92 my $current = $section->{current};
93 my $nosplit = $section->{nosplit};
96 $section->{count} += scalar(@_);
97 if( !$nosplit && $section->{count} >= $section->{max_lines} ) {
98 push @{$section->{chunks}}, $current;
99 $section->{current} = [];
100 $section->{count} = 0;
108 foreach my $i ( @strings ) {
111 push @{$section->[-1]{evals}}, @strings;
115 my( $section, $fh, $format, $init_name ) = @_;
116 my $sym = $section->symtable || {};
117 my $default = $section->default;
118 push @{$section->[-1]{chunks}}, $section->[-1]{current};
121 foreach my $i ( @{$section->[-1]{chunks}} ) {
123 static int perl_init_${name}()
128 foreach my $j ( @$i ) {
129 $j =~ s{(s\\_[0-9a-f]+)}
130 { exists($sym->{$1}) ? $sym->{$1} : $default; }ge;
133 print $fh "\treturn 0;\n}\n";
135 $section->SUPER::add( "perl_init_${name}();" );
138 foreach my $i ( @{$section->[-1]{evals}} ) {
139 $section->SUPER::add( sprintf q{eval_pv("%s",1);}, $i );
143 static int ${init_name}()
148 $section->SUPER::output( $fh, $format );
149 print $fh "\treturn 0;\n}\n";
157 { # block necessary for caller to work
159 if( $caller eq 'O' ) {
161 XSLoader::load( 'B::C' );
166 @EXPORT_OK = qw(output_all output_boilerplate output_main mark_unused
167 init_sections set_callback save_unused_subs objsym save_context);
169 use B qw(minus_c sv_undef walkoptree walksymtable main_root main_start peekop
170 class cstring cchar svref_2object compile_stats comppadlist hash
171 threadsv_names main_cv init_av end_av regex_padav opnumber amagic_generation
172 HEf_SVKEY SVf_POK SVf_ROK CVf_CONST);
173 use B::Asmdata qw(@specialsv_name);
185 my $anonsub_index = 0;
186 my $initsub_index = 0;
190 my $warn_undefined_syms;
192 my %unused_sub_packages;
195 my $pv_copy_on_grow = 0;
196 my $optimize_ppaddr = 0;
197 my $optimize_warn_sv = 0;
198 my $use_perl_script_name = 0;
199 my $save_data_fh = 0;
201 my ($debug_cops, $debug_av, $debug_cv, $debug_mg);
204 my $ithreads = $Config{useithreads} eq 'define';
208 @threadsv_names = threadsv_names();
212 my ($init, $decl, $symsect, $binopsect, $condopsect, $copsect,
213 $padopsect, $listopsect, $logopsect, $loopsect, $opsect, $pmopsect,
214 $pvopsect, $svopsect, $unopsect, $svsect, $xpvsect, $xpvavsect,
215 $xpvhvsect, $xpvcvsect, $xpvivsect, $xpvnvsect, $xpvmgsect, $xpvlvsect,
216 $xrvsect, $xpvbmsect, $xpviosect );
217 my @op_sections = \( $binopsect, $condopsect, $copsect, $padopsect, $listopsect,
218 $logopsect, $loopsect, $opsect, $pmopsect, $pvopsect, $svopsect,
221 sub walk_and_save_optree;
222 my $saveoptree_callback = \&walk_and_save_optree;
223 sub set_callback { $saveoptree_callback = shift }
224 sub saveoptree { &$saveoptree_callback(@_) }
226 sub walk_and_save_optree {
227 my ($name, $root, $start) = @_;
228 walkoptree($root, "save");
229 return objsym($start);
232 # Look this up here so we can do just a number compare
233 # rather than looking up the name of every BASEOP in B::OP
234 my $OP_THREADSV = opnumber('threadsv');
237 my ($obj, $value) = @_;
238 my $sym = sprintf("s\\_%x", $$obj);
239 $symtable{$sym} = $value;
244 return $symtable{sprintf("s\\_%x", $$obj)};
251 return 0 if $sym eq "sym_0"; # special case
252 $value = $symtable{$sym};
253 if (defined($value)) {
256 warn "warning: undefined symbol $sym\n" if $warn_undefined_syms;
263 my $sym = sprintf("re%d", $re_index++);
264 $decl->add(sprintf("static char *$sym = %s;", cstring($re)));
266 return ($sym,length(pack "a*",$re));
270 my $pv = pack "a*", shift;
273 if ($pv_copy_on_grow) {
274 $pvsym = sprintf("pv%d", $pv_index++);
276 if( defined $max_string_len && length($pv) > $max_string_len ) {
277 my $chars = join ', ', map { cchar $_ } split //, $pv;
278 $decl->add(sprintf("static char %s[] = { %s };", $pvsym, $chars));
281 my $cstring = cstring($pv);
282 if ($cstring ne "0") { # sic
283 $decl->add(sprintf("static char %s[] = %s;",
288 $pvmax = length(pack "a*",$pv) + 1;
290 return ($pvsym, $pvmax);
295 # confess "Can't save RV: not ROK" unless $sv->FLAGS & SVf_ROK;
296 my $rv = $sv->RV->save;
298 $rv =~ s/^\(([AGHS]V|IO)\s*\*\)\s*(\&sv_list.*)$/$2/;
303 # savesym, pvmax, len, pv
307 my $rok = $sv->FLAGS & SVf_ROK;
308 my $pok = $sv->FLAGS & SVf_POK;
309 my( $len, $pvmax, $savesym, $pv ) = ( 0, 0 );
311 $savesym = '(char*)' . save_rv( $sv );
314 $pv = $pok ? (pack "a*", $sv->PV) : undef;
315 $len = $pok ? length($pv) : 0;
316 ($savesym, $pvmax) = $pok ? savepv($pv) : ( 'NULL', 0 );
319 return ( $savesym, $pvmax, $len, $pv );
322 # see also init_op_ppaddr below; initializes the ppaddt to the
323 # OpTYPE; init_op_ppaddr iterates over the ops and sets
324 # op_ppaddr to PL_ppaddr[op_ppaddr]; this avoids an explicit assignmente
325 # in perl_init ( ~10 bytes/op with GCC/i386 )
326 sub B::OP::fake_ppaddr {
327 return $optimize_ppaddr ?
328 sprintf("INT2PTR(void*,OP_%s)", uc( $_[0]->name ) ) :
332 # This pair is needed becase B::FAKEOP::save doesn't scalar dereference
333 # $op->next and $op->sibling
336 # For 5.9 the hard coded text is the values for op_opt and op_static in each
337 # op. The value of op_opt is irrelevant, and the value of op_static needs to
338 # be 1 to tell op_free that this is a statically defined op and that is
339 # shouldn't be freed.
342 # Current workaround/fix for op_free() trying to free statically
343 # defined OPs is to set op_seq = -1 and check for that in op_free().
344 # Instead of hardwiring -1 in place of $op->seq, we use $op_seq
345 # so that it can be changed back easily if necessary. In fact, to
346 # stop compilers from moaning about a U16 being initialised with an
347 # uncast -1 (the printf format is %d so we can't tweak it), we have
348 # to "know" that op_seq is a U16 and use 65535. Ugh.
350 my $static = $] > 5.009 ? '0, 1, 0' : sprintf "%u", 65535;
351 sub B::OP::_save_common_middle {
353 sprintf ("%s, %u, %u, $static, 0x%x, 0x%x",
354 $op->fake_ppaddr, $op->targ, $op->type, $op->flags, $op->private);
358 sub B::OP::_save_common {
360 return sprintf("s\\_%x, s\\_%x, %s",
361 ${$op->next}, ${$op->sibling}, $op->_save_common_middle);
365 my ($op, $level) = @_;
366 my $sym = objsym($op);
367 return $sym if defined $sym;
368 my $type = $op->type;
369 $nullop_count++ unless $type;
370 if ($type == $OP_THREADSV) {
371 # saves looking up ppaddr but it's a bit naughty to hard code this
372 $init->add(sprintf("(void)find_threadsv(%s);",
373 cstring($threadsv_names[$op->targ])));
375 $opsect->add($op->_save_common);
376 my $ix = $opsect->index;
377 $init->add(sprintf("op_list[$ix].op_ppaddr = %s;", $op->ppaddr))
378 unless $optimize_ppaddr;
379 savesym($op, "&op_list[$ix]");
383 my ($class, %objdata) = @_;
384 bless \%objdata, $class;
387 sub B::FAKEOP::save {
388 my ($op, $level) = @_;
389 $opsect->add(sprintf("%s, %s, %s",
390 $op->next, $op->sibling, $op->_save_common_middle));
391 my $ix = $opsect->index;
392 $init->add(sprintf("op_list[$ix].op_ppaddr = %s;", $op->ppaddr))
393 unless $optimize_ppaddr;
394 return "&op_list[$ix]";
397 sub B::FAKEOP::next { $_[0]->{"next"} || 0 }
398 sub B::FAKEOP::type { $_[0]->{type} || 0}
399 sub B::FAKEOP::sibling { $_[0]->{sibling} || 0 }
400 sub B::FAKEOP::ppaddr { $_[0]->{ppaddr} || 0 }
401 sub B::FAKEOP::targ { $_[0]->{targ} || 0 }
402 sub B::FAKEOP::flags { $_[0]->{flags} || 0 }
403 sub B::FAKEOP::private { $_[0]->{private} || 0 }
406 my ($op, $level) = @_;
407 my $sym = objsym($op);
408 return $sym if defined $sym;
409 $unopsect->add(sprintf("%s, s\\_%x", $op->_save_common, ${$op->first}));
410 my $ix = $unopsect->index;
411 $init->add(sprintf("unop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
412 unless $optimize_ppaddr;
413 savesym($op, "(OP*)&unop_list[$ix]");
417 my ($op, $level) = @_;
418 my $sym = objsym($op);
419 return $sym if defined $sym;
420 $binopsect->add(sprintf("%s, s\\_%x, s\\_%x",
421 $op->_save_common, ${$op->first}, ${$op->last}));
422 my $ix = $binopsect->index;
423 $init->add(sprintf("binop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
424 unless $optimize_ppaddr;
425 savesym($op, "(OP*)&binop_list[$ix]");
428 sub B::LISTOP::save {
429 my ($op, $level) = @_;
430 my $sym = objsym($op);
431 return $sym if defined $sym;
432 $listopsect->add(sprintf("%s, s\\_%x, s\\_%x",
433 $op->_save_common, ${$op->first}, ${$op->last}));
434 my $ix = $listopsect->index;
435 $init->add(sprintf("listop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
436 unless $optimize_ppaddr;
437 savesym($op, "(OP*)&listop_list[$ix]");
441 my ($op, $level) = @_;
442 my $sym = objsym($op);
443 return $sym if defined $sym;
444 $logopsect->add(sprintf("%s, s\\_%x, s\\_%x",
445 $op->_save_common, ${$op->first}, ${$op->other}));
446 my $ix = $logopsect->index;
447 $init->add(sprintf("logop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
448 unless $optimize_ppaddr;
449 savesym($op, "(OP*)&logop_list[$ix]");
453 my ($op, $level) = @_;
454 my $sym = objsym($op);
455 return $sym if defined $sym;
456 #warn sprintf("LOOP: redoop %s, nextop %s, lastop %s\n",
457 # peekop($op->redoop), peekop($op->nextop),
458 # peekop($op->lastop)); # debug
459 $loopsect->add(sprintf("%s, s\\_%x, s\\_%x, s\\_%x, s\\_%x, s\\_%x",
460 $op->_save_common, ${$op->first}, ${$op->last},
461 ${$op->redoop}, ${$op->nextop},
463 my $ix = $loopsect->index;
464 $init->add(sprintf("loop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
465 unless $optimize_ppaddr;
466 savesym($op, "(OP*)&loop_list[$ix]");
470 my ($op, $level) = @_;
471 my $sym = objsym($op);
472 return $sym if defined $sym;
473 $pvopsect->add(sprintf("%s, %s", $op->_save_common, cstring($op->pv)));
474 my $ix = $pvopsect->index;
475 $init->add(sprintf("pvop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
476 unless $optimize_ppaddr;
477 savesym($op, "(OP*)&pvop_list[$ix]");
481 my ($op, $level) = @_;
482 my $sym = objsym($op);
483 return $sym if defined $sym;
485 my $svsym = '(SV*)' . $sv->save;
486 my $is_const_addr = $svsym =~ m/Null|\&/;
487 $svopsect->add(sprintf("%s, %s", $op->_save_common,
488 ( $is_const_addr ? $svsym : 'Nullsv' )));
489 my $ix = $svopsect->index;
490 $init->add(sprintf("svop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
491 unless $optimize_ppaddr;
492 $init->add("svop_list[$ix].op_sv = $svsym;")
493 unless $is_const_addr;
494 savesym($op, "(OP*)&svop_list[$ix]");
498 my ($op, $level) = @_;
499 my $sym = objsym($op);
500 return $sym if defined $sym;
501 $padopsect->add(sprintf("%s, %d",
502 $op->_save_common, $op->padix));
503 my $ix = $padopsect->index;
504 $init->add(sprintf("padop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
505 unless $optimize_ppaddr;
506 # $init->add(sprintf("padop_list[$ix].op_padix = %ld;", $op->padix));
507 savesym($op, "(OP*)&padop_list[$ix]");
511 my ($op, $level) = @_;
512 my $sym = objsym($op);
513 return $sym if defined $sym;
514 warn sprintf("COP: line %d file %s\n", $op->line, $op->file)
516 # shameless cut'n'paste from B::Deparse
518 my $warnings = $op->warnings;
519 my $is_special = $warnings->isa("B::SPECIAL");
520 if ($is_special && $$warnings == 4) {
521 # use warnings 'all';
522 $warn_sv = $optimize_warn_sv ?
526 elsif ($is_special && $$warnings == 5) {
528 $warn_sv = $optimize_warn_sv ?
532 elsif ($is_special) {
534 $warn_sv = $optimize_warn_sv ?
540 $warn_sv = $warnings->save;
543 $copsect->add(sprintf("%s, %s, NULL, NULL, %u, %d, %u, %s",
544 $op->_save_common, cstring($op->label), $op->cop_seq,
545 $op->arybase, $op->line,
546 ( $optimize_warn_sv ? $warn_sv : 'NULL' )));
547 my $ix = $copsect->index;
548 $init->add(sprintf("cop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
549 unless $optimize_ppaddr;
550 $init->add(sprintf("cop_list[$ix].cop_warnings = %s;", $warn_sv ))
551 unless $optimize_warn_sv;
552 $init->add(sprintf("CopFILE_set(&cop_list[$ix], %s);", cstring($op->file)),
553 sprintf("CopSTASHPV_set(&cop_list[$ix], %s);", cstring($op->stashpv)));
555 savesym($op, "(OP*)&cop_list[$ix]");
559 my ($op, $level) = @_;
560 my $sym = objsym($op);
561 return $sym if defined $sym;
562 my $replroot = $op->pmreplroot;
563 my $replstart = $op->pmreplstart;
565 my $replstartfield = sprintf("s\\_%x", $$replstart);
567 my $ppaddr = $op->ppaddr;
568 # under ithreads, OP_PUSHRE.op_replroot is an integer
569 $replrootfield = sprintf("s\\_%x", $$replroot) if ref $replroot;
570 if($ithreads && $op->name eq "pushre") {
571 $replrootfield = "INT2PTR(OP*,${replroot})";
572 } elsif ($$replroot) {
573 # OP_PUSHRE (a mutated version of OP_MATCH for the regexp
574 # argument to a split) stores a GV in op_pmreplroot instead
575 # of a substitution syntax tree. We don't want to walk that...
576 if ($op->name eq "pushre") {
577 $gvsym = $replroot->save;
578 # warn "PMOP::save saving a pp_pushre with GV $gvsym\n"; # debug
581 $replstartfield = saveoptree("*ignore*", $replroot, $replstart);
584 # pmnext handling is broken in perl itself, I think. Bad op_pmnext
585 # fields aren't noticed in perl's runtime (unless you try reset) but we
586 # segfault when trying to dereference it to find op->op_pmnext->op_type
587 $pmopsect->add(sprintf("%s, s\\_%x, s\\_%x, %s, %s, 0, %u, 0x%x, 0x%x, 0x%x",
588 $op->_save_common, ${$op->first}, ${$op->last},
589 $replrootfield, $replstartfield,
590 ( $ithreads ? $op->pmoffset : 0 ),
591 $op->pmflags, $op->pmpermflags, $op->pmdynflags ));
592 my $pm = sprintf("pmop_list[%d]", $pmopsect->index);
593 $init->add(sprintf("$pm.op_ppaddr = %s;", $ppaddr))
594 unless $optimize_ppaddr;
595 my $re = $op->precomp;
597 my( $resym, $relen ) = savere( $re );
598 $init->add(sprintf("PM_SETRE(&$pm,pregcomp($resym, $resym + %u, &$pm));",
602 $init->add("$pm.op_pmreplroot = (OP*)$gvsym;");
604 savesym($op, "(OP*)&$pm");
607 sub B::SPECIAL::save {
609 # special case: $$sv is not the address but an index into specialsv_list
610 # warn "SPECIAL::save specialsv $$sv\n"; # debug
611 my $sym = $specialsv_name[$$sv];
612 if (!defined($sym)) {
613 confess "unknown specialsv index $$sv passed to B::SPECIAL::save";
618 sub B::OBJECT::save {}
622 my $sym = objsym($sv);
623 return $sym if defined $sym;
624 # warn "Saving SVt_NULL SV\n"; # debug
627 warn "NULL::save for sv = 0 called from @{[(caller(1))[3]]}\n";
628 return savesym($sv, "(void*)Nullsv /* XXX */");
630 $svsect->add(sprintf("0, %u, 0x%x", $sv->REFCNT , $sv->FLAGS));
631 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
636 my $sym = objsym($sv);
637 return $sym if defined $sym;
638 $xpvivsect->add(sprintf("0, 0, 0, %d", $sv->IVX));
639 $svsect->add(sprintf("&xpviv_list[%d], %lu, 0x%x",
640 $xpvivsect->index, $sv->REFCNT , $sv->FLAGS));
641 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
646 my $sym = objsym($sv);
647 return $sym if defined $sym;
649 $val .= '.00' if $val =~ /^-?\d+$/;
650 $xpvnvsect->add(sprintf("0, 0, 0, %d, %s", $sv->IVX, $val));
651 $svsect->add(sprintf("&xpvnv_list[%d], %lu, 0x%x",
652 $xpvnvsect->index, $sv->REFCNT , $sv->FLAGS));
653 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
659 # work with byte offsets/lengths
660 my $pv = pack "a*", $pv;
661 if (defined $max_string_len && length($pv) > $max_string_len) {
662 push @res, sprintf("Newx(%s,%u,char);", $dest, length($pv)+1);
665 my $str = substr $pv, 0, $max_string_len, '';
666 push @res, sprintf("Copy(%s,$dest+$offset,%u,char);",
667 cstring($str), length($str));
668 $offset += length $str;
670 push @res, sprintf("%s[%u] = '\\0';", $dest, $offset);
673 push @res, sprintf("%s = savepvn(%s, %u);", $dest,
674 cstring($pv), length($pv));
681 my $sym = objsym($sv);
682 return $sym if defined $sym;
684 my $len = length($pv);
685 my ($pvsym, $pvmax) = savepv($pv);
686 my ($lvtarg, $lvtarg_sym);
687 $xpvlvsect->add(sprintf("%s, %u, %u, %d, %g, 0, 0, %u, %u, 0, %s",
688 $pvsym, $len, $pvmax, $sv->IVX, $sv->NVX,
689 $sv->TARGOFF, $sv->TARGLEN, cchar($sv->TYPE)));
690 $svsect->add(sprintf("&xpvlv_list[%d], %lu, 0x%x",
691 $xpvlvsect->index, $sv->REFCNT , $sv->FLAGS));
692 if (!$pv_copy_on_grow) {
693 $init->add(savepvn(sprintf("xpvlv_list[%d].xpv_pv",
694 $xpvlvsect->index), $pv));
697 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
702 my $sym = objsym($sv);
703 return $sym if defined $sym;
704 my( $savesym, $pvmax, $len, $pv ) = save_pv_or_rv( $sv );
705 $xpvivsect->add(sprintf("%s, %u, %u, %d", $savesym, $len, $pvmax, $sv->IVX));
706 $svsect->add(sprintf("&xpviv_list[%d], %u, 0x%x",
707 $xpvivsect->index, $sv->REFCNT , $sv->FLAGS));
708 if (defined($pv) && !$pv_copy_on_grow) {
709 $init->add(savepvn(sprintf("xpviv_list[%d].xpv_pv",
710 $xpvivsect->index), $pv));
712 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
717 my $sym = objsym($sv);
718 return $sym if defined $sym;
719 my( $savesym, $pvmax, $len, $pv ) = save_pv_or_rv( $sv );
721 $val .= '.00' if $val =~ /^-?\d+$/;
722 $xpvnvsect->add(sprintf("%s, %u, %u, %d, %s",
723 $savesym, $len, $pvmax, $sv->IVX, $val));
724 $svsect->add(sprintf("&xpvnv_list[%d], %lu, 0x%x",
725 $xpvnvsect->index, $sv->REFCNT , $sv->FLAGS));
726 if (defined($pv) && !$pv_copy_on_grow) {
727 $init->add(savepvn(sprintf("xpvnv_list[%d].xpv_pv",
728 $xpvnvsect->index), $pv));
730 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
735 my $sym = objsym($sv);
736 return $sym if defined $sym;
737 my $pv = pack "a*", ($sv->PV . "\0" . $sv->TABLE);
738 my $len = length($pv);
739 $xpvbmsect->add(sprintf("0, %u, %u, %d, %s, 0, 0, %d, %u, 0x%x",
740 $len, $len + 258, $sv->IVX, $sv->NVX,
741 $sv->USEFUL, $sv->PREVIOUS, $sv->RARE));
742 $svsect->add(sprintf("&xpvbm_list[%d], %lu, 0x%x",
743 $xpvbmsect->index, $sv->REFCNT , $sv->FLAGS));
745 $init->add(savepvn(sprintf("xpvbm_list[%d].xpv_pv",
746 $xpvbmsect->index), $pv),
747 sprintf("xpvbm_list[%d].xpv_cur = %u;",
748 $xpvbmsect->index, $len - 257));
749 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
754 my $sym = objsym($sv);
755 return $sym if defined $sym;
756 my( $savesym, $pvmax, $len, $pv ) = save_pv_or_rv( $sv );
757 $xpvsect->add(sprintf("%s, %u, %u", $savesym, $len, $pvmax));
758 $svsect->add(sprintf("&xpv_list[%d], %lu, 0x%x",
759 $xpvsect->index, $sv->REFCNT , $sv->FLAGS));
760 if (defined($pv) && !$pv_copy_on_grow) {
761 $init->add(savepvn(sprintf("xpv_list[%d].xpv_pv",
762 $xpvsect->index), $pv));
764 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
769 my $sym = objsym($sv);
770 return $sym if defined $sym;
771 my( $savesym, $pvmax, $len, $pv ) = save_pv_or_rv( $sv );
773 $xpvmgsect->add(sprintf("%s, %u, %u, %d, %s, 0, 0",
774 $savesym, $len, $pvmax,
775 $sv->IVX, $sv->NVX));
776 $svsect->add(sprintf("&xpvmg_list[%d], %lu, 0x%x",
777 $xpvmgsect->index, $sv->REFCNT , $sv->FLAGS));
778 if (defined($pv) && !$pv_copy_on_grow) {
779 $init->add(savepvn(sprintf("xpvmg_list[%d].xpv_pv",
780 $xpvmgsect->index), $pv));
782 $sym = savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
787 sub B::PVMG::save_magic {
789 #warn sprintf("saving magic for %s (0x%x)\n", class($sv), $$sv); # debug
790 my $stash = $sv->SvSTASH;
793 warn sprintf("xmg_stash = %s (0x%x)\n", $stash->NAME, $$stash)
795 # XXX Hope stash is already going to be saved.
796 $init->add(sprintf("SvSTASH(s\\_%x) = s\\_%x;", $$sv, $$stash));
798 my @mgchain = $sv->MAGIC;
799 my ($mg, $type, $obj, $ptr,$len,$ptrsv);
800 foreach $mg (@mgchain) {
805 warn sprintf("magic %s (0x%x), obj %s (0x%x), type %s, ptr %s\n",
806 class($sv), $$sv, class($obj), $$obj,
807 cchar($type), cstring($ptr));
810 unless( $type eq 'r' ) {
815 if ($len == HEf_SVKEY){
816 #The pointer is an SV*
817 $ptrsv=svref_2object($ptr)->save;
818 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s,(char *) %s, %d);",
819 $$sv, $$obj, cchar($type),$ptrsv,$len));
820 }elsif( $type eq 'r' ){
822 my $pmop = $REGEXP{$rx};
824 confess "PMOP not found for REGEXP $rx" unless $pmop;
826 my( $resym, $relen ) = savere( $mg->precomp );
827 my $pmsym = $pmop->save;
828 $init->add( split /\n/, sprintf <<CODE, $$sv, cchar($type), cstring($ptr) );
830 REGEXP* rx = pregcomp($resym, $resym + $relen, (PMOP*)$pmsym);
831 sv_magic((SV*)s\\_%x, (SV*)rx, %s, %s, %d);
835 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
836 $$sv, $$obj, cchar($type),cstring($ptr),$len));
843 my $sym = objsym($sv);
844 return $sym if defined $sym;
845 my $rv = save_rv( $sv );
846 # GVs need to be handled at runtime
847 if( ref( $sv->RV ) eq 'B::GV' ) {
848 $xrvsect->add( "(SV*)Nullgv" );
849 $init->add(sprintf("xrv_list[%d].xrv_rv = (SV*)%s;\n", $xrvsect->index, $rv));
852 elsif( $sv->RV->isa( 'B::HV' ) && $sv->RV->NAME ) {
853 $xrvsect->add( "(SV*)Nullhv" );
854 $init->add(sprintf("xrv_list[%d].xrv_rv = (SV*)%s;\n", $xrvsect->index, $rv));
859 $svsect->add(sprintf("&xrv_list[%d], %lu, 0x%x",
860 $xrvsect->index, $sv->REFCNT , $sv->FLAGS));
861 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
865 my ($cvstashname, $cvname) = @_;
866 warn sprintf("No definition for sub %s::%s\n", $cvstashname, $cvname);
867 # Handle AutoLoader classes explicitly. Any more general AUTOLOAD
868 # use should be handled by the class itself.
870 my $isa = \@{"$cvstashname\::ISA"};
871 if (grep($_ eq "AutoLoader", @$isa)) {
872 warn "Forcing immediate load of sub derived from AutoLoader\n";
873 # Tweaked version of AutoLoader::AUTOLOAD
874 my $dir = $cvstashname;
876 eval { require "auto/$dir/$cvname.al" };
878 warn qq(failed require "auto/$dir/$cvname.al": $@\n);
888 my $sym = objsym($cv);
890 # warn sprintf("CV 0x%x already saved as $sym\n", $$cv); # debug
893 # Reserve a place in svsect and xpvcvsect and record indices
895 my ($cvname, $cvstashname);
898 $cvstashname = $gv->STASH->NAME;
900 my $root = $cv->ROOT;
901 my $cvxsub = $cv->XSUB;
902 my $isconst = $cv->CvFLAGS & CVf_CONST;
904 my $value = $cv->XSUBANY;
905 my $stash = $gv->STASH;
906 my $vsym = $value->save;
907 my $stsym = $stash->save;
908 my $name = cstring($cvname);
909 $decl->add( "static CV* cv$cv_index;" );
910 $init->add( "cv$cv_index = newCONSTSUB( $stsym, NULL, $vsym );" );
911 my $sym = savesym( $cv, "cv$cv_index" );
915 #INIT is removed from the symbol table, so this call must come
916 # from PL_initav->save. Re-bootstrapping will push INIT back in
917 # so nullop should be sent.
918 if (!$isconst && $cvxsub && ($cvname ne "INIT")) {
920 my $stashname = $egv->STASH->NAME;
921 if ($cvname eq "bootstrap")
923 my $file = $gv->FILE;
924 $decl->add("/* bootstrap $file */");
925 warn "Bootstrap $stashname $file\n";
926 # if it not isa('DynaLoader'), it should hopefully be XSLoaded
927 # ( attributes being an exception, of course )
928 if( $stashname ne 'attributes' &&
929 !UNIVERSAL::isa($stashname,'DynaLoader') ) {
930 $xsub{$stashname}='Dynamic-XSLoaded';
934 $xsub{$stashname}='Dynamic';
936 # $xsub{$stashname}='Static' unless $xsub{$stashname};
941 # XSUBs for IO::File, IO::Handle, IO::Socket,
942 # IO::Seekable and IO::Poll
943 # are defined in IO.xs, so let's bootstrap it
944 svref_2object( \&IO::bootstrap )->save
945 if grep { $stashname eq $_ } qw(IO::File IO::Handle IO::Socket
946 IO::Seekable IO::Poll);
948 warn sprintf("stub for XSUB $cvstashname\:\:$cvname CV 0x%x\n", $$cv) if $debug_cv;
949 return qq/(perl_get_cv("$stashname\:\:$cvname",TRUE))/;
951 if ($cvxsub && $cvname eq "INIT") {
953 return svref_2object(\&Dummy_initxs)->save;
955 my $sv_ix = $svsect->index + 1;
956 $svsect->add("svix$sv_ix");
957 my $xpvcv_ix = $xpvcvsect->index + 1;
958 $xpvcvsect->add("xpvcvix$xpvcv_ix");
959 # Save symbol now so that GvCV() doesn't recurse back to us via CvGV()
960 $sym = savesym($cv, "&sv_list[$sv_ix]");
961 warn sprintf("saving $cvstashname\:\:$cvname CV 0x%x as $sym\n", $$cv) if $debug_cv;
962 if (!$$root && !$cvxsub) {
963 if (try_autoload($cvstashname, $cvname)) {
964 # Recalculate root and xsub
967 if ($$root || $cvxsub) {
968 warn "Successful forced autoload\n";
973 my $padlist = $cv->PADLIST;
976 my $xsubany = "Nullany";
978 warn sprintf("saving op tree for CV 0x%x, root = 0x%x\n",
979 $$cv, $$root) if $debug_cv;
982 my $stashname = $gv->STASH->NAME;
983 my $gvname = $gv->NAME;
984 if ($gvname ne "__ANON__") {
985 $ppname = (${$gv->FORM} == $$cv) ? "pp_form_" : "pp_sub_";
986 $ppname .= ($stashname eq "main") ?
987 $gvname : "$stashname\::$gvname";
988 $ppname =~ s/::/__/g;
989 if ($gvname eq "INIT"){
990 $ppname .= "_$initsub_index";
996 $ppname = "pp_anonsub_$anonsub_index";
999 $startfield = saveoptree($ppname, $root, $cv->START, $padlist->ARRAY);
1000 warn sprintf("done saving op tree for CV 0x%x, name %s, root 0x%x\n",
1001 $$cv, $ppname, $$root) if $debug_cv;
1003 warn sprintf("saving PADLIST 0x%x for CV 0x%x\n",
1004 $$padlist, $$cv) if $debug_cv;
1006 warn sprintf("done saving PADLIST 0x%x for CV 0x%x\n",
1007 $$padlist, $$cv) if $debug_cv;
1011 warn sprintf("No definition for sub %s::%s (unable to autoload)\n",
1012 $cvstashname, $cvname); # debug
1014 $pv = '' unless defined $pv; # Avoid use of undef warnings
1015 $symsect->add(sprintf("xpvcvix%d\t%s, %u, 0, %d, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub, $xsubany, Nullgv, \"\", %d, s\\_%x, (CV*)s\\_%x, 0x%x, 0x%x",
1016 $xpvcv_ix, cstring($pv), length($pv), $cv->IVX,
1017 $cv->NVX, $startfield, ${$cv->ROOT}, $cv->DEPTH,
1018 $$padlist, ${$cv->OUTSIDE}, $cv->CvFLAGS,
1021 if (${$cv->OUTSIDE} == ${main_cv()}){
1022 $init->add(sprintf("CvOUTSIDE(s\\_%x)=PL_main_cv;",$$cv));
1023 $init->add(sprintf("SvREFCNT_inc(PL_main_cv);"));
1028 $init->add(sprintf("CvGV(s\\_%x) = s\\_%x;",$$cv,$$gv));
1029 warn sprintf("done saving GV 0x%x for CV 0x%x\n",
1030 $$gv, $$cv) if $debug_cv;
1033 $init->add( savepvn( "CvFILE($sym)", $cv->FILE) );
1036 $init->add(sprintf("CvFILE($sym) = %s;", cstring($cv->FILE)));
1038 my $stash = $cv->STASH;
1041 $init->add(sprintf("CvSTASH(s\\_%x) = s\\_%x;", $$cv, $$stash));
1042 warn sprintf("done saving STASH 0x%x for CV 0x%x\n",
1043 $$stash, $$cv) if $debug_cv;
1045 $symsect->add(sprintf("svix%d\t(XPVCV*)&xpvcv_list[%u], %lu, 0x%x",
1046 $sv_ix, $xpvcv_ix, $cv->REFCNT +1*0 , $cv->FLAGS));
1052 my $sym = objsym($gv);
1053 if (defined($sym)) {
1054 #warn sprintf("GV 0x%x already saved as $sym\n", $$gv); # debug
1057 my $ix = $gv_index++;
1058 $sym = savesym($gv, "gv_list[$ix]");
1059 #warn sprintf("Saving GV 0x%x as $sym\n", $$gv); # debug
1061 my $is_empty = $gv->is_empty;
1062 my $gvname = $gv->NAME;
1063 my $fullname = $gv->STASH->NAME . "::" . $gvname;
1064 my $name = cstring($fullname);
1065 #warn "GV name is $name\n"; # debug
1067 unless ($is_empty) {
1069 if ($$gv != $$egv) {
1070 #warn(sprintf("EGV name is %s, saving it now\n",
1071 # $egv->STASH->NAME . "::" . $egv->NAME)); # debug
1072 $egvsym = $egv->save;
1075 $init->add(qq[$sym = gv_fetchpv($name, TRUE, SVt_PV);],
1076 sprintf("SvFLAGS($sym) = 0x%x;", $gv->FLAGS ),
1077 sprintf("GvFLAGS($sym) = 0x%x;", $gv->GvFLAGS));
1078 $init->add(sprintf("GvLINE($sym) = %u;", $gv->LINE)) unless $is_empty;
1079 # XXX hack for when Perl accesses PVX of GVs
1080 $init->add("SvPVX($sym) = emptystring;\n");
1081 # Shouldn't need to do save_magic since gv_fetchpv handles that
1083 # XXX will always be > 1!!!
1084 my $refcnt = $gv->REFCNT + 1;
1085 $init->add(sprintf("SvREFCNT($sym) += %u;", $refcnt - 1 )) if $refcnt > 1;
1087 return $sym if $is_empty;
1089 # XXX B::walksymtable creates an extra reference to the GV
1090 my $gvrefcnt = $gv->GvREFCNT;
1091 if ($gvrefcnt > 1) {
1092 $init->add(sprintf("GvREFCNT($sym) += %u;", $gvrefcnt - 1));
1094 # some non-alphavetic globs require some parts to be saved
1095 # ( ex. %!, but not $! )
1100 sub Save_FORM() { 16 }
1101 sub Save_IO() { 32 }
1103 if( $gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/ ) {
1104 $savefields = Save_HV|Save_AV|Save_SV|Save_CV|Save_FORM|Save_IO;
1106 elsif( $gvname eq '!' ) {
1107 $savefields = Save_HV;
1109 # attributes::bootstrap is created in perl_parse
1110 # saving it would overwrite it, because perl_init() is
1111 # called after perl_parse()
1112 $savefields&=~Save_CV if $fullname eq 'attributes::bootstrap';
1115 # XXX is that correct?
1116 if (defined($egvsym) && $egvsym !~ m/Null/ ) {
1117 # Shared glob *foo = *bar
1118 $init->add("gp_free($sym);",
1119 "GvGP($sym) = GvGP($egvsym);");
1120 } elsif ($savefields) {
1121 # Don't save subfields of special GVs (*_, *1, *# and so on)
1122 # warn "GV::save saving subfields\n"; # debug
1124 if ($$gvsv && $savefields&Save_SV) {
1126 $init->add(sprintf("GvSV($sym) = s\\_%x;", $$gvsv));
1127 # warn "GV::save \$$name\n"; # debug
1130 if ($$gvav && $savefields&Save_AV) {
1132 $init->add(sprintf("GvAV($sym) = s\\_%x;", $$gvav));
1133 # warn "GV::save \@$name\n"; # debug
1136 if ($$gvhv && $savefields&Save_HV) {
1138 $init->add(sprintf("GvHV($sym) = s\\_%x;", $$gvhv));
1139 # warn "GV::save \%$name\n"; # debug
1142 if ($$gvcv && $savefields&Save_CV) {
1143 my $origname=cstring($gvcv->GV->EGV->STASH->NAME .
1144 "::" . $gvcv->GV->EGV->NAME);
1145 if (0 && $gvcv->XSUB && $name ne $origname) { #XSUB alias
1146 # must save as a 'stub' so newXS() has a CV to populate
1147 $init->add("{ CV *cv;");
1148 $init->add("\tcv=perl_get_cv($origname,TRUE);");
1149 $init->add("\tGvCV($sym)=cv;");
1150 $init->add("\tSvREFCNT_inc((SV *)cv);");
1153 $init->add(sprintf("GvCV($sym) = (CV*)(%s);", $gvcv->save));
1154 # warn "GV::save &$name\n"; # debug
1157 $init->add(sprintf("GvFILE($sym) = %s;", cstring($gv->FILE)));
1158 # warn "GV::save GvFILE(*$name)\n"; # debug
1159 my $gvform = $gv->FORM;
1160 if ($$gvform && $savefields&Save_FORM) {
1162 $init->add(sprintf("GvFORM($sym) = (CV*)s\\_%x;", $$gvform));
1163 # warn "GV::save GvFORM(*$name)\n"; # debug
1166 if ($$gvio && $savefields&Save_IO) {
1168 $init->add(sprintf("GvIOp($sym) = s\\_%x;", $$gvio));
1169 if( $fullname =~ m/::DATA$/ && $save_data_fh ) {
1171 my $fh = *{$fullname}{IO};
1173 $gvio->save_data( $fullname, <$fh> ) if $fh->opened;
1175 # warn "GV::save GvIO(*$name)\n"; # debug
1183 my $sym = objsym($av);
1184 return $sym if defined $sym;
1185 my $line = "0, -1, -1, 0, 0.0, 0, Nullhv, 0, 0";
1186 $line .= sprintf(", 0x%x", $av->AvFLAGS) if $] < 5.009;
1187 $xpvavsect->add($line);
1188 $svsect->add(sprintf("&xpvav_list[%d], %lu, 0x%x",
1189 $xpvavsect->index, $av->REFCNT , $av->FLAGS));
1190 my $sv_list_index = $svsect->index;
1191 my $fill = $av->FILL;
1194 $line = sprintf("saving AV 0x%x FILL=$fill", $$av);
1195 $line .= sprintf(" AvFLAGS=0x%x", $av->AvFLAGS) if $] < 5.009;
1198 # XXX AVf_REAL is wrong test: need to save comppadlist but not stack
1199 #if ($fill > -1 && ($avflags & AVf_REAL)) {
1201 my @array = $av->ARRAY;
1205 foreach $el (@array) {
1206 warn sprintf("AV 0x%x[%d] = %s 0x%x\n",
1207 $$av, $i++, class($el), $$el);
1210 # my @names = map($_->save, @array);
1211 # XXX Better ways to write loop?
1212 # Perhaps svp[0] = ...; svp[1] = ...; svp[2] = ...;
1213 # Perhaps I32 i = 0; svp[i++] = ...; svp[i++] = ...; svp[i++] = ...;
1215 # micro optimization: op/pat.t ( and other code probably )
1216 # has very large pads ( 20k/30k elements ) passing them to
1217 # ->add is a performance bottleneck: passing them as a
1218 # single string cuts runtime from 6min20sec to 40sec
1220 # you want to keep this out of the no_split/split
1221 # map("\t*svp++ = (SV*)$_;", @names),
1223 foreach my $i ( 0..$#array ) {
1224 $acc .= "\t*svp++ = (SV*)" . $array[$i]->save . ";\n\t";
1231 "\tAV *av = (AV*)&sv_list[$sv_list_index];",
1232 "\tav_extend(av, $fill);",
1233 "\tsvp = AvARRAY(av);" );
1235 $init->add("\tAvFILLp(av) = $fill;",
1238 # we really added a lot of lines ( B::C::InitSection->add
1239 # should really scan for \n, but that would slow
1241 $init->inc_count( $#array );
1244 $init->add("av_extend((AV*)&sv_list[$sv_list_index], $max);")
1247 return savesym($av, "(AV*)&sv_list[$sv_list_index]");
1252 my $sym = objsym($hv);
1253 return $sym if defined $sym;
1254 my $name = $hv->NAME;
1258 # A perl bug means HvPMROOT isn't altered when a PMOP is freed. Usually
1259 # the only symptom is that sv_reset tries to reset the PMf_USED flag of
1260 # a trashed op but we look at the trashed op_type and segfault.
1261 #my $adpmroot = ${$hv->PMROOT};
1263 $decl->add("static HV *hv$hv_index;");
1264 # XXX Beware of weird package names containing double-quotes, \n, ...?
1265 $init->add(qq[hv$hv_index = gv_stashpv("$name", TRUE);]);
1267 $init->add(sprintf("HvPMROOT(hv$hv_index) = (PMOP*)s\\_%x;",
1270 $sym = savesym($hv, "hv$hv_index");
1274 # It's just an ordinary HV
1275 $xpvhvsect->add(sprintf("0, 0, %d, 0, 0.0, 0, Nullhv, %d, 0, 0, 0",
1276 $hv->MAX, $hv->RITER));
1277 $svsect->add(sprintf("&xpvhv_list[%d], %lu, 0x%x",
1278 $xpvhvsect->index, $hv->REFCNT , $hv->FLAGS));
1279 my $sv_list_index = $svsect->index;
1280 my @contents = $hv->ARRAY;
1283 for ($i = 1; $i < @contents; $i += 2) {
1284 $contents[$i] = $contents[$i]->save;
1287 $init->add("{", "\tHV *hv = (HV*)&sv_list[$sv_list_index];");
1289 my ($key, $value) = splice(@contents, 0, 2);
1290 $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
1291 cstring($key),length(pack "a*",$key),
1292 $value, hash($key)));
1293 # $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
1294 # cstring($key),length($key),$value, 0));
1300 return savesym($hv, "(HV*)&sv_list[$sv_list_index]");
1303 sub B::IO::save_data {
1304 my( $io, $globname, @data ) = @_;
1305 my $data = join '', @data;
1307 # XXX using $DATA might clobber it!
1308 my $sym = svref_2object( \\$data )->save;
1309 $init->add( split /\n/, <<CODE );
1311 GV* gv = (GV*)gv_fetchpv( "$globname", TRUE, SVt_PV );
1316 # for PerlIO::scalar
1318 $init->add_eval( sprintf 'open(%s, "<", $%s)', $globname, $globname );
1323 my $sym = objsym($io);
1324 return $sym if defined $sym;
1326 $pv = '' unless defined $pv;
1327 my $len = length($pv);
1328 $xpviosect->add(sprintf("0, %u, %u, %d, %s, 0, 0, 0, 0, 0, %d, %d, %d, %d, %s, Nullgv, %s, Nullgv, %s, Nullgv, %d, %s, 0x%x",
1329 $len, $len+1, $io->IVX, $io->NVX, $io->LINES,
1330 $io->PAGE, $io->PAGE_LEN, $io->LINES_LEFT,
1331 cstring($io->TOP_NAME), cstring($io->FMT_NAME),
1332 cstring($io->BOTTOM_NAME), $io->SUBPROCESS,
1333 cchar($io->IoTYPE), $io->IoFLAGS));
1334 $svsect->add(sprintf("&xpvio_list[%d], %lu, 0x%x",
1335 $xpviosect->index, $io->REFCNT , $io->FLAGS));
1336 $sym = savesym($io, sprintf("(IO*)&sv_list[%d]", $svsect->index));
1337 # deal with $x = *STDIN/STDOUT/STDERR{IO}
1339 foreach ( qw(stdin stdout stderr) ) {
1340 $io->IsSTD($_) and $perlio_func = $_;
1342 if( $perlio_func ) {
1343 $init->add( "IoIFP(${sym})=PerlIO_${perlio_func}();" );
1344 $init->add( "IoOFP(${sym})=PerlIO_${perlio_func}();" );
1348 foreach $field (qw(TOP_GV FMT_GV BOTTOM_GV)) {
1349 $fsym = $io->$field();
1351 $init->add(sprintf("Io$field($sym) = (GV*)s\\_%x;", $$fsym));
1361 # This is where we catch an honest-to-goodness Nullsv (which gets
1362 # blessed into B::SV explicitly) and any stray erroneous SVs.
1363 return 0 unless $$sv;
1364 confess sprintf("cannot save that type of SV: %s (0x%x)\n",
1369 my $init_name = shift;
1371 my @sections = ($opsect, $unopsect, $binopsect, $logopsect, $condopsect,
1372 $listopsect, $pmopsect, $svopsect, $padopsect, $pvopsect,
1373 $loopsect, $copsect, $svsect, $xpvsect,
1374 $xpvavsect, $xpvhvsect, $xpvcvsect, $xpvivsect, $xpvnvsect,
1375 $xpvmgsect, $xpvlvsect, $xrvsect, $xpvbmsect, $xpviosect);
1376 $symsect->output(\*STDOUT, "#define %s\n");
1378 output_declarations();
1379 foreach $section (@sections) {
1380 my $lines = $section->index + 1;
1382 my $name = $section->name;
1383 my $typename = ($name eq "xpvcv") ? "XPVCV_or_similar" : uc($name);
1384 print "Static $typename ${name}_list[$lines];\n";
1387 # XXX hack for when Perl accesses PVX of GVs
1388 print 'Static char emptystring[] = "\0";';
1390 $decl->output(\*STDOUT, "%s\n");
1392 foreach $section (@sections) {
1393 my $lines = $section->index + 1;
1395 my $name = $section->name;
1396 my $typename = ($name eq "xpvcv") ? "XPVCV_or_similar" : uc($name);
1397 printf "static %s %s_list[%u] = {\n", $typename, $name, $lines;
1398 $section->output(\*STDOUT, "\t{ %s }, /* %d */\n");
1403 $init->output(\*STDOUT, "\t%s\n", $init_name );
1405 warn compile_stats();
1406 warn "NULLOP count: $nullop_count\n";
1410 sub output_declarations {
1412 #ifdef BROKEN_STATIC_REDECL
1413 #define Static extern
1415 #define Static static
1416 #endif /* BROKEN_STATIC_REDECL */
1418 #ifdef BROKEN_UNION_INIT
1420 * Cribbed from cv.h with ANY (a union) replaced by void*.
1421 * Some pre-Standard compilers can't cope with initialising unions. Ho hum.
1424 STRLEN xpv_cur; /* length of xp_pv as a C string */
1425 STRLEN xpv_len; /* allocated size */
1426 IV xof_off; /* integer value */
1427 NV xnv_nv; /* numeric value, if any */
1428 MAGIC* xmg_magic; /* magic for scalar array */
1429 HV* xmg_stash; /* class package */
1434 void (*xcv_xsub) (pTHX_ CV*);
1438 long xcv_depth; /* >= 2 indicates recursive call */
1442 print <<'EOT' if $] < 5.009;
1443 #ifdef USE_5005THREADS
1444 perl_mutex *xcv_mutexp;
1445 struct perl_thread *xcv_owner; /* current owner thread */
1446 #endif /* USE_5005THREADS */
1449 cv_flags_t xcv_flags;
1450 U32 xcv_outside_seq; /* the COP sequence (at the point of our
1451 * compilation) in the lexically enclosing
1454 #define ANYINIT(i) i
1456 #define XPVCV_or_similar XPVCV
1457 #define ANYINIT(i) {i}
1458 #endif /* BROKEN_UNION_INIT */
1459 #define Nullany ANYINIT(0)
1464 print "static GV *gv_list[$gv_index];\n" if $gv_index;
1469 sub output_boilerplate {
1475 /* Workaround for mapstart: the only op which needs a different ppaddr */
1476 #undef Perl_pp_mapstart
1477 #define Perl_pp_mapstart Perl_pp_grepstart
1479 #define OP_MAPSTART OP_GREPSTART
1480 #define XS_DynaLoader_boot_DynaLoader boot_DynaLoader
1481 EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
1483 static void xs_init (pTHX);
1484 static void dl_init (pTHX);
1485 static PerlInterpreter *my_perl;
1490 my( $op_type, $num ) = @_;
1491 my $op_list = $op_type."_list";
1493 $init->add( split /\n/, <<EOT );
1497 for( i = 0; i < ${num}; ++i )
1499 ${op_list}\[i].op_ppaddr = PL_ppaddr[INT2PTR(int,${op_list}\[i].op_ppaddr)];
1506 my( $op_type, $num ) = @_;
1507 my $op_list = $op_type."_list";
1509 # for resons beyond imagination, MSVC5 considers pWARN_ALL non-const
1510 $init->add( split /\n/, <<EOT );
1514 for( i = 0; i < ${num}; ++i )
1516 switch( (int)(${op_list}\[i].cop_warnings) )
1519 ${op_list}\[i].cop_warnings = pWARN_ALL;
1522 ${op_list}\[i].cop_warnings = pWARN_NONE;
1525 ${op_list}\[i].cop_warnings = pWARN_STD;
1537 /* if USE_IMPLICIT_SYS, we need a 'real' exit */
1543 main(int argc, char **argv, char **env)
1552 PERL_SYS_INIT3(&argc,&argv,&env);
1554 if (!PL_do_undump) {
1555 my_perl = perl_alloc();
1558 perl_construct( my_perl );
1559 PL_perl_destruct_level = 0;
1563 # XXX init free elems!
1564 my $pad_len = regex_padav->FILL + 1 - 1; # first is an avref
1568 for( i = 0; i < $pad_len; ++i ) {
1569 av_push( PL_regex_padav, newSViv(0) );
1571 PL_regex_pad = AvARRAY( PL_regex_padav );
1579 PL_cshlen = strlen(PL_cshname);
1582 #ifdef ALLOW_PERL_OPTIONS
1583 #define EXTRA_OPTIONS 3
1585 #define EXTRA_OPTIONS 4
1586 #endif /* ALLOW_PERL_OPTIONS */
1587 Newx(fakeargv, argc + EXTRA_OPTIONS + 1, char *);
1589 fakeargv[0] = argv[0];
1597 fakeargv[options_count] = "-T";
1602 #ifndef ALLOW_PERL_OPTIONS
1603 fakeargv[options_count] = "--";
1605 #endif /* ALLOW_PERL_OPTIONS */
1606 for (i = 1; i < argc; i++)
1607 fakeargv[i + options_count - 1] = argv[i];
1608 fakeargv[argc + options_count - 1] = 0;
1610 exitstatus = perl_parse(my_perl, xs_init, argc + options_count - 1,
1619 if( $use_perl_script_name ) {
1621 $dollar_0 =~ s/\\/\\\\/g;
1622 $dollar_0 = '"' . $dollar_0 . '"';
1625 if ((tmpgv = gv_fetchpv("0",TRUE, SVt_PV))) {/* $0 */
1626 tmpsv = GvSV(tmpgv);
1627 sv_setpv(tmpsv, ${dollar_0});
1634 if ((tmpgv = gv_fetchpv("0",TRUE, SVt_PV))) {/* $0 */
1635 tmpsv = GvSV(tmpgv);
1636 sv_setpv(tmpsv, argv[0]);
1643 if ((tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))) {/* $^X */
1644 tmpsv = GvSV(tmpgv);
1646 sv_setpv(tmpsv,"perl.exe");
1648 sv_setpv(tmpsv,"perl");
1655 /* PL_main_cv = PL_compcv; */
1658 exitstatus = perl_init();
1663 exitstatus = perl_run( my_perl );
1665 perl_destruct( my_perl );
1666 perl_free( my_perl );
1673 /* yanked from perl.c */
1677 char *file = __FILE__;
1681 print "\n#ifdef USE_DYNAMIC_LOADING";
1682 print qq/\n\tnewXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);/;
1683 print "\n#endif\n" ;
1684 # delete $xsub{'DynaLoader'};
1685 delete $xsub{'UNIVERSAL'};
1686 print("/* bootstrapping code*/\n\tSAVETMPS;\n");
1687 print("\ttarg=sv_newmortal();\n");
1688 print "#ifdef USE_DYNAMIC_LOADING\n";
1689 print "\tPUSHMARK(sp);\n";
1690 print qq/\tXPUSHp("DynaLoader",strlen("DynaLoader"));\n/;
1691 print qq/\tPUTBACK;\n/;
1692 print "\tboot_DynaLoader(aTHX_ NULL);\n";
1693 print qq/\tSPAGAIN;\n/;
1695 foreach my $stashname (keys %xsub){
1696 if ($xsub{$stashname} !~ m/Dynamic/ ) {
1697 my $stashxsub=$stashname;
1698 $stashxsub =~ s/::/__/g;
1699 print "\tPUSHMARK(sp);\n";
1700 print qq/\tXPUSHp("$stashname",strlen("$stashname"));\n/;
1701 print qq/\tPUTBACK;\n/;
1702 print "\tboot_$stashxsub(aTHX_ NULL);\n";
1703 print qq/\tSPAGAIN;\n/;
1706 print("\tFREETMPS;\n/* end bootstrapping code */\n");
1713 char *file = __FILE__;
1717 print("/* Dynamicboot strapping code*/\n\tSAVETMPS;\n");
1718 print("\ttarg=sv_newmortal();\n");
1719 foreach my $stashname (@DynaLoader::dl_modules) {
1720 warn "Loaded $stashname\n";
1721 if (exists($xsub{$stashname}) && $xsub{$stashname} =~ m/Dynamic/) {
1722 my $stashxsub=$stashname;
1723 $stashxsub =~ s/::/__/g;
1724 print "\tPUSHMARK(sp);\n";
1725 print qq/\tXPUSHp("$stashname",/,length($stashname),qq/);\n/;
1726 print qq/\tPUTBACK;\n/;
1727 print "#ifdef USE_DYNAMIC_LOADING\n";
1728 warn "bootstrapping $stashname added to xs_init\n";
1729 if( $xsub{$stashname} eq 'Dynamic' ) {
1730 print qq/\tperl_call_method("bootstrap",G_DISCARD);\n/;
1733 print qq/\tperl_call_pv("XSLoader::load",G_DISCARD);\n/;
1736 print "\tboot_$stashxsub(aTHX_ NULL);\n";
1738 print qq/\tSPAGAIN;\n/;
1741 print("\tFREETMPS;\n/* end Dynamic bootstrapping code */\n");
1747 warn "----Symbol table:\n";
1748 while (($sym, $val) = each %symtable) {
1749 warn "$sym => $val\n";
1751 warn "---End of symbol table\n";
1757 svref_2object($sv)->save;
1761 sub Dummy_BootStrap { }
1766 my $package=$gv->STASH->NAME;
1767 my $name = $gv->NAME;
1773 my $fullname = $gv->STASH->NAME . "::" . $gv->NAME;
1775 # We may be looking at this package just because it is a branch in the
1776 # symbol table which is on the path to a package which we need to save
1777 # e.g. this is 'Getopt' and we need to save 'Getopt::Long'
1779 return unless ($unused_sub_packages{$package});
1780 return unless ($$cv || $$av || $$sv || $$hv);
1786 my $package = shift;
1787 unless ($unused_sub_packages{$package})
1790 $unused_sub_packages{$package} = 1;
1791 if (defined @{$package.'::ISA'})
1793 foreach my $isa (@{$package.'::ISA'})
1795 if ($isa eq 'DynaLoader')
1797 unless (defined(&{$package.'::bootstrap'}))
1799 warn "Forcing bootstrap of $package\n";
1800 eval { $package->bootstrap };
1805 unless ($unused_sub_packages{$isa})
1807 warn "$isa saved (it is in $package\'s \@ISA)\n";
1819 no strict qw(vars refs);
1820 my $package = shift;
1821 $package =~ s/::$//;
1822 return $unused_sub_packages{$package} = 0 if ($package =~ /::::/); # skip ::::ISA::CACHE etc.
1823 # warn "Considering $package\n";#debug
1824 foreach my $u (grep($unused_sub_packages{$_},keys %unused_sub_packages))
1826 # If this package is a prefix to something we are saving, traverse it
1827 # but do not mark it for saving if it is not already
1828 # e.g. to get to Getopt::Long we need to traverse Getopt but need
1830 return 1 if ($u =~ /^$package\:\:/);
1832 if (exists $unused_sub_packages{$package})
1834 # warn "Cached $package is ".$unused_sub_packages{$package}."\n";
1835 delete_unsaved_hashINC($package) unless $unused_sub_packages{$package} ;
1836 return $unused_sub_packages{$package};
1838 # Omit the packages which we use (and which cause grief
1839 # because of fancy "goto &$AUTOLOAD" stuff).
1840 # XXX Surely there must be a nicer way to do this.
1841 if ($package eq "FileHandle" || $package eq "Config" ||
1842 $package eq "SelectSaver" || $package =~/^(B|IO)::/)
1844 delete_unsaved_hashINC($package);
1845 return $unused_sub_packages{$package} = 0;
1847 # Now see if current package looks like an OO class this is probably too strong.
1848 foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE))
1850 if (UNIVERSAL::can($package, $m))
1852 warn "$package has method $m: saving package\n";#debug
1853 return mark_package($package);
1856 delete_unsaved_hashINC($package);
1857 return $unused_sub_packages{$package} = 0;
1859 sub delete_unsaved_hashINC{
1861 $packname =~ s/\:\:/\//g;
1863 # warn "deleting $packname" if $INC{$packname} ;# debug
1864 delete $INC{$packname};
1868 my ($symref, $recurse, $prefix) = @_;
1872 $prefix = '' unless defined $prefix;
1873 while (($sym, $ref) = each %$symref)
1879 $sym = $prefix . $sym;
1880 if ($sym ne "main::" && $sym ne "<none>::" && &$recurse($sym))
1882 walkpackages(\%glob, $recurse, $sym);
1889 sub save_unused_subs
1892 &descend_marked_unused;
1894 walkpackages(\%{"main::"}, sub { should_save($_[0]); return 1 });
1895 warn "Saving methods\n";
1896 walksymtable(\%{"main::"}, "savecv", \&should_save);
1901 my $curpad_nam = (comppadlist->ARRAY)[0]->save;
1902 my $curpad_sym = (comppadlist->ARRAY)[1]->save;
1903 my $inc_hv = svref_2object(\%INC)->save;
1904 my $inc_av = svref_2object(\@INC)->save;
1905 my $amagic_generate= amagic_generation;
1906 $init->add( "PL_curpad = AvARRAY($curpad_sym);",
1907 "GvHV(PL_incgv) = $inc_hv;",
1908 "GvAV(PL_incgv) = $inc_av;",
1909 "av_store(CvPADLIST(PL_main_cv),0,SvREFCNT_inc($curpad_nam));",
1910 "av_store(CvPADLIST(PL_main_cv),1,SvREFCNT_inc($curpad_sym));",
1911 "PL_amagic_generation= $amagic_generate;" );
1914 sub descend_marked_unused {
1915 foreach my $pack (keys %unused_sub_packages)
1917 mark_package($pack);
1922 # this is mainly for the test suite
1923 my $warner = $SIG{__WARN__};
1924 local $SIG{__WARN__} = sub { print STDERR @_ };
1926 warn "Starting compile\n";
1927 warn "Walking tree\n";
1928 seek(STDOUT,0,0); #exclude print statements in BEGIN{} into output
1929 walkoptree(main_root, "save");
1930 warn "done main optree, walking symtable for extras\n" if $debug_cv;
1932 # XSLoader was used, force saving of XSLoader::load
1933 if( $use_xsloader ) {
1934 my $cv = svref_2object( \&XSLoader::load );
1937 # save %SIG ( in case it was set in a BEGIN block )
1939 local $SIG{__WARN__} = $warner;
1941 $init->add("{", "\tHV* hv = get_hv(\"main::SIG\",1);" );
1942 foreach my $k ( keys %SIG ) {
1943 next unless ref $SIG{$k};
1944 my $cv = svref_2object( \$SIG{$k} );
1946 $init->add('{',sprintf 'SV* sv = (SV*)%s;', $sv );
1947 $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
1948 cstring($k),length(pack "a*",$k),
1950 $init->add('mg_set(sv);','}');
1956 $init->add( sprintf " PL_dowarn = ( %s ) ? G_WARN_ON : G_WARN_OFF;", $^W );
1958 my $init_av = init_av->save;
1959 my $end_av = end_av->save;
1960 $init->add(sprintf("PL_main_root = s\\_%x;", ${main_root()}),
1961 sprintf("PL_main_start = s\\_%x;", ${main_start()}),
1962 "PL_initav = (AV *) $init_av;",
1963 "PL_endav = (AV*) $end_av;");
1965 # init op addrs ( must be the last action, otherwise
1966 # some ops might not be initialized
1967 if( $optimize_ppaddr ) {
1968 foreach my $i ( @op_sections ) {
1970 next unless $section->index >= 0;
1971 init_op_addr( $section->name, $section->index + 1);
1974 init_op_warn( $copsect->name, $copsect->index + 1)
1975 if $optimize_warn_sv && $copsect->index >= 0;
1977 warn "Writing output\n";
1978 output_boilerplate();
1980 output_all("perl_init");
1986 my @sections = (decl => \$decl, sym => \$symsect,
1987 binop => \$binopsect, condop => \$condopsect,
1988 cop => \$copsect, padop => \$padopsect,
1989 listop => \$listopsect, logop => \$logopsect,
1990 loop => \$loopsect, op => \$opsect, pmop => \$pmopsect,
1991 pvop => \$pvopsect, svop => \$svopsect, unop => \$unopsect,
1992 sv => \$svsect, xpv => \$xpvsect, xpvav => \$xpvavsect,
1993 xpvhv => \$xpvhvsect, xpvcv => \$xpvcvsect,
1994 xpviv => \$xpvivsect, xpvnv => \$xpvnvsect,
1995 xpvmg => \$xpvmgsect, xpvlv => \$xpvlvsect,
1996 xrv => \$xrvsect, xpvbm => \$xpvbmsect,
1997 xpvio => \$xpviosect);
1998 my ($name, $sectref);
1999 while (($name, $sectref) = splice(@sections, 0, 2)) {
2000 $$sectref = new B::C::Section $name, \%symtable, 0;
2002 $init = new B::C::InitSection 'init', \%symtable, 0;
2007 my ($arg,$val) = @_;
2008 $unused_sub_packages{$arg} = $val;
2013 my ($option, $opt, $arg);
2014 my @eval_at_startup;
2015 my %option_map = ( 'cog' => \$pv_copy_on_grow,
2016 'save-data' => \$save_data_fh,
2017 'ppaddr' => \$optimize_ppaddr,
2018 'warn-sv' => \$optimize_warn_sv,
2019 'use-script-name' => \$use_perl_script_name,
2020 'save-sig-hash' => \$save_sig,
2022 my %optimization_map = ( 0 => [ qw() ], # special case
2024 2 => [ qw(-fwarn-sv -fppaddr) ],
2027 while ($option = shift @options) {
2028 if ($option =~ /^-(.)(.*)/) {
2032 unshift @options, $option;
2035 if ($opt eq "-" && $arg eq "-") {
2040 $warn_undefined_syms = 1;
2041 } elsif ($opt eq "D") {
2042 $arg ||= shift @options;
2043 foreach $arg (split(//, $arg)) {
2046 } elsif ($arg eq "c") {
2048 } elsif ($arg eq "A") {
2050 } elsif ($arg eq "C") {
2052 } elsif ($arg eq "M") {
2055 warn "ignoring unknown debug option: $arg\n";
2058 } elsif ($opt eq "o") {
2059 $arg ||= shift @options;
2060 open(STDOUT, ">$arg") or return "$arg: $!\n";
2061 } elsif ($opt eq "v") {
2063 } elsif ($opt eq "u") {
2064 $arg ||= shift @options;
2065 mark_unused($arg,undef);
2066 } elsif ($opt eq "f") {
2067 $arg ||= shift @options;
2068 $arg =~ m/(no-)?(.*)/;
2069 my $no = defined($1) && $1 eq 'no-';
2070 $arg = $no ? $2 : $arg;
2071 if( exists $option_map{$arg} ) {
2072 ${$option_map{$arg}} = !$no;
2074 die "Invalid optimization '$arg'";
2076 } elsif ($opt eq "O") {
2077 $arg = 1 if $arg eq "";
2079 foreach my $i ( 1 .. $arg ) {
2080 push @opt, @{$optimization_map{$i}}
2081 if exists $optimization_map{$i};
2083 unshift @options, @opt;
2084 } elsif ($opt eq "e") {
2085 push @eval_at_startup, $arg;
2086 } elsif ($opt eq "l") {
2087 $max_string_len = $arg;
2091 foreach my $i ( @eval_at_startup ) {
2092 $init->add_eval( $i );
2097 foreach $objname (@options) {
2098 eval "save_object(\\$objname)";
2103 return sub { save_main() };
2113 B::C - Perl compiler's C backend
2117 perl -MO=C[,OPTIONS] foo.pl
2121 This compiler backend takes Perl source and generates C source code
2122 corresponding to the internal structures that perl uses to run
2123 your program. When the generated C source is compiled and run, it
2124 cuts out the time which perl would have taken to load and parse
2125 your program into its internal semi-compiled form. That means that
2126 compiling with this backend will not help improve the runtime
2127 execution speed of your program but may improve the start-up time.
2128 Depending on the environment in which your program runs this may be
2129 either a help or a hindrance.
2133 If there are any non-option arguments, they are taken to be
2134 names of objects to be saved (probably doesn't work properly yet).
2135 Without extra arguments, it saves the main program.
2141 Output to filename instead of STDOUT
2145 Verbose compilation (currently gives a few compilation statistics).
2149 Force end of options
2153 Force apparently unused subs from package Packname to be compiled.
2154 This allows programs to use eval "foo()" even when sub foo is never
2155 seen to be used at compile time. The down side is that any subs which
2156 really are never used also have code generated. This option is
2157 necessary, for example, if you have a signal handler foo which you
2158 initialise with C<$SIG{BAR} = "foo">. A better fix, though, is just
2159 to change it to C<$SIG{BAR} = \&foo>. You can have multiple B<-u>
2160 options. The compiler tries to figure out which packages may possibly
2161 have subs in which need compiling but the current version doesn't do
2162 it very well. In particular, it is confused by nested packages (i.e.
2163 of the form C<A::B>) where package C<A> does not contain any subs.
2167 Debug options (concatenated or separate flags like C<perl -D>).
2171 OPs, prints each OP as it's processed
2175 COPs, prints COPs as processed (incl. file & line num)
2179 prints AV information on saving
2183 prints CV information on saving
2187 prints MAGIC information on saving
2191 Force options/optimisations on or off one at a time. You can explicitly
2192 disable an option using B<-fno-option>. All options default to
2199 Copy-on-grow: PVs declared and initialised statically.
2201 =item B<-fsave-data>
2203 Save package::DATA filehandles ( only available with PerlIO ).
2207 Optimize the initialization of op_ppaddr.
2211 Optimize the initialization of cop_warnings.
2213 =item B<-fuse-script-name>
2215 Use the script name instead of the program name as $0.
2217 =item B<-fsave-sig-hash>
2219 Save compile-time modifications to the %SIG hash.
2225 Optimisation level (n = 0, 1, 2, ...). B<-O> means B<-O1>.
2231 Disable all optimizations.
2239 Enable B<-fppaddr>, B<-fwarn-sv>.
2245 Some C compilers impose an arbitrary limit on the length of string
2246 constants (e.g. 2048 characters for Microsoft Visual C++). The
2247 B<-llimit> options tells the C backend not to generate string literals
2248 exceeding that limit.
2254 perl -MO=C,-ofoo.c foo.pl
2255 perl cc_harness -o foo foo.c
2257 Note that C<cc_harness> lives in the C<B> subdirectory of your perl
2258 library directory. The utility called C<perlcc> may also be used to
2259 help make use of this compiler.
2261 perl -MO=C,-v,-DcA,-l2048 bar.pl > /dev/null
2265 Plenty. Current status: experimental.
2269 Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>