B/C.pm: make $0 to argv[0] again
[p5sagit/p5-mst-13.2.git] / ext / B / B / C.pm
CommitLineData
a798dbf2 1# C.pm
2#
1a52ab62 3# Copyright (c) 1996, 1997, 1998 Malcolm Beattie
a798dbf2 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#
66a2622e 8package B::C::Section;
28b605d8 9
b326da91 10our $VERSION = '1.01';
28b605d8 11
66a2622e 12use B ();
13use base B::Section;
14
15sub new
16{
17 my $class = shift;
18 my $o = $class->SUPER::new(@_);
b326da91 19 push @$o, { values => [] };
66a2622e 20 return $o;
21}
22
23sub add
b326da91 24{
66a2622e 25 my $section = shift;
b326da91 26 push(@{$section->[-1]{values}},@_);
66a2622e 27}
28
29sub index
b326da91 30{
66a2622e 31 my $section = shift;
b326da91 32 return scalar(@{$section->[-1]{values}})-1;
66a2622e 33}
34
35sub output
b326da91 36{
66a2622e 37 my ($section, $fh, $format) = @_;
38 my $sym = $section->symtable || {};
39 my $default = $section->default;
9d2bbe64 40 my $i;
b326da91 41 foreach (@{$section->[-1]{values}})
66a2622e 42 {
43 s{(s\\_[0-9a-f]+)}{ exists($sym->{$1}) ? $sym->{$1} : $default; }ge;
9d2bbe64 44 printf $fh $format, $_, $i;
45 ++$i;
66a2622e 46 }
47}
48
b326da91 49package B::C::InitSection;
50
9d2bbe64 51# avoid use vars
52@B::C::InitSection::ISA = qw(B::C::Section);
b326da91 53
54sub new {
55 my $class = shift;
9d2bbe64 56 my $max_lines = 10000; #pop;
b326da91 57 my $section = $class->SUPER::new( @_ );
58
59 $section->[-1]{evals} = [];
9d2bbe64 60 $section->[-1]{chunks} = [];
61 $section->[-1]{nosplit} = 0;
62 $section->[-1]{current} = [];
63 $section->[-1]{count} = 0;
64 $section->[-1]{max_lines} = $max_lines;
b326da91 65
66 return $section;
67}
68
9d2bbe64 69sub split {
70 my $section = shift;
71 $section->[-1]{nosplit}--
72 if $section->[-1]{nosplit} > 0;
73}
74
75sub no_split {
76 shift->[-1]{nosplit}++;
77}
78
79sub inc_count {
80 my $section = shift;
81
82 $section->[-1]{count} += $_[0];
83 # this is cheating
84 $section->add();
85}
86
87sub add {
88 my $section = shift->[-1];
89 my $current = $section->{current};
90 my $nosplit = $section->{nosplit};
91
92 push @$current, @_;
93 $section->{count} += scalar(@_);
94 if( !$nosplit && $section->{count} >= $section->{max_lines} ) {
95 push @{$section->{chunks}}, $current;
96 $section->{current} = [];
97 $section->{count} = 0;
98 }
99}
100
b326da91 101sub add_eval {
102 my $section = shift;
103 my @strings = @_;
104
105 foreach my $i ( @strings ) {
106 $i =~ s/\"/\\\"/g;
107 }
108 push @{$section->[-1]{evals}}, @strings;
109}
110
111sub output {
9d2bbe64 112 my( $section, $fh, $format, $init_name ) = @_;
113 my $sym = $section->symtable || {};
114 my $default = $section->default;
115 push @{$section->[-1]{chunks}}, $section->[-1]{current};
116
117 my $name = "aaaa";
118 foreach my $i ( @{$section->[-1]{chunks}} ) {
119 print $fh <<"EOT";
120static int perl_init_${name}()
121{
122 dTARG;
123 dSP;
124EOT
125 foreach my $j ( @$i ) {
126 $j =~ s{(s\\_[0-9a-f]+)}
127 { exists($sym->{$1}) ? $sym->{$1} : $default; }ge;
128 print $fh "\t$j\n";
129 }
130 print $fh "\treturn 0;\n}\n";
b326da91 131
9d2bbe64 132 $section->SUPER::add( "perl_init_${name}();" );
133 ++$name;
134 }
b326da91 135 foreach my $i ( @{$section->[-1]{evals}} ) {
9d2bbe64 136 $section->SUPER::add( sprintf q{eval_pv("%s",1);}, $i );
b326da91 137 }
9d2bbe64 138
139 print $fh <<"EOT";
140static int ${init_name}()
141{
142 dTARG;
143 dSP;
144EOT
145 $section->SUPER::output( $fh, $format );
146 print $fh "\treturn 0;\n}\n";
b326da91 147}
148
149
a798dbf2 150package B::C;
151use Exporter ();
9d2bbe64 152our %REGEXP;
153
154{ # block necessary for caller to work
155 my $caller = caller;
156 if( $caller eq 'O' ) {
157 require XSLoader;
158 XSLoader::load( 'B::C' );
159 }
160}
161
a798dbf2 162@ISA = qw(Exporter);
0cc1d052 163@EXPORT_OK = qw(output_all output_boilerplate output_main mark_unused
164 init_sections set_callback save_unused_subs objsym save_context);
a798dbf2 165
166use B qw(minus_c sv_undef walkoptree walksymtable main_root main_start peekop
167 class cstring cchar svref_2object compile_stats comppadlist hash
9d2bbe64 168 threadsv_names main_cv init_av end_av regex_padav opnumber amagic_generation
b326da91 169 AVf_REAL HEf_SVKEY SVf_POK SVf_ROK CVf_CONST);
a798dbf2 170use B::Asmdata qw(@specialsv_name);
171
172use FileHandle;
173use Carp;
174use strict;
f0cd5c3a 175use Config;
a798dbf2 176
177my $hv_index = 0;
178my $gv_index = 0;
179my $re_index = 0;
180my $pv_index = 0;
b326da91 181my $cv_index = 0;
a798dbf2 182my $anonsub_index = 0;
44887cfa 183my $initsub_index = 0;
a798dbf2 184
185my %symtable;
af765ed9 186my %xsub;
a798dbf2 187my $warn_undefined_syms;
188my $verbose;
66a2622e 189my %unused_sub_packages;
b326da91 190my $use_xsloader;
a798dbf2 191my $nullop_count;
66a2622e 192my $pv_copy_on_grow = 0;
b326da91 193my $optimize_ppaddr = 0;
194my $optimize_warn_sv = 0;
195my $use_perl_script_name = 0;
196my $save_data_fh = 0;
197my $save_sig = 0;
a798dbf2 198my ($debug_cops, $debug_av, $debug_cv, $debug_mg);
dc333d64 199my $max_string_len;
a798dbf2 200
9d2bbe64 201my $ithreads = $Config{useithreads} eq 'define';
202
a798dbf2 203my @threadsv_names;
204BEGIN {
205 @threadsv_names = threadsv_names();
206}
207
208# Code sections
66a2622e 209my ($init, $decl, $symsect, $binopsect, $condopsect, $copsect,
7934575e 210 $padopsect, $listopsect, $logopsect, $loopsect, $opsect, $pmopsect,
a798dbf2 211 $pvopsect, $svopsect, $unopsect, $svsect, $xpvsect, $xpvavsect,
212 $xpvhvsect, $xpvcvsect, $xpvivsect, $xpvnvsect, $xpvmgsect, $xpvlvsect,
af765ed9 213 $xrvsect, $xpvbmsect, $xpviosect );
b326da91 214my @op_sections = \( $binopsect, $condopsect, $copsect, $padopsect, $listopsect,
215 $logopsect, $loopsect, $opsect, $pmopsect, $pvopsect, $svopsect,
216 $unopsect );
a798dbf2 217
218sub walk_and_save_optree;
219my $saveoptree_callback = \&walk_and_save_optree;
220sub set_callback { $saveoptree_callback = shift }
221sub saveoptree { &$saveoptree_callback(@_) }
222
223sub walk_and_save_optree {
224 my ($name, $root, $start) = @_;
225 walkoptree($root, "save");
226 return objsym($start);
227}
228
229# Current workaround/fix for op_free() trying to free statically
230# defined OPs is to set op_seq = -1 and check for that in op_free().
231# Instead of hardwiring -1 in place of $op->seq, we use $op_seq
232# so that it can be changed back easily if necessary. In fact, to
233# stop compilers from moaning about a U16 being initialised with an
234# uncast -1 (the printf format is %d so we can't tweak it), we have
235# to "know" that op_seq is a U16 and use 65535. Ugh.
236my $op_seq = 65535;
237
0cc1d052 238# Look this up here so we can do just a number compare
239# rather than looking up the name of every BASEOP in B::OP
240my $OP_THREADSV = opnumber('threadsv');
a798dbf2 241
242sub savesym {
243 my ($obj, $value) = @_;
244 my $sym = sprintf("s\\_%x", $$obj);
245 $symtable{$sym} = $value;
246}
247
248sub objsym {
249 my $obj = shift;
250 return $symtable{sprintf("s\\_%x", $$obj)};
251}
252
253sub getsym {
254 my $sym = shift;
255 my $value;
256
257 return 0 if $sym eq "sym_0"; # special case
258 $value = $symtable{$sym};
259 if (defined($value)) {
260 return $value;
261 } else {
262 warn "warning: undefined symbol $sym\n" if $warn_undefined_syms;
263 return "UNUSED";
264 }
265}
266
b326da91 267sub savere {
268 my $re = shift;
269 my $sym = sprintf("re%d", $re_index++);
270 $decl->add(sprintf("static char *$sym = %s;", cstring($re)));
271
272 return ($sym,length(pack "a*",$re));
273}
274
a798dbf2 275sub savepv {
9d2bbe64 276 my $pv = pack "a*", shift;
a798dbf2 277 my $pvsym = 0;
278 my $pvmax = 0;
9d2bbe64 279 if ($pv_copy_on_grow) {
280 $pvsym = sprintf("pv%d", $pv_index++);
281
282 if( defined $max_string_len && length($pv) > $max_string_len ) {
283 my $chars = join ', ', map { cchar $_ } split //, $pv;
284 $decl->add(sprintf("static char %s[] = { %s };", $pvsym, $chars));
285 }
286 else {
287 my $cstring = cstring($pv);
288 if ($cstring ne "0") { # sic
289 $decl->add(sprintf("static char %s[] = %s;",
290 $pvsym, $cstring));
291 }
292 }
a798dbf2 293 } else {
b326da91 294 $pvmax = length(pack "a*",$pv) + 1;
a798dbf2 295 }
296 return ($pvsym, $pvmax);
297}
298
b326da91 299sub save_rv {
300 my $sv = shift;
301# confess "Can't save RV: not ROK" unless $sv->FLAGS & SVf_ROK;
302 my $rv = $sv->RV->save;
303
304 $rv =~ s/^\(([AGHS]V|IO)\s*\*\)\s*(\&sv_list.*)$/$2/;
305
306 return $rv;
307}
308
309# savesym, pvmax, len, pv
310sub save_pv_or_rv {
311 my $sv = shift;
312
313 my $rok = $sv->FLAGS & SVf_ROK;
314 my $pok = $sv->FLAGS & SVf_POK;
9d2bbe64 315 my( $len, $pvmax, $savesym, $pv ) = ( 0, 0 );
b326da91 316 if( $rok ) {
317 $savesym = '(char*)' . save_rv( $sv );
318 }
319 else {
320 $pv = $pok ? (pack "a*", $sv->PV) : undef;
321 $len = $pok ? length($pv) : 0;
322 ($savesym, $pvmax) = $pok ? savepv($pv) : ( 'NULL', 0 );
323 }
324
325 return ( $savesym, $pvmax, $len, $pv );
326}
327
328# see also init_op_ppaddr below; initializes the ppaddt to the
329# OpTYPE; init_op_ppaddr iterates over the ops and sets
330# op_ppaddr to PL_ppaddr[op_ppaddr]; this avoids an explicit assignmente
331# in perl_init ( ~10 bytes/op with GCC/i386 )
332sub B::OP::fake_ppaddr {
333 return $optimize_ppaddr ?
334 sprintf("INT2PTR(void*,OP_%s)", uc( $_[0]->name ) ) :
335 'NULL';
336}
337
a798dbf2 338sub B::OP::save {
339 my ($op, $level) = @_;
2c0b28dd 340 my $sym = objsym($op);
341 return $sym if defined $sym;
a798dbf2 342 my $type = $op->type;
343 $nullop_count++ unless $type;
0cc1d052 344 if ($type == $OP_THREADSV) {
a798dbf2 345 # saves looking up ppaddr but it's a bit naughty to hard code this
346 $init->add(sprintf("(void)find_threadsv(%s);",
347 cstring($threadsv_names[$op->targ])));
348 }
b326da91 349 $opsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x",
350 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr, $op->targ,
a798dbf2 351 $type, $op_seq, $op->flags, $op->private));
dc333d64 352 my $ix = $opsect->index;
b326da91 353 $init->add(sprintf("op_list[$ix].op_ppaddr = %s;", $op->ppaddr))
354 unless $optimize_ppaddr;
dc333d64 355 savesym($op, "&op_list[$ix]");
a798dbf2 356}
357
358sub B::FAKEOP::new {
359 my ($class, %objdata) = @_;
360 bless \%objdata, $class;
361}
362
363sub B::FAKEOP::save {
364 my ($op, $level) = @_;
b326da91 365 $opsect->add(sprintf("%s, %s, %s, %u, %u, %u, 0x%x, 0x%x",
366 $op->next, $op->sibling, $op->fake_ppaddr, $op->targ,
a798dbf2 367 $op->type, $op_seq, $op->flags, $op->private));
dc333d64 368 my $ix = $opsect->index;
b326da91 369 $init->add(sprintf("op_list[$ix].op_ppaddr = %s;", $op->ppaddr))
370 unless $optimize_ppaddr;
dc333d64 371 return "&op_list[$ix]";
a798dbf2 372}
373
374sub B::FAKEOP::next { $_[0]->{"next"} || 0 }
375sub B::FAKEOP::type { $_[0]->{type} || 0}
376sub B::FAKEOP::sibling { $_[0]->{sibling} || 0 }
377sub B::FAKEOP::ppaddr { $_[0]->{ppaddr} || 0 }
378sub B::FAKEOP::targ { $_[0]->{targ} || 0 }
379sub B::FAKEOP::flags { $_[0]->{flags} || 0 }
380sub B::FAKEOP::private { $_[0]->{private} || 0 }
381
382sub B::UNOP::save {
383 my ($op, $level) = @_;
2c0b28dd 384 my $sym = objsym($op);
385 return $sym if defined $sym;
b326da91 386 $unopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x",
387 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr,
a798dbf2 388 $op->targ, $op->type, $op_seq, $op->flags,
389 $op->private, ${$op->first}));
dc333d64 390 my $ix = $unopsect->index;
b326da91 391 $init->add(sprintf("unop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
392 unless $optimize_ppaddr;
dc333d64 393 savesym($op, "(OP*)&unop_list[$ix]");
a798dbf2 394}
395
396sub B::BINOP::save {
397 my ($op, $level) = @_;
2c0b28dd 398 my $sym = objsym($op);
399 return $sym if defined $sym;
b326da91 400 $binopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x",
401 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr,
a798dbf2 402 $op->targ, $op->type, $op_seq, $op->flags,
403 $op->private, ${$op->first}, ${$op->last}));
dc333d64 404 my $ix = $binopsect->index;
b326da91 405 $init->add(sprintf("binop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
406 unless $optimize_ppaddr;
dc333d64 407 savesym($op, "(OP*)&binop_list[$ix]");
a798dbf2 408}
409
410sub B::LISTOP::save {
411 my ($op, $level) = @_;
2c0b28dd 412 my $sym = objsym($op);
413 return $sym if defined $sym;
b326da91 414 $listopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x",
415 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr,
a798dbf2 416 $op->targ, $op->type, $op_seq, $op->flags,
117dada2 417 $op->private, ${$op->first}, ${$op->last}));
dc333d64 418 my $ix = $listopsect->index;
b326da91 419 $init->add(sprintf("listop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
420 unless $optimize_ppaddr;
dc333d64 421 savesym($op, "(OP*)&listop_list[$ix]");
a798dbf2 422}
423
424sub B::LOGOP::save {
425 my ($op, $level) = @_;
2c0b28dd 426 my $sym = objsym($op);
427 return $sym if defined $sym;
b326da91 428 $logopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x",
429 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr,
a798dbf2 430 $op->targ, $op->type, $op_seq, $op->flags,
431 $op->private, ${$op->first}, ${$op->other}));
dc333d64 432 my $ix = $logopsect->index;
b326da91 433 $init->add(sprintf("logop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
434 unless $optimize_ppaddr;
dc333d64 435 savesym($op, "(OP*)&logop_list[$ix]");
a798dbf2 436}
437
a798dbf2 438sub B::LOOP::save {
439 my ($op, $level) = @_;
2c0b28dd 440 my $sym = objsym($op);
441 return $sym if defined $sym;
a798dbf2 442 #warn sprintf("LOOP: redoop %s, nextop %s, lastop %s\n",
443 # peekop($op->redoop), peekop($op->nextop),
444 # peekop($op->lastop)); # debug
b326da91 445 $loopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x, s\\_%x, s\\_%x, s\\_%x",
446 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr,
a798dbf2 447 $op->targ, $op->type, $op_seq, $op->flags,
448 $op->private, ${$op->first}, ${$op->last},
117dada2 449 ${$op->redoop}, ${$op->nextop},
a798dbf2 450 ${$op->lastop}));
dc333d64 451 my $ix = $loopsect->index;
b326da91 452 $init->add(sprintf("loop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
453 unless $optimize_ppaddr;
dc333d64 454 savesym($op, "(OP*)&loop_list[$ix]");
a798dbf2 455}
456
457sub B::PVOP::save {
458 my ($op, $level) = @_;
2c0b28dd 459 my $sym = objsym($op);
460 return $sym if defined $sym;
b326da91 461 $pvopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, %s",
462 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr,
a798dbf2 463 $op->targ, $op->type, $op_seq, $op->flags,
464 $op->private, cstring($op->pv)));
dc333d64 465 my $ix = $pvopsect->index;
b326da91 466 $init->add(sprintf("pvop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
467 unless $optimize_ppaddr;
dc333d64 468 savesym($op, "(OP*)&pvop_list[$ix]");
a798dbf2 469}
470
471sub B::SVOP::save {
472 my ($op, $level) = @_;
2c0b28dd 473 my $sym = objsym($op);
474 return $sym if defined $sym;
9d2bbe64 475 my $sv = $op->sv;
476 my $svsym = '(SV*)' . $sv->save;
477 my $is_const_addr = $svsym =~ m/Null|\&/;
478 $svopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, %s",
b326da91 479 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr,
a798dbf2 480 $op->targ, $op->type, $op_seq, $op->flags,
9d2bbe64 481 $op->private,
482 ( $is_const_addr ? $svsym : 'Nullsv' )));
dc333d64 483 my $ix = $svopsect->index;
b326da91 484 $init->add(sprintf("svop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
485 unless $optimize_ppaddr;
9d2bbe64 486 $init->add("svop_list[$ix].op_sv = $svsym;")
487 unless $is_const_addr;
dc333d64 488 savesym($op, "(OP*)&svop_list[$ix]");
a798dbf2 489}
490
7934575e 491sub B::PADOP::save {
a798dbf2 492 my ($op, $level) = @_;
2c0b28dd 493 my $sym = objsym($op);
494 return $sym if defined $sym;
9d2bbe64 495 $padopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, %d",
b326da91 496 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr,
a798dbf2 497 $op->targ, $op->type, $op_seq, $op->flags,
9d2bbe64 498 $op->private,$op->padix));
dc333d64 499 my $ix = $padopsect->index;
b326da91 500 $init->add(sprintf("padop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
501 unless $optimize_ppaddr;
9d2bbe64 502# $init->add(sprintf("padop_list[$ix].op_padix = %ld;", $op->padix));
dc333d64 503 savesym($op, "(OP*)&padop_list[$ix]");
a798dbf2 504}
505
506sub B::COP::save {
507 my ($op, $level) = @_;
2c0b28dd 508 my $sym = objsym($op);
509 return $sym if defined $sym;
57843af0 510 warn sprintf("COP: line %d file %s\n", $op->line, $op->file)
a798dbf2 511 if $debug_cops;
b326da91 512 # shameless cut'n'paste from B::Deparse
513 my $warn_sv;
514 my $warnings = $op->warnings;
515 my $is_special = $warnings->isa("B::SPECIAL");
516 if ($is_special && $$warnings == 4) {
517 # use warnings 'all';
518 $warn_sv = $optimize_warn_sv ?
519 'INT2PTR(SV*,1)' :
520 'pWARN_ALL';
521 }
522 elsif ($is_special && $$warnings == 5) {
523 # no warnings 'all';
524 $warn_sv = $optimize_warn_sv ?
9d2bbe64 525 'INT2PTR(SV*,2)' :
b326da91 526 'pWARN_NONE';
527 }
528 elsif ($is_special) {
529 # use warnings;
530 $warn_sv = $optimize_warn_sv ?
9d2bbe64 531 'INT2PTR(SV*,3)' :
b326da91 532 'pWARN_STD';
533 }
534 else {
535 # something else
536 $warn_sv = $warnings->save;
537 }
538
539 $copsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, %s, NULL, NULL, %u, %d, %u, %s",
540 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr,
a798dbf2 541 $op->targ, $op->type, $op_seq, $op->flags,
542 $op->private, cstring($op->label), $op->cop_seq,
b326da91 543 $op->arybase, $op->line,
544 ( $optimize_warn_sv ? $warn_sv : 'NULL' )));
dc333d64 545 my $ix = $copsect->index;
b326da91 546 $init->add(sprintf("cop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
547 unless $optimize_ppaddr;
548 $init->add(sprintf("cop_list[$ix].cop_warnings = %s;", $warn_sv ))
549 unless $optimize_warn_sv;
dc333d64 550 $init->add(sprintf("CopFILE_set(&cop_list[$ix], %s);", cstring($op->file)),
551 sprintf("CopSTASHPV_set(&cop_list[$ix], %s);", cstring($op->stashpv)));
b326da91 552
dc333d64 553 savesym($op, "(OP*)&cop_list[$ix]");
a798dbf2 554}
555
556sub B::PMOP::save {
557 my ($op, $level) = @_;
2c0b28dd 558 my $sym = objsym($op);
559 return $sym if defined $sym;
a798dbf2 560 my $replroot = $op->pmreplroot;
561 my $replstart = $op->pmreplstart;
9d2bbe64 562 my $replrootfield;
a798dbf2 563 my $replstartfield = sprintf("s\\_%x", $$replstart);
564 my $gvsym;
565 my $ppaddr = $op->ppaddr;
9d2bbe64 566 # under ithreads, OP_PUSHRE.op_replroot is an integer
567 $replrootfield = sprintf("s\\_%x", $$replroot) if ref $replroot;
568 if($ithreads && $op->name eq "pushre") {
569 $replrootfield = "INT2PTR(OP*,${replroot})";
570 } elsif ($$replroot) {
a798dbf2 571 # OP_PUSHRE (a mutated version of OP_MATCH for the regexp
572 # argument to a split) stores a GV in op_pmreplroot instead
573 # of a substitution syntax tree. We don't want to walk that...
3f872cb9 574 if ($op->name eq "pushre") {
a798dbf2 575 $gvsym = $replroot->save;
576# warn "PMOP::save saving a pp_pushre with GV $gvsym\n"; # debug
577 $replrootfield = 0;
578 } else {
579 $replstartfield = saveoptree("*ignore*", $replroot, $replstart);
580 }
581 }
582 # pmnext handling is broken in perl itself, I think. Bad op_pmnext
583 # fields aren't noticed in perl's runtime (unless you try reset) but we
584 # segfault when trying to dereference it to find op->op_pmnext->op_type
9d2bbe64 585 $pmopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x, %s, %s, 0, %u, 0x%x, 0x%x, 0x%x",
b326da91 586 ${$op->next}, ${$op->sibling}, $op->fake_ppaddr, $op->targ,
a798dbf2 587 $op->type, $op_seq, $op->flags, $op->private,
117dada2 588 ${$op->first}, ${$op->last},
a798dbf2 589 $replrootfield, $replstartfield,
9d2bbe64 590 ( $ithreads ? $op->pmoffset : 0 ),
591 $op->pmflags, $op->pmpermflags, $op->pmdynflags ));
a798dbf2 592 my $pm = sprintf("pmop_list[%d]", $pmopsect->index);
b326da91 593 $init->add(sprintf("$pm.op_ppaddr = %s;", $ppaddr))
594 unless $optimize_ppaddr;
a798dbf2 595 my $re = $op->precomp;
596 if (defined($re)) {
b326da91 597 my( $resym, $relen ) = savere( $re );
f5eac215 598 $init->add(sprintf("PM_SETRE(&$pm,pregcomp($resym, $resym + %u, &$pm));",
b326da91 599 $relen));
a798dbf2 600 }
601 if ($gvsym) {
602 $init->add("$pm.op_pmreplroot = (OP*)$gvsym;");
603 }
dc333d64 604 savesym($op, "(OP*)&$pm");
a798dbf2 605}
606
607sub B::SPECIAL::save {
608 my ($sv) = @_;
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";
614 }
615 return $sym;
616}
617
618sub B::OBJECT::save {}
619
620sub B::NULL::save {
621 my ($sv) = @_;
622 my $sym = objsym($sv);
623 return $sym if defined $sym;
624# warn "Saving SVt_NULL SV\n"; # debug
625 # debug
87d7fd28 626 if ($$sv == 0) {
627 warn "NULL::save for sv = 0 called from @{[(caller(1))[3]]}\n";
b326da91 628 return savesym($sv, "(void*)Nullsv /* XXX */");
87d7fd28 629 }
932e9ff9 630 $svsect->add(sprintf("0, %u, 0x%x", $sv->REFCNT , $sv->FLAGS));
a798dbf2 631 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
632}
633
634sub B::IV::save {
635 my ($sv) = @_;
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",
932e9ff9 640 $xpvivsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 641 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
642}
643
644sub B::NV::save {
645 my ($sv) = @_;
646 my $sym = objsym($sv);
647 return $sym if defined $sym;
56eca212 648 my $val= $sv->NVX;
649 $val .= '.00' if $val =~ /^-?\d+$/;
650 $xpvnvsect->add(sprintf("0, 0, 0, %d, %s", $sv->IVX, $val));
a798dbf2 651 $svsect->add(sprintf("&xpvnv_list[%d], %lu, 0x%x",
932e9ff9 652 $xpvnvsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 653 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
654}
655
dc333d64 656sub savepvn {
657 my ($dest,$pv) = @_;
658 my @res;
b326da91 659 # work with byte offsets/lengths
660 my $pv = pack "a*", $pv;
dc333d64 661 if (defined $max_string_len && length($pv) > $max_string_len) {
662 push @res, sprintf("New(0,%s,%u,char);", $dest, length($pv)+1);
663 my $offset = 0;
664 while (length $pv) {
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;
669 }
670 push @res, sprintf("%s[%u] = '\\0';", $dest, $offset);
671 }
672 else {
673 push @res, sprintf("%s = savepvn(%s, %u);", $dest,
674 cstring($pv), length($pv));
675 }
676 return @res;
677}
678
a798dbf2 679sub B::PVLV::save {
680 my ($sv) = @_;
681 my $sym = objsym($sv);
682 return $sym if defined $sym;
683 my $pv = $sv->PV;
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",
932e9ff9 691 $xpvlvsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 692 if (!$pv_copy_on_grow) {
dc333d64 693 $init->add(savepvn(sprintf("xpvlv_list[%d].xpv_pv",
694 $xpvlvsect->index), $pv));
a798dbf2 695 }
696 $sv->save_magic;
697 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
698}
699
700sub B::PVIV::save {
701 my ($sv) = @_;
702 my $sym = objsym($sv);
703 return $sym if defined $sym;
b326da91 704 my( $savesym, $pvmax, $len, $pv ) = save_pv_or_rv( $sv );
705 $xpvivsect->add(sprintf("%s, %u, %u, %d", $savesym, $len, $pvmax, $sv->IVX));
a798dbf2 706 $svsect->add(sprintf("&xpviv_list[%d], %u, 0x%x",
932e9ff9 707 $xpvivsect->index, $sv->REFCNT , $sv->FLAGS));
b326da91 708 if (defined($pv) && !$pv_copy_on_grow) {
dc333d64 709 $init->add(savepvn(sprintf("xpviv_list[%d].xpv_pv",
710 $xpvivsect->index), $pv));
a798dbf2 711 }
712 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
713}
714
715sub B::PVNV::save {
716 my ($sv) = @_;
717 my $sym = objsym($sv);
718 return $sym if defined $sym;
b326da91 719 my( $savesym, $pvmax, $len, $pv ) = save_pv_or_rv( $sv );
56eca212 720 my $val= $sv->NVX;
721 $val .= '.00' if $val =~ /^-?\d+$/;
a798dbf2 722 $xpvnvsect->add(sprintf("%s, %u, %u, %d, %s",
b326da91 723 $savesym, $len, $pvmax, $sv->IVX, $val));
a798dbf2 724 $svsect->add(sprintf("&xpvnv_list[%d], %lu, 0x%x",
932e9ff9 725 $xpvnvsect->index, $sv->REFCNT , $sv->FLAGS));
b326da91 726 if (defined($pv) && !$pv_copy_on_grow) {
dc333d64 727 $init->add(savepvn(sprintf("xpvnv_list[%d].xpv_pv",
728 $xpvnvsect->index), $pv));
a798dbf2 729 }
730 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
731}
732
733sub B::BM::save {
734 my ($sv) = @_;
735 my $sym = objsym($sv);
736 return $sym if defined $sym;
b326da91 737 my $pv = pack "a*", ($sv->PV . "\0" . $sv->TABLE);
a798dbf2 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",
932e9ff9 743 $xpvbmsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 744 $sv->save_magic;
dc333d64 745 $init->add(savepvn(sprintf("xpvbm_list[%d].xpv_pv",
746 $xpvbmsect->index), $pv),
a798dbf2 747 sprintf("xpvbm_list[%d].xpv_cur = %u;",
748 $xpvbmsect->index, $len - 257));
749 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
750}
751
752sub B::PV::save {
753 my ($sv) = @_;
754 my $sym = objsym($sv);
755 return $sym if defined $sym;
b326da91 756 my( $savesym, $pvmax, $len, $pv ) = save_pv_or_rv( $sv );
757 $xpvsect->add(sprintf("%s, %u, %u", $savesym, $len, $pvmax));
a798dbf2 758 $svsect->add(sprintf("&xpv_list[%d], %lu, 0x%x",
932e9ff9 759 $xpvsect->index, $sv->REFCNT , $sv->FLAGS));
b326da91 760 if (defined($pv) && !$pv_copy_on_grow) {
dc333d64 761 $init->add(savepvn(sprintf("xpv_list[%d].xpv_pv",
762 $xpvsect->index), $pv));
a798dbf2 763 }
764 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
765}
766
767sub B::PVMG::save {
768 my ($sv) = @_;
769 my $sym = objsym($sv);
770 return $sym if defined $sym;
b326da91 771 my( $savesym, $pvmax, $len, $pv ) = save_pv_or_rv( $sv );
772
a798dbf2 773 $xpvmgsect->add(sprintf("%s, %u, %u, %d, %s, 0, 0",
b326da91 774 $savesym, $len, $pvmax,
775 $sv->IVX, $sv->NVX));
a798dbf2 776 $svsect->add(sprintf("&xpvmg_list[%d], %lu, 0x%x",
b326da91 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));
a798dbf2 781 }
782 $sym = savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
783 $sv->save_magic;
784 return $sym;
785}
786
787sub B::PVMG::save_magic {
788 my ($sv) = @_;
789 #warn sprintf("saving magic for %s (0x%x)\n", class($sv), $$sv); # debug
790 my $stash = $sv->SvSTASH;
56eca212 791 $stash->save;
a798dbf2 792 if ($$stash) {
793 warn sprintf("xmg_stash = %s (0x%x)\n", $stash->NAME, $$stash)
794 if $debug_mg;
795 # XXX Hope stash is already going to be saved.
796 $init->add(sprintf("SvSTASH(s\\_%x) = s\\_%x;", $$sv, $$stash));
797 }
798 my @mgchain = $sv->MAGIC;
88b39979 799 my ($mg, $type, $obj, $ptr,$len,$ptrsv);
a798dbf2 800 foreach $mg (@mgchain) {
801 $type = $mg->TYPE;
a798dbf2 802 $ptr = $mg->PTR;
88b39979 803 $len=$mg->LENGTH;
a798dbf2 804 if ($debug_mg) {
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));
808 }
b326da91 809
810 unless( $type eq 'r' ) {
811 $obj = $mg->OBJ;
812 $obj->save;
813 }
814
88b39979 815 if ($len == HEf_SVKEY){
816 #The pointer is an SV*
817 $ptrsv=svref_2object($ptr)->save;
5ab5c7a4 818 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s,(char *) %s, %d);",
88b39979 819 $$sv, $$obj, cchar($type),$ptrsv,$len));
b326da91 820 }elsif( $type eq 'r' ){
9d2bbe64 821 my $rx = $mg->REGEX;
822 my $pmop = $REGEXP{$rx};
823
824 confess "PMOP not found for REGEXP $rx" unless $pmop;
825
826 my( $resym, $relen ) = savere( $mg->precomp );
827 my $pmsym = $pmop->save;
828 $init->add( split /\n/, sprintf <<CODE, $$sv, cchar($type), cstring($ptr) );
829{
830 REGEXP* rx = pregcomp($resym, $resym + $relen, (PMOP*)$pmsym);
831 sv_magic((SV*)s\\_%x, (SV*)rx, %s, %s, %d);
832}
833CODE
b326da91 834 }else{
88b39979 835 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
a798dbf2 836 $$sv, $$obj, cchar($type),cstring($ptr),$len));
88b39979 837 }
a798dbf2 838 }
839}
840
841sub B::RV::save {
842 my ($sv) = @_;
843 my $sym = objsym($sv);
844 return $sym if defined $sym;
b326da91 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));
850 }
851 # and stashes, too
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));
855 }
856 else {
857 $xrvsect->add($rv);
858 }
a798dbf2 859 $svsect->add(sprintf("&xrv_list[%d], %lu, 0x%x",
932e9ff9 860 $xrvsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 861 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
862}
863
864sub try_autoload {
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.
869 no strict 'refs';
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;
875 $dir =~ s(::)(/)g;
876 eval { require "auto/$dir/$cvname.al" };
877 if ($@) {
878 warn qq(failed require "auto/$dir/$cvname.al": $@\n);
879 return 0;
880 } else {
881 return 1;
882 }
883 }
884}
e9a14d94 885sub Dummy_initxs{};
a798dbf2 886sub B::CV::save {
887 my ($cv) = @_;
888 my $sym = objsym($cv);
889 if (defined($sym)) {
890# warn sprintf("CV 0x%x already saved as $sym\n", $$cv); # debug
891 return $sym;
892 }
893 # Reserve a place in svsect and xpvcvsect and record indices
af765ed9 894 my $gv = $cv->GV;
6771324e 895 my ($cvname, $cvstashname);
896 if ($$gv){
897 $cvname = $gv->NAME;
898 $cvstashname = $gv->STASH->NAME;
899 }
af765ed9 900 my $root = $cv->ROOT;
901 my $cvxsub = $cv->XSUB;
b326da91 902 my $isconst = $cv->CvFLAGS & CVf_CONST;
903 if( $isconst ) {
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" );
912 $cv_index++;
913 return $sym;
914 }
e9a14d94 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.
b326da91 918 if (!$isconst && $cvxsub && ($cvname ne "INIT")) {
af765ed9 919 my $egv = $gv->EGV;
920 my $stashname = $egv->STASH->NAME;
be6f3502 921 if ($cvname eq "bootstrap")
b326da91 922 {
923 my $file = $gv->FILE;
be6f3502 924 $decl->add("/* bootstrap $file */");
925 warn "Bootstrap $stashname $file\n";
b326da91 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';
931 $use_xsloader = 1;
932 }
933 else {
934 $xsub{$stashname}='Dynamic';
935 }
be6f3502 936 # $xsub{$stashname}='Static' unless $xsub{$stashname};
a0e9c8c7 937 return qq/NULL/;
b326da91 938 }
939 else
940 {
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);
947 }
a0e9c8c7 948 warn sprintf("stub for XSUB $cvstashname\:\:$cvname CV 0x%x\n", $$cv) if $debug_cv;
be6f3502 949 return qq/(perl_get_cv("$stashname\:\:$cvname",TRUE))/;
e9a14d94 950 }
951 if ($cvxsub && $cvname eq "INIT") {
952 no strict 'refs';
953 return svref_2object(\&Dummy_initxs)->save;
af765ed9 954 }
a798dbf2 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]");
a0e9c8c7 961 warn sprintf("saving $cvstashname\:\:$cvname CV 0x%x as $sym\n", $$cv) if $debug_cv;
a798dbf2 962 if (!$$root && !$cvxsub) {
963 if (try_autoload($cvstashname, $cvname)) {
964 # Recalculate root and xsub
965 $root = $cv->ROOT;
966 $cvxsub = $cv->XSUB;
967 if ($$root || $cvxsub) {
968 warn "Successful forced autoload\n";
969 }
970 }
971 }
972 my $startfield = 0;
973 my $padlist = $cv->PADLIST;
974 my $pv = $cv->PV;
975 my $xsub = 0;
976 my $xsubany = "Nullany";
977 if ($$root) {
978 warn sprintf("saving op tree for CV 0x%x, root = 0x%x\n",
979 $$cv, $$root) if $debug_cv;
980 my $ppname = "";
981 if ($$gv) {
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;
44887cfa 989 if ($gvname eq "INIT"){
990 $ppname .= "_$initsub_index";
991 $initsub_index++;
992 }
a798dbf2 993 }
994 }
995 if (!$ppname) {
996 $ppname = "pp_anonsub_$anonsub_index";
997 $anonsub_index++;
998 }
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;
1002 if ($$padlist) {
1003 warn sprintf("saving PADLIST 0x%x for CV 0x%x\n",
1004 $$padlist, $$cv) if $debug_cv;
1005 $padlist->save;
1006 warn sprintf("done saving PADLIST 0x%x for CV 0x%x\n",
1007 $$padlist, $$cv) if $debug_cv;
1008 }
1009 }
a798dbf2 1010 else {
1011 warn sprintf("No definition for sub %s::%s (unable to autoload)\n",
1012 $cvstashname, $cvname); # debug
66a2622e 1013 }
1014 $pv = '' unless defined $pv; # Avoid use of undef warnings
5712119f 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",
a798dbf2 1016 $xpvcv_ix, cstring($pv), length($pv), $cv->IVX,
1017 $cv->NVX, $startfield, ${$cv->ROOT}, $cv->DEPTH,
5cfd8ad4 1018 $$padlist, ${$cv->OUTSIDE}, $cv->CvFLAGS));
1019
1020 if (${$cv->OUTSIDE} == ${main_cv()}){
1021 $init->add(sprintf("CvOUTSIDE(s\\_%x)=PL_main_cv;",$$cv));
358b5eb8 1022 $init->add(sprintf("SvREFCNT_inc(PL_main_cv);"));
5cfd8ad4 1023 }
1024
a798dbf2 1025 if ($$gv) {
1026 $gv->save;
1027 $init->add(sprintf("CvGV(s\\_%x) = s\\_%x;",$$cv,$$gv));
1028 warn sprintf("done saving GV 0x%x for CV 0x%x\n",
1029 $$gv, $$cv) if $debug_cv;
1030 }
9d2bbe64 1031 if( $ithreads ) {
1032 $init->add( savepvn( "CvFILE($sym)", $cv->FILE) );
1033 }
1034 else {
1035 $init->add(sprintf("CvFILE($sym) = %s;", cstring($cv->FILE)));
1036 }
a798dbf2 1037 my $stash = $cv->STASH;
1038 if ($$stash) {
1039 $stash->save;
1040 $init->add(sprintf("CvSTASH(s\\_%x) = s\\_%x;", $$cv, $$stash));
1041 warn sprintf("done saving STASH 0x%x for CV 0x%x\n",
1042 $$stash, $$cv) if $debug_cv;
1043 }
1044 $symsect->add(sprintf("svix%d\t(XPVCV*)&xpvcv_list[%u], %lu, 0x%x",
9d2bbe64 1045 $sv_ix, $xpvcv_ix, $cv->REFCNT +1*0 , $cv->FLAGS));
a798dbf2 1046 return $sym;
1047}
1048
1049sub B::GV::save {
be6f3502 1050 my ($gv) = @_;
a798dbf2 1051 my $sym = objsym($gv);
1052 if (defined($sym)) {
1053 #warn sprintf("GV 0x%x already saved as $sym\n", $$gv); # debug
1054 return $sym;
1055 } else {
1056 my $ix = $gv_index++;
1057 $sym = savesym($gv, "gv_list[$ix]");
1058 #warn sprintf("Saving GV 0x%x as $sym\n", $$gv); # debug
1059 }
87d7fd28 1060 my $is_empty = $gv->is_empty;
a798dbf2 1061 my $gvname = $gv->NAME;
b326da91 1062 my $fullname = $gv->STASH->NAME . "::" . $gvname;
1063 my $name = cstring($fullname);
a798dbf2 1064 #warn "GV name is $name\n"; # debug
a798dbf2 1065 my $egvsym;
87d7fd28 1066 unless ($is_empty) {
1067 my $egv = $gv->EGV;
1068 if ($$gv != $$egv) {
1069 #warn(sprintf("EGV name is %s, saving it now\n",
1070 # $egv->STASH->NAME . "::" . $egv->NAME)); # debug
1071 $egvsym = $egv->save;
1072 }
a798dbf2 1073 }
1074 $init->add(qq[$sym = gv_fetchpv($name, TRUE, SVt_PV);],
9d2bbe64 1075 sprintf("SvFLAGS($sym) = 0x%x;", $gv->FLAGS ),
87d7fd28 1076 sprintf("GvFLAGS($sym) = 0x%x;", $gv->GvFLAGS));
1077 $init->add(sprintf("GvLINE($sym) = %u;", $gv->LINE)) unless $is_empty;
9d2bbe64 1078 # XXX hack for when Perl accesses PVX of GVs
1079 $init->add("SvPVX($sym) = emptystring;\n");
a798dbf2 1080 # Shouldn't need to do save_magic since gv_fetchpv handles that
1081 #$gv->save_magic;
9d2bbe64 1082 # XXX will always be > 1!!!
a798dbf2 1083 my $refcnt = $gv->REFCNT + 1;
9d2bbe64 1084 $init->add(sprintf("SvREFCNT($sym) += %u;", $refcnt - 1 )) if $refcnt > 1;
87d7fd28 1085
1086 return $sym if $is_empty;
1087
9d2bbe64 1088 # XXX B::walksymtable creates an extra reference to the GV
a798dbf2 1089 my $gvrefcnt = $gv->GvREFCNT;
1090 if ($gvrefcnt > 1) {
1091 $init->add(sprintf("GvREFCNT($sym) += %u;", $gvrefcnt - 1));
1092 }
b326da91 1093 # some non-alphavetic globs require some parts to be saved
1094 # ( ex. %!, but not $! )
1095 sub Save_HV() { 1 }
1096 sub Save_AV() { 2 }
1097 sub Save_SV() { 4 }
1098 sub Save_CV() { 8 }
1099 sub Save_FORM() { 16 }
1100 sub Save_IO() { 32 }
1101 my $savefields = 0;
1102 if( $gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/ ) {
1103 $savefields = Save_HV|Save_AV|Save_SV|Save_CV|Save_FORM|Save_IO;
1104 }
1105 elsif( $gvname eq '!' ) {
1106 $savefields = Save_HV;
1107 }
1108 # attributes::bootstrap is created in perl_parse
1109 # saving it would overwrite it, because perl_init() is
1110 # called after perl_parse()
1111 $savefields&=~Save_CV if $fullname eq 'attributes::bootstrap';
1112
1113 # save it
9d2bbe64 1114 # XXX is that correct?
1115 if (defined($egvsym) && $egvsym !~ m/Null/ ) {
a798dbf2 1116 # Shared glob *foo = *bar
1117 $init->add("gp_free($sym);",
1118 "GvGP($sym) = GvGP($egvsym);");
b326da91 1119 } elsif ($savefields) {
a798dbf2 1120 # Don't save subfields of special GVs (*_, *1, *# and so on)
1121# warn "GV::save saving subfields\n"; # debug
1122 my $gvsv = $gv->SV;
b326da91 1123 if ($$gvsv && $savefields&Save_SV) {
cfa4c8ee 1124 $gvsv->save;
a798dbf2 1125 $init->add(sprintf("GvSV($sym) = s\\_%x;", $$gvsv));
1126# warn "GV::save \$$name\n"; # debug
a798dbf2 1127 }
1128 my $gvav = $gv->AV;
b326da91 1129 if ($$gvav && $savefields&Save_AV) {
cfa4c8ee 1130 $gvav->save;
a798dbf2 1131 $init->add(sprintf("GvAV($sym) = s\\_%x;", $$gvav));
1132# warn "GV::save \@$name\n"; # debug
a798dbf2 1133 }
1134 my $gvhv = $gv->HV;
b326da91 1135 if ($$gvhv && $savefields&Save_HV) {
cfa4c8ee 1136 $gvhv->save;
a798dbf2 1137 $init->add(sprintf("GvHV($sym) = s\\_%x;", $$gvhv));
1138# warn "GV::save \%$name\n"; # debug
a798dbf2 1139 }
1140 my $gvcv = $gv->CV;
b326da91 1141 if ($$gvcv && $savefields&Save_CV) {
be6f3502 1142 my $origname=cstring($gvcv->GV->EGV->STASH->NAME .
1143 "::" . $gvcv->GV->EGV->NAME);
1144 if (0 && $gvcv->XSUB && $name ne $origname) { #XSUB alias
1145 # must save as a 'stub' so newXS() has a CV to populate
af765ed9 1146 $init->add("{ CV *cv;");
be6f3502 1147 $init->add("\tcv=perl_get_cv($origname,TRUE);");
af765ed9 1148 $init->add("\tGvCV($sym)=cv;");
1149 $init->add("\tSvREFCNT_inc((SV *)cv);");
be6f3502 1150 $init->add("}");
b326da91 1151 } else {
be6f3502 1152 $init->add(sprintf("GvCV($sym) = (CV*)(%s);", $gvcv->save));
1153# warn "GV::save &$name\n"; # debug
1154 }
af765ed9 1155 }
b195d487 1156 $init->add(sprintf("GvFILE($sym) = %s;", cstring($gv->FILE)));
1157# warn "GV::save GvFILE(*$name)\n"; # debug
a798dbf2 1158 my $gvform = $gv->FORM;
b326da91 1159 if ($$gvform && $savefields&Save_FORM) {
cfa4c8ee 1160 $gvform->save;
a798dbf2 1161 $init->add(sprintf("GvFORM($sym) = (CV*)s\\_%x;", $$gvform));
1162# warn "GV::save GvFORM(*$name)\n"; # debug
a798dbf2 1163 }
1164 my $gvio = $gv->IO;
b326da91 1165 if ($$gvio && $savefields&Save_IO) {
cfa4c8ee 1166 $gvio->save;
a798dbf2 1167 $init->add(sprintf("GvIOp($sym) = s\\_%x;", $$gvio));
b326da91 1168 if( $fullname =~ m/::DATA$/ && $save_data_fh ) {
1169 no strict 'refs';
1170 my $fh = *{$fullname}{IO};
1171 use strict 'refs';
1172 $gvio->save_data( $fullname, <$fh> ) if $fh->opened;
1173 }
a798dbf2 1174# warn "GV::save GvIO(*$name)\n"; # debug
a798dbf2 1175 }
1176 }
1177 return $sym;
1178}
9d2bbe64 1179
a798dbf2 1180sub B::AV::save {
1181 my ($av) = @_;
1182 my $sym = objsym($av);
1183 return $sym if defined $sym;
1184 my $avflags = $av->AvFLAGS;
1185 $xpvavsect->add(sprintf("0, -1, -1, 0, 0.0, 0, Nullhv, 0, 0, 0x%x",
1186 $avflags));
1187 $svsect->add(sprintf("&xpvav_list[%d], %lu, 0x%x",
932e9ff9 1188 $xpvavsect->index, $av->REFCNT , $av->FLAGS));
a798dbf2 1189 my $sv_list_index = $svsect->index;
1190 my $fill = $av->FILL;
1191 $av->save_magic;
1192 warn sprintf("saving AV 0x%x FILL=$fill AvFLAGS=0x%x", $$av, $avflags)
1193 if $debug_av;
1194 # XXX AVf_REAL is wrong test: need to save comppadlist but not stack
1195 #if ($fill > -1 && ($avflags & AVf_REAL)) {
1196 if ($fill > -1) {
1197 my @array = $av->ARRAY;
1198 if ($debug_av) {
1199 my $el;
1200 my $i = 0;
1201 foreach $el (@array) {
1202 warn sprintf("AV 0x%x[%d] = %s 0x%x\n",
1203 $$av, $i++, class($el), $$el);
1204 }
1205 }
9d2bbe64 1206# my @names = map($_->save, @array);
a798dbf2 1207 # XXX Better ways to write loop?
1208 # Perhaps svp[0] = ...; svp[1] = ...; svp[2] = ...;
1209 # Perhaps I32 i = 0; svp[i++] = ...; svp[i++] = ...; svp[i++] = ...;
9d2bbe64 1210
1211 # micro optimization: op/pat.t ( and other code probably )
1212 # has very large pads ( 20k/30k elements ) passing them to
1213 # ->add is a performance bottleneck: passing them as a
1214 # single string cuts runtime from 6min20sec to 40sec
1215
1216 # you want to keep this out of the no_split/split
1217 # map("\t*svp++ = (SV*)$_;", @names),
1218 my $acc = '';
1219 foreach my $i ( 0..$#array ) {
1220 $acc .= "\t*svp++ = (SV*)" . $array[$i]->save . ";\n\t";
1221 }
1222 $acc .= "\n";
1223
1224 $init->no_split;
a798dbf2 1225 $init->add("{",
1226 "\tSV **svp;",
1227 "\tAV *av = (AV*)&sv_list[$sv_list_index];",
1228 "\tav_extend(av, $fill);",
9d2bbe64 1229 "\tsvp = AvARRAY(av);" );
1230 $init->add($acc);
1231 $init->add("\tAvFILLp(av) = $fill;",
a798dbf2 1232 "}");
9d2bbe64 1233 $init->split;
1234 # we really added a lot of lines ( B::C::InitSection->add
1235 # should really scan for \n, but that would slow
1236 # it down
1237 $init->inc_count( $#array );
a798dbf2 1238 } else {
1239 my $max = $av->MAX;
1240 $init->add("av_extend((AV*)&sv_list[$sv_list_index], $max);")
1241 if $max > -1;
1242 }
1243 return savesym($av, "(AV*)&sv_list[$sv_list_index]");
1244}
1245
1246sub B::HV::save {
1247 my ($hv) = @_;
1248 my $sym = objsym($hv);
1249 return $sym if defined $sym;
1250 my $name = $hv->NAME;
1251 if ($name) {
1252 # It's a stash
1253
1254 # A perl bug means HvPMROOT isn't altered when a PMOP is freed. Usually
1255 # the only symptom is that sv_reset tries to reset the PMf_USED flag of
1256 # a trashed op but we look at the trashed op_type and segfault.
1257 #my $adpmroot = ${$hv->PMROOT};
1258 my $adpmroot = 0;
1259 $decl->add("static HV *hv$hv_index;");
1260 # XXX Beware of weird package names containing double-quotes, \n, ...?
1261 $init->add(qq[hv$hv_index = gv_stashpv("$name", TRUE);]);
1262 if ($adpmroot) {
1263 $init->add(sprintf("HvPMROOT(hv$hv_index) = (PMOP*)s\\_%x;",
1264 $adpmroot));
1265 }
1266 $sym = savesym($hv, "hv$hv_index");
1267 $hv_index++;
1268 return $sym;
1269 }
1270 # It's just an ordinary HV
1271 $xpvhvsect->add(sprintf("0, 0, %d, 0, 0.0, 0, Nullhv, %d, 0, 0, 0",
1272 $hv->MAX, $hv->RITER));
1273 $svsect->add(sprintf("&xpvhv_list[%d], %lu, 0x%x",
932e9ff9 1274 $xpvhvsect->index, $hv->REFCNT , $hv->FLAGS));
a798dbf2 1275 my $sv_list_index = $svsect->index;
1276 my @contents = $hv->ARRAY;
1277 if (@contents) {
1278 my $i;
1279 for ($i = 1; $i < @contents; $i += 2) {
1280 $contents[$i] = $contents[$i]->save;
1281 }
9d2bbe64 1282 $init->no_split;
a798dbf2 1283 $init->add("{", "\tHV *hv = (HV*)&sv_list[$sv_list_index];");
1284 while (@contents) {
1285 my ($key, $value) = splice(@contents, 0, 2);
1286 $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
b326da91 1287 cstring($key),length(pack "a*",$key),
1288 $value, hash($key)));
cf86991c 1289# $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
1290# cstring($key),length($key),$value, 0));
a798dbf2 1291 }
1292 $init->add("}");
9d2bbe64 1293 $init->split;
a798dbf2 1294 }
56eca212 1295 $hv->save_magic();
a798dbf2 1296 return savesym($hv, "(HV*)&sv_list[$sv_list_index]");
1297}
1298
b326da91 1299sub B::IO::save_data {
1300 my( $io, $globname, @data ) = @_;
1301 my $data = join '', @data;
1302
1303 # XXX using $DATA might clobber it!
1304 my $sym = svref_2object( \\$data )->save;
9d2bbe64 1305 $init->add( split /\n/, <<CODE );
b326da91 1306 {
1307 GV* gv = (GV*)gv_fetchpv( "$globname", TRUE, SVt_PV );
1308 SV* sv = $sym;
1309 GvSV( gv ) = sv;
1310 }
1311CODE
e934609f 1312 # for PerlIO::scalar
b326da91 1313 $use_xsloader = 1;
1314 $init->add_eval( sprintf 'open(%s, "<", $%s)', $globname, $globname );
1315}
1316
a798dbf2 1317sub B::IO::save {
1318 my ($io) = @_;
1319 my $sym = objsym($io);
1320 return $sym if defined $sym;
1321 my $pv = $io->PV;
66a2622e 1322 $pv = '' unless defined $pv;
a798dbf2 1323 my $len = length($pv);
1324 $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",
1325 $len, $len+1, $io->IVX, $io->NVX, $io->LINES,
1326 $io->PAGE, $io->PAGE_LEN, $io->LINES_LEFT,
1327 cstring($io->TOP_NAME), cstring($io->FMT_NAME),
1328 cstring($io->BOTTOM_NAME), $io->SUBPROCESS,
1329 cchar($io->IoTYPE), $io->IoFLAGS));
1330 $svsect->add(sprintf("&xpvio_list[%d], %lu, 0x%x",
932e9ff9 1331 $xpviosect->index, $io->REFCNT , $io->FLAGS));
a798dbf2 1332 $sym = savesym($io, sprintf("(IO*)&sv_list[%d]", $svsect->index));
b326da91 1333 # deal with $x = *STDIN/STDOUT/STDERR{IO}
1334 my $perlio_func;
1335 foreach ( qw(stdin stdout stderr) ) {
1336 $io->IsSTD($_) and $perlio_func = $_;
1337 }
1338 if( $perlio_func ) {
1339 $init->add( "IoIFP(${sym})=PerlIO_${perlio_func}();" );
1340 $init->add( "IoOFP(${sym})=PerlIO_${perlio_func}();" );
1341 }
1342
a798dbf2 1343 my ($field, $fsym);
1344 foreach $field (qw(TOP_GV FMT_GV BOTTOM_GV)) {
1345 $fsym = $io->$field();
1346 if ($$fsym) {
1347 $init->add(sprintf("Io$field($sym) = (GV*)s\\_%x;", $$fsym));
1348 $fsym->save;
1349 }
1350 }
1351 $io->save_magic;
1352 return $sym;
1353}
1354
1355sub B::SV::save {
1356 my $sv = shift;
1357 # This is where we catch an honest-to-goodness Nullsv (which gets
1358 # blessed into B::SV explicitly) and any stray erroneous SVs.
1359 return 0 unless $$sv;
1360 confess sprintf("cannot save that type of SV: %s (0x%x)\n",
1361 class($sv), $$sv);
1362}
1363
1364sub output_all {
1365 my $init_name = shift;
1366 my $section;
1367 my @sections = ($opsect, $unopsect, $binopsect, $logopsect, $condopsect,
7934575e 1368 $listopsect, $pmopsect, $svopsect, $padopsect, $pvopsect,
66a2622e 1369 $loopsect, $copsect, $svsect, $xpvsect,
a798dbf2 1370 $xpvavsect, $xpvhvsect, $xpvcvsect, $xpvivsect, $xpvnvsect,
1371 $xpvmgsect, $xpvlvsect, $xrvsect, $xpvbmsect, $xpviosect);
1372 $symsect->output(\*STDOUT, "#define %s\n");
1373 print "\n";
1374 output_declarations();
1375 foreach $section (@sections) {
1376 my $lines = $section->index + 1;
1377 if ($lines) {
1378 my $name = $section->name;
1379 my $typename = ($name eq "xpvcv") ? "XPVCV_or_similar" : uc($name);
1380 print "Static $typename ${name}_list[$lines];\n";
1381 }
1382 }
9d2bbe64 1383 # XXX hack for when Perl accesses PVX of GVs
1384 print 'Static char emptystring[] = "\0";';
1385
a798dbf2 1386 $decl->output(\*STDOUT, "%s\n");
1387 print "\n";
1388 foreach $section (@sections) {
1389 my $lines = $section->index + 1;
1390 if ($lines) {
1391 my $name = $section->name;
1392 my $typename = ($name eq "xpvcv") ? "XPVCV_or_similar" : uc($name);
1393 printf "static %s %s_list[%u] = {\n", $typename, $name, $lines;
9d2bbe64 1394 $section->output(\*STDOUT, "\t{ %s }, /* %d */\n");
a798dbf2 1395 print "};\n\n";
1396 }
1397 }
1398
9d2bbe64 1399 $init->output(\*STDOUT, "\t%s\n", $init_name );
a798dbf2 1400 if ($verbose) {
1401 warn compile_stats();
1402 warn "NULLOP count: $nullop_count\n";
1403 }
1404}
1405
1406sub output_declarations {
1407 print <<'EOT';
1408#ifdef BROKEN_STATIC_REDECL
1409#define Static extern
1410#else
1411#define Static static
1412#endif /* BROKEN_STATIC_REDECL */
1413
1414#ifdef BROKEN_UNION_INIT
1415/*
1416 * Cribbed from cv.h with ANY (a union) replaced by void*.
1417 * Some pre-Standard compilers can't cope with initialising unions. Ho hum.
1418 */
1419typedef struct {
1420 char * xpv_pv; /* pointer to malloced string */
1421 STRLEN xpv_cur; /* length of xp_pv as a C string */
1422 STRLEN xpv_len; /* allocated size */
1423 IV xof_off; /* integer value */
76ef7183 1424 NV xnv_nv; /* numeric value, if any */
a798dbf2 1425 MAGIC* xmg_magic; /* magic for scalar array */
1426 HV* xmg_stash; /* class package */
1427
1428 HV * xcv_stash;
1429 OP * xcv_start;
1430 OP * xcv_root;
acfe0abc 1431 void (*xcv_xsub) (pTHX_ CV*);
76ef7183 1432 ANY xcv_xsubany;
a798dbf2 1433 GV * xcv_gv;
57843af0 1434 char * xcv_file;
b195d487 1435 long xcv_depth; /* >= 2 indicates recursive call */
a798dbf2 1436 AV * xcv_padlist;
1437 CV * xcv_outside;
fc290457 1438 cv_flags_t xcv_flags;
a798dbf2 1439} XPVCV_or_similar;
1440#define ANYINIT(i) i
1441#else
1442#define XPVCV_or_similar XPVCV
1443#define ANYINIT(i) {i}
1444#endif /* BROKEN_UNION_INIT */
1445#define Nullany ANYINIT(0)
1446
1447#define UNUSED 0
1448#define sym_0 0
a798dbf2 1449EOT
1450 print "static GV *gv_list[$gv_index];\n" if $gv_index;
1451 print "\n";
1452}
1453
1454
1455sub output_boilerplate {
1456 print <<'EOT';
1457#include "EXTERN.h"
1458#include "perl.h"
93865851 1459#include "XSUB.h"
a798dbf2 1460
1461/* Workaround for mapstart: the only op which needs a different ppaddr */
3f872cb9 1462#undef Perl_pp_mapstart
1463#define Perl_pp_mapstart Perl_pp_grepstart
b326da91 1464#undef OP_MAPSTART
1465#define OP_MAPSTART OP_GREPSTART
511dd457 1466#define XS_DynaLoader_boot_DynaLoader boot_DynaLoader
5712119f 1467EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
a798dbf2 1468
5712119f 1469static void xs_init (pTHX);
1470static void dl_init (pTHX);
a798dbf2 1471static PerlInterpreter *my_perl;
1472EOT
1473}
1474
b326da91 1475sub init_op_addr {
1476 my( $op_type, $num ) = @_;
1477 my $op_list = $op_type."_list";
1478
1479 $init->add( split /\n/, <<EOT );
1480 {
1481 int i;
1482
1483 for( i = 0; i < ${num}; ++i )
1484 {
1485 ${op_list}\[i].op_ppaddr = PL_ppaddr[INT2PTR(int,${op_list}\[i].op_ppaddr)];
1486 }
1487 }
1488EOT
1489}
1490
1491sub init_op_warn {
1492 my( $op_type, $num ) = @_;
1493 my $op_list = $op_type."_list";
1494
1495 # for resons beyond imagination, MSVC5 considers pWARN_ALL non-const
1496 $init->add( split /\n/, <<EOT );
1497 {
1498 int i;
1499
1500 for( i = 0; i < ${num}; ++i )
1501 {
1502 switch( (int)(${op_list}\[i].cop_warnings) )
1503 {
1504 case 1:
1505 ${op_list}\[i].cop_warnings = pWARN_ALL;
1506 break;
1507 case 2:
1508 ${op_list}\[i].cop_warnings = pWARN_NONE;
1509 break;
1510 case 3:
1511 ${op_list}\[i].cop_warnings = pWARN_STD;
1512 break;
1513 default:
1514 break;
1515 }
1516 }
1517 }
1518EOT
1519}
1520
a798dbf2 1521sub output_main {
1522 print <<'EOT';
9d2bbe64 1523/* if USE_IMPLICIT_SYS, we need a 'real' exit */
1524#if defined(exit)
1525#undef exit
1526#endif
1527
a798dbf2 1528int
a798dbf2 1529main(int argc, char **argv, char **env)
a798dbf2 1530{
1531 int exitstatus;
1532 int i;
1533 char **fakeargv;
b326da91 1534 GV* tmpgv;
1535 SV* tmpsv;
9d2bbe64 1536 int options_count;
a798dbf2 1537
5712119f 1538 PERL_SYS_INIT3(&argc,&argv,&env);
9d2bbe64 1539
81009501 1540 if (!PL_do_undump) {
a798dbf2 1541 my_perl = perl_alloc();
1542 if (!my_perl)
1543 exit(1);
1544 perl_construct( my_perl );
5712119f 1545 PL_perl_destruct_level = 0;
a798dbf2 1546 }
9d2bbe64 1547EOT
1548 if( $ithreads ) {
1549 # XXX init free elems!
1550 my $pad_len = regex_padav->FILL + 1 - 1; # first is an avref
a798dbf2 1551
9d2bbe64 1552 print <<EOT;
1553#ifdef USE_ITHREADS
1554 for( i = 0; i < $pad_len; ++i ) {
1555 av_push( PL_regex_padav, newSViv(0) );
1556 }
1557 PL_regex_pad = AvARRAY( PL_regex_padav );
1558#endif
1559EOT
1560 }
1561
1562 print <<'EOT';
a798dbf2 1563#ifdef CSH
81009501 1564 if (!PL_cshlen)
1565 PL_cshlen = strlen(PL_cshname);
a798dbf2 1566#endif
1567
1568#ifdef ALLOW_PERL_OPTIONS
a798dbf2 1569#define EXTRA_OPTIONS 3
b326da91 1570#else
1571#define EXTRA_OPTIONS 4
a798dbf2 1572#endif /* ALLOW_PERL_OPTIONS */
1573 New(666, fakeargv, argc + EXTRA_OPTIONS + 1, char *);
b326da91 1574
a798dbf2 1575 fakeargv[0] = argv[0];
1576 fakeargv[1] = "-e";
1577 fakeargv[2] = "";
9d2bbe64 1578 options_count = 3;
b326da91 1579EOT
1580 # honour -T
9d2bbe64 1581 print <<EOT;
1582 if( ${^TAINT} ) {
1583 fakeargv[options_count] = "-T";
1584 ++options_count;
1585 }
1586EOT
b326da91 1587 print <<'EOT';
a798dbf2 1588#ifndef ALLOW_PERL_OPTIONS
9d2bbe64 1589 fakeargv[options_count] = "--";
1590 ++options_count;
a798dbf2 1591#endif /* ALLOW_PERL_OPTIONS */
1592 for (i = 1; i < argc; i++)
9d2bbe64 1593 fakeargv[i + options_count - 1] = argv[i];
1594 fakeargv[argc + options_count - 1] = 0;
b326da91 1595
9d2bbe64 1596 exitstatus = perl_parse(my_perl, xs_init, argc + options_count - 1,
a798dbf2 1597 fakeargv, NULL);
b326da91 1598
a798dbf2 1599 if (exitstatus)
1600 exit( exitstatus );
1601
b326da91 1602 TAINT;
1603EOT
1604
1605 if( $use_perl_script_name ) {
1606 my $dollar_0 = $0;
1607 $dollar_0 =~ s/\\/\\\\/g;
1608 $dollar_0 = '"' . $dollar_0 . '"';
1609
1610 print <<EOT;
1611 if ((tmpgv = gv_fetchpv("0",TRUE, SVt_PV))) {/* $0 */
1612 tmpsv = GvSV(tmpgv);
1613 sv_setpv(tmpsv, ${dollar_0});
1614 SvSETMAGIC(tmpsv);
1615 }
1616EOT
1617 }
ede8dd12 1618 else {
1619 print <<EOT;
1620 if ((tmpgv = gv_fetchpv("0",TRUE, SVt_PV))) {/* $0 */
1621 tmpsv = GvSV(tmpgv);
1622 sv_setpv(tmpsv, argv[0]);
1623 SvSETMAGIC(tmpsv);
1624 }
1625EOT
1626 }
b326da91 1627
1628 print <<'EOT';
1629 if ((tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))) {/* $^X */
1630 tmpsv = GvSV(tmpgv);
1631#ifdef WIN32
1632 sv_setpv(tmpsv,"perl.exe");
1633#else
1634 sv_setpv(tmpsv,"perl");
1635#endif
1636 SvSETMAGIC(tmpsv);
1637 }
1638
1639 TAINT_NOT;
1640
1641 /* PL_main_cv = PL_compcv; */
81009501 1642 PL_compcv = 0;
a798dbf2 1643
1644 exitstatus = perl_init();
1645 if (exitstatus)
1646 exit( exitstatus );
5712119f 1647 dl_init(aTHX);
a798dbf2 1648
1649 exitstatus = perl_run( my_perl );
1650
1651 perl_destruct( my_perl );
1652 perl_free( my_perl );
1653
5712119f 1654 PERL_SYS_TERM();
1655
a798dbf2 1656 exit( exitstatus );
1657}
1658
511dd457 1659/* yanked from perl.c */
a798dbf2 1660static void
5712119f 1661xs_init(pTHX)
a798dbf2 1662{
511dd457 1663 char *file = __FILE__;
af765ed9 1664 dTARG;
39644a26 1665 dSP;
a798dbf2 1666EOT
af765ed9 1667 print "\n#ifdef USE_DYNAMIC_LOADING";
1668 print qq/\n\tnewXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);/;
1669 print "\n#endif\n" ;
a0e9c8c7 1670 # delete $xsub{'DynaLoader'};
af765ed9 1671 delete $xsub{'UNIVERSAL'};
be6f3502 1672 print("/* bootstrapping code*/\n\tSAVETMPS;\n");
af765ed9 1673 print("\ttarg=sv_newmortal();\n");
b326da91 1674 print "#ifdef USE_DYNAMIC_LOADING\n";
a0e9c8c7 1675 print "\tPUSHMARK(sp);\n";
1676 print qq/\tXPUSHp("DynaLoader",strlen("DynaLoader"));\n/;
1677 print qq/\tPUTBACK;\n/;
5712119f 1678 print "\tboot_DynaLoader(aTHX_ NULL);\n";
a0e9c8c7 1679 print qq/\tSPAGAIN;\n/;
1680 print "#endif\n";
1681 foreach my $stashname (keys %xsub){
b326da91 1682 if ($xsub{$stashname} !~ m/Dynamic/ ) {
be6f3502 1683 my $stashxsub=$stashname;
1684 $stashxsub =~ s/::/__/g;
1685 print "\tPUSHMARK(sp);\n";
a0e9c8c7 1686 print qq/\tXPUSHp("$stashname",strlen("$stashname"));\n/;
1687 print qq/\tPUTBACK;\n/;
5712119f 1688 print "\tboot_$stashxsub(aTHX_ NULL);\n";
a0e9c8c7 1689 print qq/\tSPAGAIN;\n/;
be6f3502 1690 }
1691 }
1692 print("\tFREETMPS;\n/* end bootstrapping code */\n");
a0e9c8c7 1693 print "}\n";
be6f3502 1694
1695print <<'EOT';
1696static void
5712119f 1697dl_init(pTHX)
be6f3502 1698{
1699 char *file = __FILE__;
1700 dTARG;
39644a26 1701 dSP;
be6f3502 1702EOT
1703 print("/* Dynamicboot strapping code*/\n\tSAVETMPS;\n");
1704 print("\ttarg=sv_newmortal();\n");
1705 foreach my $stashname (@DynaLoader::dl_modules) {
1706 warn "Loaded $stashname\n";
b326da91 1707 if (exists($xsub{$stashname}) && $xsub{$stashname} =~ m/Dynamic/) {
be6f3502 1708 my $stashxsub=$stashname;
1709 $stashxsub =~ s/::/__/g;
1710 print "\tPUSHMARK(sp);\n";
a0e9c8c7 1711 print qq/\tXPUSHp("$stashname",/,length($stashname),qq/);\n/;
be6f3502 1712 print qq/\tPUTBACK;\n/;
b326da91 1713 print "#ifdef USE_DYNAMIC_LOADING\n";
af765ed9 1714 warn "bootstrapping $stashname added to xs_init\n";
b326da91 1715 if( $xsub{$stashname} eq 'Dynamic' ) {
1716 print qq/\tperl_call_method("bootstrap",G_DISCARD);\n/;
1717 }
1718 else {
1719 print qq/\tperl_call_pv("XSLoader::load",G_DISCARD);\n/;
1720 }
9d2bbe64 1721 print "#else\n";
5712119f 1722 print "\tboot_$stashxsub(aTHX_ NULL);\n";
be6f3502 1723 print "#endif\n";
1724 print qq/\tSPAGAIN;\n/;
1725 }
af765ed9 1726 }
be6f3502 1727 print("\tFREETMPS;\n/* end Dynamic bootstrapping code */\n");
a0e9c8c7 1728 print "}\n";
af765ed9 1729}
a798dbf2 1730sub dump_symtable {
1731 # For debugging
1732 my ($sym, $val);
1733 warn "----Symbol table:\n";
1734 while (($sym, $val) = each %symtable) {
1735 warn "$sym => $val\n";
1736 }
1737 warn "---End of symbol table\n";
1738}
1739
1740sub save_object {
1741 my $sv;
1742 foreach $sv (@_) {
1743 svref_2object($sv)->save;
1744 }
338a6d08 1745}
1746
1747sub Dummy_BootStrap { }
a798dbf2 1748
66a2622e 1749sub B::GV::savecv
1750{
1751 my $gv = shift;
1752 my $package=$gv->STASH->NAME;
1753 my $name = $gv->NAME;
1754 my $cv = $gv->CV;
7cf11ee8 1755 my $sv = $gv->SV;
1756 my $av = $gv->AV;
1757 my $hv = $gv->HV;
7cf11ee8 1758
b326da91 1759 my $fullname = $gv->STASH->NAME . "::" . $gv->NAME;
1760
66a2622e 1761 # We may be looking at this package just because it is a branch in the
1762 # symbol table which is on the path to a package which we need to save
7cf11ee8 1763 # e.g. this is 'Getopt' and we need to save 'Getopt::Long'
66a2622e 1764 #
7cf11ee8 1765 return unless ($unused_sub_packages{$package});
be6f3502 1766 return unless ($$cv || $$av || $$sv || $$hv);
1767 $gv->save;
66a2622e 1768}
5ed82aed 1769
66a2622e 1770sub mark_package
1771{
1772 my $package = shift;
1773 unless ($unused_sub_packages{$package})
1774 {
1775 no strict 'refs';
1776 $unused_sub_packages{$package} = 1;
6771324e 1777 if (defined @{$package.'::ISA'})
66a2622e 1778 {
1779 foreach my $isa (@{$package.'::ISA'})
1780 {
1781 if ($isa eq 'DynaLoader')
1782 {
1783 unless (defined(&{$package.'::bootstrap'}))
1784 {
1785 warn "Forcing bootstrap of $package\n";
1786 eval { $package->bootstrap };
1787 }
1788 }
a0e9c8c7 1789# else
66a2622e 1790 {
1791 unless ($unused_sub_packages{$isa})
1792 {
1793 warn "$isa saved (it is in $package\'s \@ISA)\n";
1794 mark_package($isa);
1795 }
1796 }
1797 }
1798 }
1799 }
1800 return 1;
1801}
1802
1803sub should_save
1804{
1805 no strict qw(vars refs);
1806 my $package = shift;
1807 $package =~ s/::$//;
1808 return $unused_sub_packages{$package} = 0 if ($package =~ /::::/); # skip ::::ISA::CACHE etc.
cf86991c 1809 # warn "Considering $package\n";#debug
66a2622e 1810 foreach my $u (grep($unused_sub_packages{$_},keys %unused_sub_packages))
1811 {
1812 # If this package is a prefix to something we are saving, traverse it
1813 # but do not mark it for saving if it is not already
1814 # e.g. to get to Getopt::Long we need to traverse Getopt but need
1815 # not save Getopt
1816 return 1 if ($u =~ /^$package\:\:/);
1817 }
1818 if (exists $unused_sub_packages{$package})
1819 {
cf86991c 1820 # warn "Cached $package is ".$unused_sub_packages{$package}."\n";
cfa4c8ee 1821 delete_unsaved_hashINC($package) unless $unused_sub_packages{$package} ;
1822 return $unused_sub_packages{$package};
66a2622e 1823 }
1824 # Omit the packages which we use (and which cause grief
1825 # because of fancy "goto &$AUTOLOAD" stuff).
1826 # XXX Surely there must be a nicer way to do this.
1827 if ($package eq "FileHandle" || $package eq "Config" ||
cf86991c 1828 $package eq "SelectSaver" || $package =~/^(B|IO)::/)
66a2622e 1829 {
cfa4c8ee 1830 delete_unsaved_hashINC($package);
66a2622e 1831 return $unused_sub_packages{$package} = 0;
1832 }
1833 # Now see if current package looks like an OO class this is probably too strong.
1834 foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE))
1835 {
b368a11e 1836 if (UNIVERSAL::can($package, $m))
66a2622e 1837 {
1838 warn "$package has method $m: saving package\n";#debug
1839 return mark_package($package);
1840 }
1841 }
cfa4c8ee 1842 delete_unsaved_hashINC($package);
66a2622e 1843 return $unused_sub_packages{$package} = 0;
a798dbf2 1844}
cfa4c8ee 1845sub delete_unsaved_hashINC{
1846 my $packname=shift;
1847 $packname =~ s/\:\:/\//g;
1848 $packname .= '.pm';
59c10aa2 1849# warn "deleting $packname" if $INC{$packname} ;# debug
cfa4c8ee 1850 delete $INC{$packname};
1851}
66a2622e 1852sub walkpackages
1853{
1854 my ($symref, $recurse, $prefix) = @_;
1855 my $sym;
1856 my $ref;
1857 no strict 'vars';
1858 local(*glob);
1859 $prefix = '' unless defined $prefix;
1860 while (($sym, $ref) = each %$symref)
1861 {
1862 *glob = $ref;
1863 if ($sym =~ /::$/)
1864 {
1865 $sym = $prefix . $sym;
b4e94495 1866 if ($sym ne "main::" && $sym ne "<none>::" && &$recurse($sym))
66a2622e 1867 {
1868 walkpackages(\%glob, $recurse, $sym);
1869 }
1870 }
1871 }
1872}
338a6d08 1873
1874
66a2622e 1875sub save_unused_subs
1876{
1877 no strict qw(refs);
a9b6343a 1878 &descend_marked_unused;
66a2622e 1879 warn "Prescan\n";
1880 walkpackages(\%{"main::"}, sub { should_save($_[0]); return 1 });
1881 warn "Saving methods\n";
1882 walksymtable(\%{"main::"}, "savecv", \&should_save);
a798dbf2 1883}
1884
0cc1d052 1885sub save_context
1886{
1887 my $curpad_nam = (comppadlist->ARRAY)[0]->save;
1888 my $curpad_sym = (comppadlist->ARRAY)[1]->save;
1889 my $inc_hv = svref_2object(\%INC)->save;
1890 my $inc_av = svref_2object(\@INC)->save;
56eca212 1891 my $amagic_generate= amagic_generation;
0cc1d052 1892 $init->add( "PL_curpad = AvARRAY($curpad_sym);",
1893 "GvHV(PL_incgv) = $inc_hv;",
1894 "GvAV(PL_incgv) = $inc_av;",
1895 "av_store(CvPADLIST(PL_main_cv),0,SvREFCNT_inc($curpad_nam));",
56eca212 1896 "av_store(CvPADLIST(PL_main_cv),1,SvREFCNT_inc($curpad_sym));",
1897 "PL_amagic_generation= $amagic_generate;" );
0cc1d052 1898}
1899
a9b6343a 1900sub descend_marked_unused {
1901 foreach my $pack (keys %unused_sub_packages)
1902 {
1903 mark_package($pack);
1904 }
1905}
73544139 1906
a798dbf2 1907sub save_main {
b326da91 1908 # this is mainly for the test suite
1909 my $warner = $SIG{__WARN__};
1910 local $SIG{__WARN__} = sub { print STDERR @_ };
1911
66a2622e 1912 warn "Starting compile\n";
66a2622e 1913 warn "Walking tree\n";
73544139 1914 seek(STDOUT,0,0); #exclude print statements in BEGIN{} into output
a798dbf2 1915 walkoptree(main_root, "save");
1916 warn "done main optree, walking symtable for extras\n" if $debug_cv;
66a2622e 1917 save_unused_subs();
b326da91 1918 # XSLoader was used, force saving of XSLoader::load
1919 if( $use_xsloader ) {
1920 my $cv = svref_2object( \&XSLoader::load );
1921 $cv->save;
1922 }
1923 # save %SIG ( in case it was set in a BEGIN block )
1924 if( $save_sig ) {
1925 local $SIG{__WARN__} = $warner;
9d2bbe64 1926 $init->no_split;
b326da91 1927 $init->add("{", "\tHV* hv = get_hv(\"main::SIG\",1);" );
1928 foreach my $k ( keys %SIG ) {
9d2bbe64 1929 next unless ref $SIG{$k};
b326da91 1930 my $cv = svref_2object( \$SIG{$k} );
1931 my $sv = $cv->save;
1932 $init->add('{',sprintf 'SV* sv = (SV*)%s;', $sv );
1933 $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
1934 cstring($k),length(pack "a*",$k),
1935 'sv', hash($k)));
1936 $init->add('mg_set(sv);','}');
1937 }
1938 $init->add('}');
9d2bbe64 1939 $init->split;
b326da91 1940 }
1941 # honour -w
1942 $init->add( sprintf " PL_dowarn = ( %s ) ? G_WARN_ON : G_WARN_OFF;", $^W );
1943 #
0cc1d052 1944 my $init_av = init_av->save;
b326da91 1945 my $end_av = end_av->save;
81009501 1946 $init->add(sprintf("PL_main_root = s\\_%x;", ${main_root()}),
1947 sprintf("PL_main_start = s\\_%x;", ${main_start()}),
b326da91 1948 "PL_initav = (AV *) $init_av;",
1949 "PL_endav = (AV*) $end_av;");
0cc1d052 1950 save_context();
b326da91 1951 # init op addrs ( must be the last action, otherwise
1952 # some ops might not be initialized
1953 if( $optimize_ppaddr ) {
1954 foreach my $i ( @op_sections ) {
1955 my $section = $$i;
1956 next unless $section->index >= 0;
1957 init_op_addr( $section->name, $section->index + 1);
1958 }
1959 }
1960 init_op_warn( $copsect->name, $copsect->index + 1)
1961 if $optimize_warn_sv && $copsect->index >= 0;
1962
5ed82aed 1963 warn "Writing output\n";
a798dbf2 1964 output_boilerplate();
1965 print "\n";
1966 output_all("perl_init");
1967 print "\n";
1968 output_main();
1969}
1970
1971sub init_sections {
b326da91 1972 my @sections = (decl => \$decl, sym => \$symsect,
a798dbf2 1973 binop => \$binopsect, condop => \$condopsect,
7934575e 1974 cop => \$copsect, padop => \$padopsect,
a798dbf2 1975 listop => \$listopsect, logop => \$logopsect,
1976 loop => \$loopsect, op => \$opsect, pmop => \$pmopsect,
1977 pvop => \$pvopsect, svop => \$svopsect, unop => \$unopsect,
1978 sv => \$svsect, xpv => \$xpvsect, xpvav => \$xpvavsect,
1979 xpvhv => \$xpvhvsect, xpvcv => \$xpvcvsect,
1980 xpviv => \$xpvivsect, xpvnv => \$xpvnvsect,
1981 xpvmg => \$xpvmgsect, xpvlv => \$xpvlvsect,
1982 xrv => \$xrvsect, xpvbm => \$xpvbmsect,
af765ed9 1983 xpvio => \$xpviosect);
a798dbf2 1984 my ($name, $sectref);
1985 while (($name, $sectref) = splice(@sections, 0, 2)) {
66a2622e 1986 $$sectref = new B::C::Section $name, \%symtable, 0;
a798dbf2 1987 }
b326da91 1988 $init = new B::C::InitSection 'init', \%symtable, 0;
1989}
0cc1d052 1990
1991sub mark_unused
1992{
1993 my ($arg,$val) = @_;
1994 $unused_sub_packages{$arg} = $val;
a798dbf2 1995}
1996
1997sub compile {
1998 my @options = @_;
1999 my ($option, $opt, $arg);
b326da91 2000 my @eval_at_startup;
2001 my %option_map = ( 'cog' => \$pv_copy_on_grow,
2002 'save-data' => \$save_data_fh,
2003 'ppaddr' => \$optimize_ppaddr,
2004 'warn-sv' => \$optimize_warn_sv,
2005 'use-script-name' => \$use_perl_script_name,
2006 'save-sig-hash' => \$save_sig,
2007 );
9d2bbe64 2008 my %optimization_map = ( 0 => [ qw() ], # special case
2009 1 => [ qw(-fcog) ],
2010 2 => [ qw(-fwarn-sv -fppaddr) ],
2011 );
a798dbf2 2012 OPTION:
2013 while ($option = shift @options) {
2014 if ($option =~ /^-(.)(.*)/) {
2015 $opt = $1;
2016 $arg = $2;
2017 } else {
2018 unshift @options, $option;
2019 last OPTION;
2020 }
2021 if ($opt eq "-" && $arg eq "-") {
2022 shift @options;
2023 last OPTION;
2024 }
2025 if ($opt eq "w") {
2026 $warn_undefined_syms = 1;
2027 } elsif ($opt eq "D") {
2028 $arg ||= shift @options;
2029 foreach $arg (split(//, $arg)) {
2030 if ($arg eq "o") {
2031 B->debug(1);
2032 } elsif ($arg eq "c") {
2033 $debug_cops = 1;
2034 } elsif ($arg eq "A") {
2035 $debug_av = 1;
2036 } elsif ($arg eq "C") {
2037 $debug_cv = 1;
2038 } elsif ($arg eq "M") {
2039 $debug_mg = 1;
2040 } else {
2041 warn "ignoring unknown debug option: $arg\n";
2042 }
2043 }
2044 } elsif ($opt eq "o") {
2045 $arg ||= shift @options;
2046 open(STDOUT, ">$arg") or return "$arg: $!\n";
2047 } elsif ($opt eq "v") {
2048 $verbose = 1;
2049 } elsif ($opt eq "u") {
2050 $arg ||= shift @options;
0cc1d052 2051 mark_unused($arg,undef);
a798dbf2 2052 } elsif ($opt eq "f") {
2053 $arg ||= shift @options;
b326da91 2054 $arg =~ m/(no-)?(.*)/;
2055 my $no = defined($1) && $1 eq 'no-';
2056 $arg = $no ? $2 : $arg;
2057 if( exists $option_map{$arg} ) {
2058 ${$option_map{$arg}} = !$no;
2059 } else {
2060 die "Invalid optimization '$arg'";
2061 }
a798dbf2 2062 } elsif ($opt eq "O") {
2063 $arg = 1 if $arg eq "";
9d2bbe64 2064 my @opt;
2065 foreach my $i ( 1 .. $arg ) {
2066 push @opt, @{$optimization_map{$i}}
2067 if exists $optimization_map{$i};
2068 }
2069 unshift @options, @opt;
b326da91 2070 } elsif ($opt eq "e") {
2071 push @eval_at_startup, $arg;
dc333d64 2072 } elsif ($opt eq "l") {
2073 $max_string_len = $arg;
a798dbf2 2074 }
2075 }
2076 init_sections();
b326da91 2077 foreach my $i ( @eval_at_startup ) {
2078 $init->add_eval( $i );
2079 }
a798dbf2 2080 if (@options) {
2081 return sub {
2082 my $objname;
2083 foreach $objname (@options) {
2084 eval "save_object(\\$objname)";
2085 }
2086 output_all();
2087 }
2088 } else {
2089 return sub { save_main() };
2090 }
2091}
2092
20931;
7f20e9dd 2094
2095__END__
2096
2097=head1 NAME
2098
2099B::C - Perl compiler's C backend
2100
2101=head1 SYNOPSIS
2102
2103 perl -MO=C[,OPTIONS] foo.pl
2104
2105=head1 DESCRIPTION
2106
1a52ab62 2107This compiler backend takes Perl source and generates C source code
2108corresponding to the internal structures that perl uses to run
2109your program. When the generated C source is compiled and run, it
2110cuts out the time which perl would have taken to load and parse
2111your program into its internal semi-compiled form. That means that
2112compiling with this backend will not help improve the runtime
2113execution speed of your program but may improve the start-up time.
2114Depending on the environment in which your program runs this may be
2115either a help or a hindrance.
2116
2117=head1 OPTIONS
2118
2119If there are any non-option arguments, they are taken to be
2120names of objects to be saved (probably doesn't work properly yet).
2121Without extra arguments, it saves the main program.
2122
2123=over 4
2124
2125=item B<-ofilename>
2126
2127Output to filename instead of STDOUT
2128
2129=item B<-v>
2130
2131Verbose compilation (currently gives a few compilation statistics).
2132
2133=item B<-->
2134
2135Force end of options
2136
2137=item B<-uPackname>
2138
2139Force apparently unused subs from package Packname to be compiled.
2140This allows programs to use eval "foo()" even when sub foo is never
2141seen to be used at compile time. The down side is that any subs which
2142really are never used also have code generated. This option is
2143necessary, for example, if you have a signal handler foo which you
2144initialise with C<$SIG{BAR} = "foo">. A better fix, though, is just
2145to change it to C<$SIG{BAR} = \&foo>. You can have multiple B<-u>
2146options. The compiler tries to figure out which packages may possibly
2147have subs in which need compiling but the current version doesn't do
2148it very well. In particular, it is confused by nested packages (i.e.
2149of the form C<A::B>) where package C<A> does not contain any subs.
2150
2151=item B<-D>
2152
2153Debug options (concatenated or separate flags like C<perl -D>).
2154
2155=item B<-Do>
2156
2157OPs, prints each OP as it's processed
2158
2159=item B<-Dc>
2160
2161COPs, prints COPs as processed (incl. file & line num)
2162
2163=item B<-DA>
2164
2165prints AV information on saving
2166
2167=item B<-DC>
2168
2169prints CV information on saving
2170
2171=item B<-DM>
2172
2173prints MAGIC information on saving
2174
2175=item B<-f>
2176
b326da91 2177Force options/optimisations on or off one at a time. You can explicitly
2178disable an option using B<-fno-option>. All options default to
2179B<disabled>.
2180
2181=over 4
1a52ab62 2182
2183=item B<-fcog>
2184
2185Copy-on-grow: PVs declared and initialised statically.
2186
b326da91 2187=item B<-fsave-data>
2188
2189Save package::DATA filehandles ( only available with PerlIO ).
1a52ab62 2190
b326da91 2191=item B<-fppaddr>
2192
2193Optimize the initialization of op_ppaddr.
2194
2195=item B<-fwarn-sv>
2196
2197Optimize the initialization of cop_warnings.
2198
2199=item B<-fuse-script-name>
2200
2201Use the script name instead of the program name as $0.
2202
2203=item B<-fsave-sig-hash>
2204
2205Save compile-time modifications to the %SIG hash.
2206
2207=back
1a52ab62 2208
2209=item B<-On>
2210
9d2bbe64 2211Optimisation level (n = 0, 1, 2, ...). B<-O> means B<-O1>.
2212
2213=over 4
2214
2215=item B<-O0>
2216
2217Disable all optimizations.
2218
2219=item B<-O1>
2220
2221Enable B<-fcog>.
2222
2223=item B<-O2>
2224
2225Enable B<-fppaddr>, B<-fwarn-sv>.
2226
2227=back
1a52ab62 2228
dc333d64 2229=item B<-llimit>
2230
2231Some C compilers impose an arbitrary limit on the length of string
2232constants (e.g. 2048 characters for Microsoft Visual C++). The
2233B<-llimit> options tells the C backend not to generate string literals
2234exceeding that limit.
2235
a45bd81d 2236=back
2237
1a52ab62 2238=head1 EXAMPLES
2239
2240 perl -MO=C,-ofoo.c foo.pl
2241 perl cc_harness -o foo foo.c
2242
2243Note that C<cc_harness> lives in the C<B> subdirectory of your perl
2244library directory. The utility called C<perlcc> may also be used to
2245help make use of this compiler.
2246
dc333d64 2247 perl -MO=C,-v,-DcA,-l2048 bar.pl > /dev/null
1a52ab62 2248
2249=head1 BUGS
2250
2251Plenty. Current status: experimental.
7f20e9dd 2252
2253=head1 AUTHOR
2254
2255Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>
2256
2257=cut