This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Reapply some perldoc changes not in 3.09.
[perl5.git] / ext / B / B / C.pm
CommitLineData
a798dbf2
MB
1# C.pm
2#
1a52ab62 3# Copyright (c) 1996, 1997, 1998 Malcolm Beattie
a798dbf2
MB
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
NIS
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
NIS
20 return $o;
21}
22
23sub add
b326da91 24{
66a2622e 25 my $section = shift;
b326da91 26 push(@{$section->[-1]{values}},@_);
66a2622e
NIS
27}
28
29sub index
b326da91 30{
66a2622e 31 my $section = shift;
b326da91 32 return scalar(@{$section->[-1]{values}})-1;
66a2622e
NIS
33}
34
35sub output
b326da91 36{
66a2622e
NIS
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
NIS
42 {
43 s{(s\\_[0-9a-f]+)}{ exists($sym->{$1}) ? $sym->{$1} : $default; }ge;
9d2bbe64
MB
44 printf $fh $format, $_, $i;
45 ++$i;
66a2622e
NIS
46 }
47}
48
b326da91
MB
49package B::C::InitSection;
50
9d2bbe64
MB
51# avoid use vars
52@B::C::InitSection::ISA = qw(B::C::Section);
b326da91
MB
53
54sub new {
55 my $class = shift;
9d2bbe64 56 my $max_lines = 10000; #pop;
b326da91
MB
57 my $section = $class->SUPER::new( @_ );
58
59 $section->[-1]{evals} = [];
9d2bbe64
MB
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
MB
65
66 return $section;
67}
68
9d2bbe64
MB
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
MB
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
MB
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
MB
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
MB
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
MB
147}
148
149
a798dbf2
MB
150package B::C;
151use Exporter ();
9d2bbe64
MB
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
NIS
163@EXPORT_OK = qw(output_all output_boilerplate output_main mark_unused
164 init_sections set_callback save_unused_subs objsym save_context);
a798dbf2
MB
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
MB
170use B::Asmdata qw(@specialsv_name);
171
172use FileHandle;
173use Carp;
174use strict;
f0cd5c3a 175use Config;
a798dbf2
MB
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
MB
184
185my %symtable;
af765ed9 186my %xsub;
a798dbf2
MB
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
MB
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
MB
201my $ithreads = $Config{useithreads} eq 'define';
202
a798dbf2
MB
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
MB
211 $pvopsect, $svopsect, $unopsect, $svsect, $xpvsect, $xpvavsect,
212 $xpvhvsect, $xpvcvsect, $xpvivsect, $xpvnvsect, $xpvmgsect, $xpvlvsect,
af765ed9 213 $xrvsect, $xpvbmsect, $xpviosect );
b326da91
MB
214my @op_sections = \( $binopsect, $condopsect, $copsect, $padopsect, $listopsect,
215 $logopsect, $loopsect, $opsect, $pmopsect, $pvopsect, $svopsect,
216 $unopsect );
a798dbf2
MB
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
NIS
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
MB
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
MB
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
MB
277 my $pvsym = 0;
278 my $pvmax = 0;
9d2bbe64
MB
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
MB
295 }
296 return ($pvsym, $pvmax);
297}
298
b326da91
MB
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
MB
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
MB
338sub B::OP::save {
339 my ($op, $level) = @_;
2c0b28dd
VB
340 my $sym = objsym($op);
341 return $sym if defined $sym;
a798dbf2
MB
342 my $type = $op->type;
343 $nullop_count++ unless $type;
0cc1d052 344 if ($type == $OP_THREADSV) {
a798dbf2
MB
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
MB
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
MB
353 $init->add(sprintf("op_list[$ix].op_ppaddr = %s;", $op->ppaddr))
354 unless $optimize_ppaddr;
dc333d64 355 savesym($op, "&op_list[$ix]");
a798dbf2
MB
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
MB
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
MB
369 $init->add(sprintf("op_list[$ix].op_ppaddr = %s;", $op->ppaddr))
370 unless $optimize_ppaddr;
dc333d64 371 return "&op_list[$ix]";
a798dbf2
MB
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
VB
384 my $sym = objsym($op);
385 return $sym if defined $sym;
b326da91
MB
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
MB
388 $op->targ, $op->type, $op_seq, $op->flags,
389 $op->private, ${$op->first}));
dc333d64 390 my $ix = $unopsect->index;
b326da91
MB
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
MB
394}
395
396sub B::BINOP::save {
397 my ($op, $level) = @_;
2c0b28dd
VB
398 my $sym = objsym($op);
399 return $sym if defined $sym;
b326da91
MB
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
MB
402 $op->targ, $op->type, $op_seq, $op->flags,
403 $op->private, ${$op->first}, ${$op->last}));
dc333d64 404 my $ix = $binopsect->index;
b326da91
MB
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
MB
408}
409
410sub B::LISTOP::save {
411 my ($op, $level) = @_;
2c0b28dd
VB
412 my $sym = objsym($op);
413 return $sym if defined $sym;
b326da91
MB
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
MB
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
MB
422}
423
424sub B::LOGOP::save {
425 my ($op, $level) = @_;
2c0b28dd
VB
426 my $sym = objsym($op);
427 return $sym if defined $sym;
b326da91
MB
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
MB
430 $op->targ, $op->type, $op_seq, $op->flags,
431 $op->private, ${$op->first}, ${$op->other}));
dc333d64 432 my $ix = $logopsect->index;
b326da91
MB
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
MB
436}
437
a798dbf2
MB
438sub B::LOOP::save {
439 my ($op, $level) = @_;
2c0b28dd
VB
440 my $sym = objsym($op);
441 return $sym if defined $sym;
a798dbf2
MB
442 #warn sprintf("LOOP: redoop %s, nextop %s, lastop %s\n",
443 # peekop($op->redoop), peekop($op->nextop),
444 # peekop($op->lastop)); # debug
b326da91
MB
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
MB
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
MB
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
MB
455}
456
457sub B::PVOP::save {
458 my ($op, $level) = @_;
2c0b28dd
VB
459 my $sym = objsym($op);
460 return $sym if defined $sym;
b326da91
MB
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
MB
463 $op->targ, $op->type, $op_seq, $op->flags,
464 $op->private, cstring($op->pv)));
dc333d64 465 my $ix = $pvopsect->index;
b326da91
MB
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
MB
469}
470
471sub B::SVOP::save {
472 my ($op, $level) = @_;
2c0b28dd
VB
473 my $sym = objsym($op);
474 return $sym if defined $sym;
9d2bbe64
MB
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
MB
481 $op->private,
482 ( $is_const_addr ? $svsym : 'Nullsv' )));
dc333d64 483 my $ix = $svopsect->index;
b326da91
MB
484 $init->add(sprintf("svop_list[$ix].op_ppaddr = %s;", $op->ppaddr))
485 unless $optimize_ppaddr;
9d2bbe64
MB
486 $init->add("svop_list[$ix].op_sv = $svsym;")
487 unless $is_const_addr;
dc333d64 488 savesym($op, "(OP*)&svop_list[$ix]");
a798dbf2
MB
489}
490
7934575e 491sub B::PADOP::save {
a798dbf2 492 my ($op, $level) = @_;
2c0b28dd
VB
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
MB
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
MB
504}
505
506sub B::COP::save {
507 my ($op, $level) = @_;
2c0b28dd
VB
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
MB
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
MB
526 'pWARN_NONE';
527 }
528 elsif ($is_special) {
529 # use warnings;
530 $warn_sv = $optimize_warn_sv ?
9d2bbe64 531 'INT2PTR(SV*,3)' :
b326da91
MB
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
MB
541 $op->targ, $op->type, $op_seq, $op->flags,
542 $op->private, cstring($op->label), $op->cop_seq,
b326da91
MB
543 $op->arybase, $op->line,
544 ( $optimize_warn_sv ? $warn_sv : 'NULL' )));
dc333d64 545 my $ix = $copsect->index;
b326da91
MB
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
GS
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
MB
554}
555
556sub B::PMOP::save {
557 my ($op, $level) = @_;
2c0b28dd
VB
558 my $sym = objsym($op);
559 return $sym if defined $sym;
a798dbf2
MB
560 my $replroot = $op->pmreplroot;
561 my $replstart = $op->pmreplstart;
9d2bbe64 562 my $replrootfield;
a798dbf2
MB
563 my $replstartfield = sprintf("s\\_%x", $$replstart);
564 my $gvsym;
565 my $ppaddr = $op->ppaddr;
9d2bbe64
MB
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
MB
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
MB
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
MB
590 ( $ithreads ? $op->pmoffset : 0 ),
591 $op->pmflags, $op->pmpermflags, $op->pmdynflags ));
a798dbf2 592 my $pm = sprintf("pmop_list[%d]", $pmopsect->index);
b326da91
MB
593 $init->add(sprintf("$pm.op_ppaddr = %s;", $ppaddr))
594 unless $optimize_ppaddr;
a798dbf2
MB
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
MB
600 }
601 if ($gvsym) {
602 $init->add("$pm.op_pmreplroot = (OP*)$gvsym;");
603 }
dc333d64 604 savesym($op, "(OP*)&$pm");
a798dbf2
MB
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
GS
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
MB
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
MB
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
GS
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
MB
653 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
654}
655
dc333d64
GS
656sub savepvn {
657 my ($dest,$pv) = @_;
658 my @res;
b326da91
MB
659 # work with byte offsets/lengths
660 my $pv = pack "a*", $pv;
dc333d64
GS
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
MB
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
GS
693 $init->add(savepvn(sprintf("xpvlv_list[%d].xpv_pv",
694 $xpvlvsect->index), $pv));
a798dbf2
MB
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
MB
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
GS
709 $init->add(savepvn(sprintf("xpviv_list[%d].xpv_pv",
710 $xpvivsect->index), $pv));
a798dbf2
MB
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
GS
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
GS
727 $init->add(savepvn(sprintf("xpvnv_list[%d].xpv_pv",
728 $xpvnvsect->index), $pv));
a798dbf2
MB
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
MB
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
GS
745 $init->add(savepvn(sprintf("xpvbm_list[%d].xpv_pv",
746 $xpvbmsect->index), $pv),
a798dbf2
MB
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
MB
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
GS
761 $init->add(savepvn(sprintf("xpv_list[%d].xpv_pv",
762 $xpvsect->index), $pv));
a798dbf2
MB
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
MB
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
MB
774 $savesym, $len, $pvmax,
775 $sv->IVX, $sv->NVX));
a798dbf2 776 $svsect->add(sprintf("&xpvmg_list[%d], %lu, 0x%x",
b326da91
MB
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
MB
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
MB
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
MB
800 foreach $mg (@mgchain) {
801 $type = $mg->TYPE;
a798dbf2 802 $ptr = $mg->PTR;
88b39979 803 $len=$mg->LENGTH;
a798dbf2
MB
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
MB
809
810 unless( $type eq 'r' ) {
811 $obj = $mg->OBJ;
812 $obj->save;
813 }
814
88b39979
VB
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
MB
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
MB
838 }
839}
840
841sub B::RV::save {
842 my ($sv) = @_;
843 my $sym = objsym($sv);
844 return $sym if defined $sym;
b326da91
MB
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
MB
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
MB
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
VB
895 my ($cvname, $cvstashname);
896 if ($$gv){
897 $cvname = $gv->NAME;
898 $cvstashname = $gv->STASH->NAME;
899 }
af765ed9
VB
900 my $root = $cv->ROOT;
901 my $cvxsub = $cv->XSUB;
b326da91
MB
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
VB
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
VB
919 my $egv = $gv->EGV;
920 my $stashname = $egv->STASH->NAME;
be6f3502 921 if ($cvname eq "bootstrap")
b326da91
MB
922 {
923 my $file = $gv->FILE;
be6f3502
NIS
924 $decl->add("/* bootstrap $file */");
925 warn "Bootstrap $stashname $file\n";
b326da91
MB
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
MB
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
VB
950 }
951 if ($cvxsub && $cvname eq "INIT") {
952 no strict 'refs';
953 return svref_2object(\&Dummy_initxs)->save;
af765ed9 954 }
a798dbf2
MB
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
MB
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
NIS
989 if ($gvname eq "INIT"){
990 $ppname .= "_$initsub_index";
991 $initsub_index++;
992 }
a798dbf2
MB
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
MB
1010 else {
1011 warn sprintf("No definition for sub %s::%s (unable to autoload)\n",
1012 $cvstashname, $cvname); # debug
66a2622e
NIS
1013 }
1014 $pv = '' unless defined $pv; # Avoid use of undef warnings
a3985cdc 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",
a798dbf2
MB
1016 $xpvcv_ix, cstring($pv), length($pv), $cv->IVX,
1017 $cv->NVX, $startfield, ${$cv->ROOT}, $cv->DEPTH,
a3985cdc
DM
1018 $$padlist, ${$cv->OUTSIDE}, $cv->CvFLAGS,
1019 $cv->OUTSIDE_SEQ));
5cfd8ad4
VB
1020
1021 if (${$cv->OUTSIDE} == ${main_cv()}){
1022 $init->add(sprintf("CvOUTSIDE(s\\_%x)=PL_main_cv;",$$cv));
358b5eb8 1023 $init->add(sprintf("SvREFCNT_inc(PL_main_cv);"));
5cfd8ad4
VB
1024 }
1025
a798dbf2
MB
1026 if ($$gv) {
1027 $gv->save;
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;
1031 }
9d2bbe64
MB
1032 if( $ithreads ) {
1033 $init->add( savepvn( "CvFILE($sym)", $cv->FILE) );
1034 }
1035 else {
1036 $init->add(sprintf("CvFILE($sym) = %s;", cstring($cv->FILE)));
1037 }
a798dbf2
MB
1038 my $stash = $cv->STASH;
1039 if ($$stash) {
1040 $stash->save;
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;
1044 }
1045 $symsect->add(sprintf("svix%d\t(XPVCV*)&xpvcv_list[%u], %lu, 0x%x",
9d2bbe64 1046 $sv_ix, $xpvcv_ix, $cv->REFCNT +1*0 , $cv->FLAGS));
a798dbf2
MB
1047 return $sym;
1048}
1049
1050sub B::GV::save {
be6f3502 1051 my ($gv) = @_;
a798dbf2
MB
1052 my $sym = objsym($gv);
1053 if (defined($sym)) {
1054 #warn sprintf("GV 0x%x already saved as $sym\n", $$gv); # debug
1055 return $sym;
1056 } else {
1057 my $ix = $gv_index++;
1058 $sym = savesym($gv, "gv_list[$ix]");
1059 #warn sprintf("Saving GV 0x%x as $sym\n", $$gv); # debug
1060 }
87d7fd28 1061 my $is_empty = $gv->is_empty;
a798dbf2 1062 my $gvname = $gv->NAME;
b326da91
MB
1063 my $fullname = $gv->STASH->NAME . "::" . $gvname;
1064 my $name = cstring($fullname);
a798dbf2 1065 #warn "GV name is $name\n"; # debug
a798dbf2 1066 my $egvsym;
87d7fd28
GS
1067 unless ($is_empty) {
1068 my $egv = $gv->EGV;
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;
1073 }
a798dbf2
MB
1074 }
1075 $init->add(qq[$sym = gv_fetchpv($name, TRUE, SVt_PV);],
9d2bbe64 1076 sprintf("SvFLAGS($sym) = 0x%x;", $gv->FLAGS ),
87d7fd28
GS
1077 sprintf("GvFLAGS($sym) = 0x%x;", $gv->GvFLAGS));
1078 $init->add(sprintf("GvLINE($sym) = %u;", $gv->LINE)) unless $is_empty;
9d2bbe64
MB
1079 # XXX hack for when Perl accesses PVX of GVs
1080 $init->add("SvPVX($sym) = emptystring;\n");
a798dbf2
MB
1081 # Shouldn't need to do save_magic since gv_fetchpv handles that
1082 #$gv->save_magic;
9d2bbe64 1083 # XXX will always be > 1!!!
a798dbf2 1084 my $refcnt = $gv->REFCNT + 1;
9d2bbe64 1085 $init->add(sprintf("SvREFCNT($sym) += %u;", $refcnt - 1 )) if $refcnt > 1;
87d7fd28
GS
1086
1087 return $sym if $is_empty;
1088
9d2bbe64 1089 # XXX B::walksymtable creates an extra reference to the GV
a798dbf2
MB
1090 my $gvrefcnt = $gv->GvREFCNT;
1091 if ($gvrefcnt > 1) {
1092 $init->add(sprintf("GvREFCNT($sym) += %u;", $gvrefcnt - 1));
1093 }
b326da91
MB
1094 # some non-alphavetic globs require some parts to be saved
1095 # ( ex. %!, but not $! )
1096 sub Save_HV() { 1 }
1097 sub Save_AV() { 2 }
1098 sub Save_SV() { 4 }
1099 sub Save_CV() { 8 }
1100 sub Save_FORM() { 16 }
1101 sub Save_IO() { 32 }
1102 my $savefields = 0;
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;
1105 }
1106 elsif( $gvname eq '!' ) {
1107 $savefields = Save_HV;
1108 }
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';
1113
1114 # save it
9d2bbe64
MB
1115 # XXX is that correct?
1116 if (defined($egvsym) && $egvsym !~ m/Null/ ) {
a798dbf2
MB
1117 # Shared glob *foo = *bar
1118 $init->add("gp_free($sym);",
1119 "GvGP($sym) = GvGP($egvsym);");
b326da91 1120 } elsif ($savefields) {
a798dbf2
MB
1121 # Don't save subfields of special GVs (*_, *1, *# and so on)
1122# warn "GV::save saving subfields\n"; # debug
1123 my $gvsv = $gv->SV;
b326da91 1124 if ($$gvsv && $savefields&Save_SV) {
cfa4c8ee 1125 $gvsv->save;
a798dbf2
MB
1126 $init->add(sprintf("GvSV($sym) = s\\_%x;", $$gvsv));
1127# warn "GV::save \$$name\n"; # debug
a798dbf2
MB
1128 }
1129 my $gvav = $gv->AV;
b326da91 1130 if ($$gvav && $savefields&Save_AV) {
cfa4c8ee 1131 $gvav->save;
a798dbf2
MB
1132 $init->add(sprintf("GvAV($sym) = s\\_%x;", $$gvav));
1133# warn "GV::save \@$name\n"; # debug
a798dbf2
MB
1134 }
1135 my $gvhv = $gv->HV;
b326da91 1136 if ($$gvhv && $savefields&Save_HV) {
cfa4c8ee 1137 $gvhv->save;
a798dbf2
MB
1138 $init->add(sprintf("GvHV($sym) = s\\_%x;", $$gvhv));
1139# warn "GV::save \%$name\n"; # debug
a798dbf2
MB
1140 }
1141 my $gvcv = $gv->CV;
b326da91 1142 if ($$gvcv && $savefields&Save_CV) {
be6f3502
NIS
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
af765ed9 1147 $init->add("{ CV *cv;");
be6f3502 1148 $init->add("\tcv=perl_get_cv($origname,TRUE);");
af765ed9
VB
1149 $init->add("\tGvCV($sym)=cv;");
1150 $init->add("\tSvREFCNT_inc((SV *)cv);");
be6f3502 1151 $init->add("}");
b326da91 1152 } else {
be6f3502
NIS
1153 $init->add(sprintf("GvCV($sym) = (CV*)(%s);", $gvcv->save));
1154# warn "GV::save &$name\n"; # debug
1155 }
af765ed9 1156 }
b195d487
GS
1157 $init->add(sprintf("GvFILE($sym) = %s;", cstring($gv->FILE)));
1158# warn "GV::save GvFILE(*$name)\n"; # debug
a798dbf2 1159 my $gvform = $gv->FORM;
b326da91 1160 if ($$gvform && $savefields&Save_FORM) {
cfa4c8ee 1161 $gvform->save;
a798dbf2
MB
1162 $init->add(sprintf("GvFORM($sym) = (CV*)s\\_%x;", $$gvform));
1163# warn "GV::save GvFORM(*$name)\n"; # debug
a798dbf2
MB
1164 }
1165 my $gvio = $gv->IO;
b326da91 1166 if ($$gvio && $savefields&Save_IO) {
cfa4c8ee 1167 $gvio->save;
a798dbf2 1168 $init->add(sprintf("GvIOp($sym) = s\\_%x;", $$gvio));
b326da91
MB
1169 if( $fullname =~ m/::DATA$/ && $save_data_fh ) {
1170 no strict 'refs';
1171 my $fh = *{$fullname}{IO};
1172 use strict 'refs';
1173 $gvio->save_data( $fullname, <$fh> ) if $fh->opened;
1174 }
a798dbf2 1175# warn "GV::save GvIO(*$name)\n"; # debug
a798dbf2
MB
1176 }
1177 }
1178 return $sym;
1179}
9d2bbe64 1180
a798dbf2
MB
1181sub B::AV::save {
1182 my ($av) = @_;
1183 my $sym = objsym($av);
1184 return $sym if defined $sym;
1185 my $avflags = $av->AvFLAGS;
1186 $xpvavsect->add(sprintf("0, -1, -1, 0, 0.0, 0, Nullhv, 0, 0, 0x%x",
1187 $avflags));
1188 $svsect->add(sprintf("&xpvav_list[%d], %lu, 0x%x",
932e9ff9 1189 $xpvavsect->index, $av->REFCNT , $av->FLAGS));
a798dbf2
MB
1190 my $sv_list_index = $svsect->index;
1191 my $fill = $av->FILL;
1192 $av->save_magic;
1193 warn sprintf("saving AV 0x%x FILL=$fill AvFLAGS=0x%x", $$av, $avflags)
1194 if $debug_av;
1195 # XXX AVf_REAL is wrong test: need to save comppadlist but not stack
1196 #if ($fill > -1 && ($avflags & AVf_REAL)) {
1197 if ($fill > -1) {
1198 my @array = $av->ARRAY;
1199 if ($debug_av) {
1200 my $el;
1201 my $i = 0;
1202 foreach $el (@array) {
1203 warn sprintf("AV 0x%x[%d] = %s 0x%x\n",
1204 $$av, $i++, class($el), $$el);
1205 }
1206 }
9d2bbe64 1207# my @names = map($_->save, @array);
a798dbf2
MB
1208 # XXX Better ways to write loop?
1209 # Perhaps svp[0] = ...; svp[1] = ...; svp[2] = ...;
1210 # Perhaps I32 i = 0; svp[i++] = ...; svp[i++] = ...; svp[i++] = ...;
9d2bbe64
MB
1211
1212 # micro optimization: op/pat.t ( and other code probably )
1213 # has very large pads ( 20k/30k elements ) passing them to
1214 # ->add is a performance bottleneck: passing them as a
1215 # single string cuts runtime from 6min20sec to 40sec
1216
1217 # you want to keep this out of the no_split/split
1218 # map("\t*svp++ = (SV*)$_;", @names),
1219 my $acc = '';
1220 foreach my $i ( 0..$#array ) {
1221 $acc .= "\t*svp++ = (SV*)" . $array[$i]->save . ";\n\t";
1222 }
1223 $acc .= "\n";
1224
1225 $init->no_split;
a798dbf2
MB
1226 $init->add("{",
1227 "\tSV **svp;",
1228 "\tAV *av = (AV*)&sv_list[$sv_list_index];",
1229 "\tav_extend(av, $fill);",
9d2bbe64
MB
1230 "\tsvp = AvARRAY(av);" );
1231 $init->add($acc);
1232 $init->add("\tAvFILLp(av) = $fill;",
a798dbf2 1233 "}");
9d2bbe64
MB
1234 $init->split;
1235 # we really added a lot of lines ( B::C::InitSection->add
1236 # should really scan for \n, but that would slow
1237 # it down
1238 $init->inc_count( $#array );
a798dbf2
MB
1239 } else {
1240 my $max = $av->MAX;
1241 $init->add("av_extend((AV*)&sv_list[$sv_list_index], $max);")
1242 if $max > -1;
1243 }
1244 return savesym($av, "(AV*)&sv_list[$sv_list_index]");
1245}
1246
1247sub B::HV::save {
1248 my ($hv) = @_;
1249 my $sym = objsym($hv);
1250 return $sym if defined $sym;
1251 my $name = $hv->NAME;
1252 if ($name) {
1253 # It's a stash
1254
1255 # A perl bug means HvPMROOT isn't altered when a PMOP is freed. Usually
1256 # the only symptom is that sv_reset tries to reset the PMf_USED flag of
1257 # a trashed op but we look at the trashed op_type and segfault.
1258 #my $adpmroot = ${$hv->PMROOT};
1259 my $adpmroot = 0;
1260 $decl->add("static HV *hv$hv_index;");
1261 # XXX Beware of weird package names containing double-quotes, \n, ...?
1262 $init->add(qq[hv$hv_index = gv_stashpv("$name", TRUE);]);
1263 if ($adpmroot) {
1264 $init->add(sprintf("HvPMROOT(hv$hv_index) = (PMOP*)s\\_%x;",
1265 $adpmroot));
1266 }
1267 $sym = savesym($hv, "hv$hv_index");
1268 $hv_index++;
1269 return $sym;
1270 }
1271 # It's just an ordinary HV
1272 $xpvhvsect->add(sprintf("0, 0, %d, 0, 0.0, 0, Nullhv, %d, 0, 0, 0",
1273 $hv->MAX, $hv->RITER));
1274 $svsect->add(sprintf("&xpvhv_list[%d], %lu, 0x%x",
932e9ff9 1275 $xpvhvsect->index, $hv->REFCNT , $hv->FLAGS));
a798dbf2
MB
1276 my $sv_list_index = $svsect->index;
1277 my @contents = $hv->ARRAY;
1278 if (@contents) {
1279 my $i;
1280 for ($i = 1; $i < @contents; $i += 2) {
1281 $contents[$i] = $contents[$i]->save;
1282 }
9d2bbe64 1283 $init->no_split;
a798dbf2
MB
1284 $init->add("{", "\tHV *hv = (HV*)&sv_list[$sv_list_index];");
1285 while (@contents) {
1286 my ($key, $value) = splice(@contents, 0, 2);
1287 $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
b326da91
MB
1288 cstring($key),length(pack "a*",$key),
1289 $value, hash($key)));
cf86991c
NIS
1290# $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
1291# cstring($key),length($key),$value, 0));
a798dbf2
MB
1292 }
1293 $init->add("}");
9d2bbe64 1294 $init->split;
a798dbf2 1295 }
56eca212 1296 $hv->save_magic();
a798dbf2
MB
1297 return savesym($hv, "(HV*)&sv_list[$sv_list_index]");
1298}
1299
b326da91
MB
1300sub B::IO::save_data {
1301 my( $io, $globname, @data ) = @_;
1302 my $data = join '', @data;
1303
1304 # XXX using $DATA might clobber it!
1305 my $sym = svref_2object( \\$data )->save;
9d2bbe64 1306 $init->add( split /\n/, <<CODE );
b326da91
MB
1307 {
1308 GV* gv = (GV*)gv_fetchpv( "$globname", TRUE, SVt_PV );
1309 SV* sv = $sym;
1310 GvSV( gv ) = sv;
1311 }
1312CODE
e934609f 1313 # for PerlIO::scalar
b326da91
MB
1314 $use_xsloader = 1;
1315 $init->add_eval( sprintf 'open(%s, "<", $%s)', $globname, $globname );
1316}
1317
a798dbf2
MB
1318sub B::IO::save {
1319 my ($io) = @_;
1320 my $sym = objsym($io);
1321 return $sym if defined $sym;
1322 my $pv = $io->PV;
66a2622e 1323 $pv = '' unless defined $pv;
a798dbf2
MB
1324 my $len = length($pv);
1325 $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",
1326 $len, $len+1, $io->IVX, $io->NVX, $io->LINES,
1327 $io->PAGE, $io->PAGE_LEN, $io->LINES_LEFT,
1328 cstring($io->TOP_NAME), cstring($io->FMT_NAME),
1329 cstring($io->BOTTOM_NAME), $io->SUBPROCESS,
1330 cchar($io->IoTYPE), $io->IoFLAGS));
1331 $svsect->add(sprintf("&xpvio_list[%d], %lu, 0x%x",
932e9ff9 1332 $xpviosect->index, $io->REFCNT , $io->FLAGS));
a798dbf2 1333 $sym = savesym($io, sprintf("(IO*)&sv_list[%d]", $svsect->index));
b326da91
MB
1334 # deal with $x = *STDIN/STDOUT/STDERR{IO}
1335 my $perlio_func;
1336 foreach ( qw(stdin stdout stderr) ) {
1337 $io->IsSTD($_) and $perlio_func = $_;
1338 }
1339 if( $perlio_func ) {
1340 $init->add( "IoIFP(${sym})=PerlIO_${perlio_func}();" );
1341 $init->add( "IoOFP(${sym})=PerlIO_${perlio_func}();" );
1342 }
1343
a798dbf2
MB
1344 my ($field, $fsym);
1345 foreach $field (qw(TOP_GV FMT_GV BOTTOM_GV)) {
1346 $fsym = $io->$field();
1347 if ($$fsym) {
1348 $init->add(sprintf("Io$field($sym) = (GV*)s\\_%x;", $$fsym));
1349 $fsym->save;
1350 }
1351 }
1352 $io->save_magic;
1353 return $sym;
1354}
1355
1356sub B::SV::save {
1357 my $sv = shift;
1358 # This is where we catch an honest-to-goodness Nullsv (which gets
1359 # blessed into B::SV explicitly) and any stray erroneous SVs.
1360 return 0 unless $$sv;
1361 confess sprintf("cannot save that type of SV: %s (0x%x)\n",
1362 class($sv), $$sv);
1363}
1364
1365sub output_all {
1366 my $init_name = shift;
1367 my $section;
1368 my @sections = ($opsect, $unopsect, $binopsect, $logopsect, $condopsect,
7934575e 1369 $listopsect, $pmopsect, $svopsect, $padopsect, $pvopsect,
66a2622e 1370 $loopsect, $copsect, $svsect, $xpvsect,
a798dbf2
MB
1371 $xpvavsect, $xpvhvsect, $xpvcvsect, $xpvivsect, $xpvnvsect,
1372 $xpvmgsect, $xpvlvsect, $xrvsect, $xpvbmsect, $xpviosect);
1373 $symsect->output(\*STDOUT, "#define %s\n");
1374 print "\n";
1375 output_declarations();
1376 foreach $section (@sections) {
1377 my $lines = $section->index + 1;
1378 if ($lines) {
1379 my $name = $section->name;
1380 my $typename = ($name eq "xpvcv") ? "XPVCV_or_similar" : uc($name);
1381 print "Static $typename ${name}_list[$lines];\n";
1382 }
1383 }
9d2bbe64
MB
1384 # XXX hack for when Perl accesses PVX of GVs
1385 print 'Static char emptystring[] = "\0";';
1386
a798dbf2
MB
1387 $decl->output(\*STDOUT, "%s\n");
1388 print "\n";
1389 foreach $section (@sections) {
1390 my $lines = $section->index + 1;
1391 if ($lines) {
1392 my $name = $section->name;
1393 my $typename = ($name eq "xpvcv") ? "XPVCV_or_similar" : uc($name);
1394 printf "static %s %s_list[%u] = {\n", $typename, $name, $lines;
9d2bbe64 1395 $section->output(\*STDOUT, "\t{ %s }, /* %d */\n");
a798dbf2
MB
1396 print "};\n\n";
1397 }
1398 }
1399
9d2bbe64 1400 $init->output(\*STDOUT, "\t%s\n", $init_name );
a798dbf2
MB
1401 if ($verbose) {
1402 warn compile_stats();
1403 warn "NULLOP count: $nullop_count\n";
1404 }
1405}
1406
1407sub output_declarations {
1408 print <<'EOT';
1409#ifdef BROKEN_STATIC_REDECL
1410#define Static extern
1411#else
1412#define Static static
1413#endif /* BROKEN_STATIC_REDECL */
1414
1415#ifdef BROKEN_UNION_INIT
1416/*
1417 * Cribbed from cv.h with ANY (a union) replaced by void*.
1418 * Some pre-Standard compilers can't cope with initialising unions. Ho hum.
1419 */
1420typedef struct {
1421 char * xpv_pv; /* pointer to malloced string */
1422 STRLEN xpv_cur; /* length of xp_pv as a C string */
1423 STRLEN xpv_len; /* allocated size */
1424 IV xof_off; /* integer value */
76ef7183 1425 NV xnv_nv; /* numeric value, if any */
a798dbf2
MB
1426 MAGIC* xmg_magic; /* magic for scalar array */
1427 HV* xmg_stash; /* class package */
1428
1429 HV * xcv_stash;
1430 OP * xcv_start;
1431 OP * xcv_root;
acfe0abc 1432 void (*xcv_xsub) (pTHX_ CV*);
76ef7183 1433 ANY xcv_xsubany;
a798dbf2 1434 GV * xcv_gv;
57843af0 1435 char * xcv_file;
b195d487 1436 long xcv_depth; /* >= 2 indicates recursive call */
a798dbf2
MB
1437 AV * xcv_padlist;
1438 CV * xcv_outside;
fc290457 1439 cv_flags_t xcv_flags;
a3985cdc
DM
1440 U32 xcv_outside_seq; /* the COP sequence (at the point of our
1441 * compilation) in the lexically enclosing
1442 * sub */
a798dbf2
MB
1443} XPVCV_or_similar;
1444#define ANYINIT(i) i
1445#else
1446#define XPVCV_or_similar XPVCV
1447#define ANYINIT(i) {i}
1448#endif /* BROKEN_UNION_INIT */
1449#define Nullany ANYINIT(0)
1450
1451#define UNUSED 0
1452#define sym_0 0
a798dbf2
MB
1453EOT
1454 print "static GV *gv_list[$gv_index];\n" if $gv_index;
1455 print "\n";
1456}
1457
1458
1459sub output_boilerplate {
1460 print <<'EOT';
1461#include "EXTERN.h"
1462#include "perl.h"
93865851 1463#include "XSUB.h"
a798dbf2
MB
1464
1465/* Workaround for mapstart: the only op which needs a different ppaddr */
3f872cb9
GS
1466#undef Perl_pp_mapstart
1467#define Perl_pp_mapstart Perl_pp_grepstart
b326da91
MB
1468#undef OP_MAPSTART
1469#define OP_MAPSTART OP_GREPSTART
511dd457 1470#define XS_DynaLoader_boot_DynaLoader boot_DynaLoader
5712119f 1471EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
a798dbf2 1472
5712119f
GS
1473static void xs_init (pTHX);
1474static void dl_init (pTHX);
a798dbf2
MB
1475static PerlInterpreter *my_perl;
1476EOT
1477}
1478
b326da91
MB
1479sub init_op_addr {
1480 my( $op_type, $num ) = @_;
1481 my $op_list = $op_type."_list";
1482
1483 $init->add( split /\n/, <<EOT );
1484 {
1485 int i;
1486
1487 for( i = 0; i < ${num}; ++i )
1488 {
1489 ${op_list}\[i].op_ppaddr = PL_ppaddr[INT2PTR(int,${op_list}\[i].op_ppaddr)];
1490 }
1491 }
1492EOT
1493}
1494
1495sub init_op_warn {
1496 my( $op_type, $num ) = @_;
1497 my $op_list = $op_type."_list";
1498
1499 # for resons beyond imagination, MSVC5 considers pWARN_ALL non-const
1500 $init->add( split /\n/, <<EOT );
1501 {
1502 int i;
1503
1504 for( i = 0; i < ${num}; ++i )
1505 {
1506 switch( (int)(${op_list}\[i].cop_warnings) )
1507 {
1508 case 1:
1509 ${op_list}\[i].cop_warnings = pWARN_ALL;
1510 break;
1511 case 2:
1512 ${op_list}\[i].cop_warnings = pWARN_NONE;
1513 break;
1514 case 3:
1515 ${op_list}\[i].cop_warnings = pWARN_STD;
1516 break;
1517 default:
1518 break;
1519 }
1520 }
1521 }
1522EOT
1523}
1524
a798dbf2
MB
1525sub output_main {
1526 print <<'EOT';
9d2bbe64
MB
1527/* if USE_IMPLICIT_SYS, we need a 'real' exit */
1528#if defined(exit)
1529#undef exit
1530#endif
1531
a798dbf2 1532int
a798dbf2 1533main(int argc, char **argv, char **env)
a798dbf2
MB
1534{
1535 int exitstatus;
1536 int i;
1537 char **fakeargv;
b326da91
MB
1538 GV* tmpgv;
1539 SV* tmpsv;
9d2bbe64 1540 int options_count;
a798dbf2 1541
5712119f 1542 PERL_SYS_INIT3(&argc,&argv,&env);
9d2bbe64 1543
81009501 1544 if (!PL_do_undump) {
a798dbf2
MB
1545 my_perl = perl_alloc();
1546 if (!my_perl)
1547 exit(1);
1548 perl_construct( my_perl );
5712119f 1549 PL_perl_destruct_level = 0;
a798dbf2 1550 }
9d2bbe64
MB
1551EOT
1552 if( $ithreads ) {
1553 # XXX init free elems!
1554 my $pad_len = regex_padav->FILL + 1 - 1; # first is an avref
a798dbf2 1555
9d2bbe64
MB
1556 print <<EOT;
1557#ifdef USE_ITHREADS
1558 for( i = 0; i < $pad_len; ++i ) {
1559 av_push( PL_regex_padav, newSViv(0) );
1560 }
1561 PL_regex_pad = AvARRAY( PL_regex_padav );
1562#endif
1563EOT
1564 }
1565
1566 print <<'EOT';
a798dbf2 1567#ifdef CSH
81009501
GS
1568 if (!PL_cshlen)
1569 PL_cshlen = strlen(PL_cshname);
a798dbf2
MB
1570#endif
1571
1572#ifdef ALLOW_PERL_OPTIONS
a798dbf2 1573#define EXTRA_OPTIONS 3
b326da91
MB
1574#else
1575#define EXTRA_OPTIONS 4
a798dbf2
MB
1576#endif /* ALLOW_PERL_OPTIONS */
1577 New(666, fakeargv, argc + EXTRA_OPTIONS + 1, char *);
b326da91 1578
a798dbf2
MB
1579 fakeargv[0] = argv[0];
1580 fakeargv[1] = "-e";
1581 fakeargv[2] = "";
9d2bbe64 1582 options_count = 3;
b326da91
MB
1583EOT
1584 # honour -T
9d2bbe64
MB
1585 print <<EOT;
1586 if( ${^TAINT} ) {
1587 fakeargv[options_count] = "-T";
1588 ++options_count;
1589 }
1590EOT
b326da91 1591 print <<'EOT';
a798dbf2 1592#ifndef ALLOW_PERL_OPTIONS
9d2bbe64
MB
1593 fakeargv[options_count] = "--";
1594 ++options_count;
a798dbf2
MB
1595#endif /* ALLOW_PERL_OPTIONS */
1596 for (i = 1; i < argc; i++)
9d2bbe64
MB
1597 fakeargv[i + options_count - 1] = argv[i];
1598 fakeargv[argc + options_count - 1] = 0;
b326da91 1599
9d2bbe64 1600 exitstatus = perl_parse(my_perl, xs_init, argc + options_count - 1,
a798dbf2 1601 fakeargv, NULL);
b326da91 1602
a798dbf2
MB
1603 if (exitstatus)
1604 exit( exitstatus );
1605
b326da91
MB
1606 TAINT;
1607EOT
1608
1609 if( $use_perl_script_name ) {
1610 my $dollar_0 = $0;
1611 $dollar_0 =~ s/\\/\\\\/g;
1612 $dollar_0 = '"' . $dollar_0 . '"';
1613
1614 print <<EOT;
1615 if ((tmpgv = gv_fetchpv("0",TRUE, SVt_PV))) {/* $0 */
1616 tmpsv = GvSV(tmpgv);
1617 sv_setpv(tmpsv, ${dollar_0});
1618 SvSETMAGIC(tmpsv);
1619 }
1620EOT
1621 }
ede8dd12
AT
1622 else {
1623 print <<EOT;
1624 if ((tmpgv = gv_fetchpv("0",TRUE, SVt_PV))) {/* $0 */
1625 tmpsv = GvSV(tmpgv);
1626 sv_setpv(tmpsv, argv[0]);
1627 SvSETMAGIC(tmpsv);
1628 }
1629EOT
1630 }
b326da91
MB
1631
1632 print <<'EOT';
1633 if ((tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))) {/* $^X */
1634 tmpsv = GvSV(tmpgv);
1635#ifdef WIN32
1636 sv_setpv(tmpsv,"perl.exe");
1637#else
1638 sv_setpv(tmpsv,"perl");
1639#endif
1640 SvSETMAGIC(tmpsv);
1641 }
1642
1643 TAINT_NOT;
1644
1645 /* PL_main_cv = PL_compcv; */
81009501 1646 PL_compcv = 0;
a798dbf2
MB
1647
1648 exitstatus = perl_init();
1649 if (exitstatus)
1650 exit( exitstatus );
5712119f 1651 dl_init(aTHX);
a798dbf2
MB
1652
1653 exitstatus = perl_run( my_perl );
1654
1655 perl_destruct( my_perl );
1656 perl_free( my_perl );
1657
5712119f
GS
1658 PERL_SYS_TERM();
1659
a798dbf2
MB
1660 exit( exitstatus );
1661}
1662
511dd457 1663/* yanked from perl.c */
a798dbf2 1664static void
5712119f 1665xs_init(pTHX)
a798dbf2 1666{
511dd457 1667 char *file = __FILE__;
af765ed9 1668 dTARG;
39644a26 1669 dSP;
a798dbf2 1670EOT
af765ed9
VB
1671 print "\n#ifdef USE_DYNAMIC_LOADING";
1672 print qq/\n\tnewXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);/;
1673 print "\n#endif\n" ;
a0e9c8c7 1674 # delete $xsub{'DynaLoader'};
af765ed9 1675 delete $xsub{'UNIVERSAL'};
be6f3502 1676 print("/* bootstrapping code*/\n\tSAVETMPS;\n");
af765ed9 1677 print("\ttarg=sv_newmortal();\n");
b326da91 1678 print "#ifdef USE_DYNAMIC_LOADING\n";
a0e9c8c7
NIS
1679 print "\tPUSHMARK(sp);\n";
1680 print qq/\tXPUSHp("DynaLoader",strlen("DynaLoader"));\n/;
1681 print qq/\tPUTBACK;\n/;
5712119f 1682 print "\tboot_DynaLoader(aTHX_ NULL);\n";
a0e9c8c7
NIS
1683 print qq/\tSPAGAIN;\n/;
1684 print "#endif\n";
1685 foreach my $stashname (keys %xsub){
b326da91 1686 if ($xsub{$stashname} !~ m/Dynamic/ ) {
be6f3502
NIS
1687 my $stashxsub=$stashname;
1688 $stashxsub =~ s/::/__/g;
1689 print "\tPUSHMARK(sp);\n";
a0e9c8c7
NIS
1690 print qq/\tXPUSHp("$stashname",strlen("$stashname"));\n/;
1691 print qq/\tPUTBACK;\n/;
5712119f 1692 print "\tboot_$stashxsub(aTHX_ NULL);\n";
a0e9c8c7 1693 print qq/\tSPAGAIN;\n/;
be6f3502
NIS
1694 }
1695 }
1696 print("\tFREETMPS;\n/* end bootstrapping code */\n");
a0e9c8c7 1697 print "}\n";
be6f3502
NIS
1698
1699print <<'EOT';
1700static void
5712119f 1701dl_init(pTHX)
be6f3502
NIS
1702{
1703 char *file = __FILE__;
1704 dTARG;
39644a26 1705 dSP;
be6f3502
NIS
1706EOT
1707 print("/* Dynamicboot strapping code*/\n\tSAVETMPS;\n");
1708 print("\ttarg=sv_newmortal();\n");
1709 foreach my $stashname (@DynaLoader::dl_modules) {
1710 warn "Loaded $stashname\n";
b326da91 1711 if (exists($xsub{$stashname}) && $xsub{$stashname} =~ m/Dynamic/) {
be6f3502
NIS
1712 my $stashxsub=$stashname;
1713 $stashxsub =~ s/::/__/g;
1714 print "\tPUSHMARK(sp);\n";
a0e9c8c7 1715 print qq/\tXPUSHp("$stashname",/,length($stashname),qq/);\n/;
be6f3502 1716 print qq/\tPUTBACK;\n/;
b326da91 1717 print "#ifdef USE_DYNAMIC_LOADING\n";
af765ed9 1718 warn "bootstrapping $stashname added to xs_init\n";
b326da91
MB
1719 if( $xsub{$stashname} eq 'Dynamic' ) {
1720 print qq/\tperl_call_method("bootstrap",G_DISCARD);\n/;
1721 }
1722 else {
1723 print qq/\tperl_call_pv("XSLoader::load",G_DISCARD);\n/;
1724 }
9d2bbe64 1725 print "#else\n";
5712119f 1726 print "\tboot_$stashxsub(aTHX_ NULL);\n";
be6f3502
NIS
1727 print "#endif\n";
1728 print qq/\tSPAGAIN;\n/;
1729 }
af765ed9 1730 }
be6f3502 1731 print("\tFREETMPS;\n/* end Dynamic bootstrapping code */\n");
a0e9c8c7 1732 print "}\n";
af765ed9 1733}
a798dbf2
MB
1734sub dump_symtable {
1735 # For debugging
1736 my ($sym, $val);
1737 warn "----Symbol table:\n";
1738 while (($sym, $val) = each %symtable) {
1739 warn "$sym => $val\n";
1740 }
1741 warn "---End of symbol table\n";
1742}
1743
1744sub save_object {
1745 my $sv;
1746 foreach $sv (@_) {
1747 svref_2object($sv)->save;
1748 }
338a6d08
NIS
1749}
1750
1751sub Dummy_BootStrap { }
a798dbf2 1752
66a2622e
NIS
1753sub B::GV::savecv
1754{
1755 my $gv = shift;
1756 my $package=$gv->STASH->NAME;
1757 my $name = $gv->NAME;
1758 my $cv = $gv->CV;
7cf11ee8
NIS
1759 my $sv = $gv->SV;
1760 my $av = $gv->AV;
1761 my $hv = $gv->HV;
7cf11ee8 1762
b326da91
MB
1763 my $fullname = $gv->STASH->NAME . "::" . $gv->NAME;
1764
66a2622e
NIS
1765 # We may be looking at this package just because it is a branch in the
1766 # symbol table which is on the path to a package which we need to save
7cf11ee8 1767 # e.g. this is 'Getopt' and we need to save 'Getopt::Long'
66a2622e 1768 #
7cf11ee8 1769 return unless ($unused_sub_packages{$package});
be6f3502
NIS
1770 return unless ($$cv || $$av || $$sv || $$hv);
1771 $gv->save;
66a2622e 1772}
5ed82aed 1773
66a2622e
NIS
1774sub mark_package
1775{
1776 my $package = shift;
1777 unless ($unused_sub_packages{$package})
1778 {
1779 no strict 'refs';
1780 $unused_sub_packages{$package} = 1;
6771324e 1781 if (defined @{$package.'::ISA'})
66a2622e
NIS
1782 {
1783 foreach my $isa (@{$package.'::ISA'})
1784 {
1785 if ($isa eq 'DynaLoader')
1786 {
1787 unless (defined(&{$package.'::bootstrap'}))
1788 {
1789 warn "Forcing bootstrap of $package\n";
1790 eval { $package->bootstrap };
1791 }
1792 }
a0e9c8c7 1793# else
66a2622e
NIS
1794 {
1795 unless ($unused_sub_packages{$isa})
1796 {
1797 warn "$isa saved (it is in $package\'s \@ISA)\n";
1798 mark_package($isa);
1799 }
1800 }
1801 }
1802 }
1803 }
1804 return 1;
1805}
1806
1807sub should_save
1808{
1809 no strict qw(vars refs);
1810 my $package = shift;
1811 $package =~ s/::$//;
1812 return $unused_sub_packages{$package} = 0 if ($package =~ /::::/); # skip ::::ISA::CACHE etc.
cf86991c 1813 # warn "Considering $package\n";#debug
66a2622e
NIS
1814 foreach my $u (grep($unused_sub_packages{$_},keys %unused_sub_packages))
1815 {
1816 # If this package is a prefix to something we are saving, traverse it
1817 # but do not mark it for saving if it is not already
1818 # e.g. to get to Getopt::Long we need to traverse Getopt but need
1819 # not save Getopt
1820 return 1 if ($u =~ /^$package\:\:/);
1821 }
1822 if (exists $unused_sub_packages{$package})
1823 {
cf86991c 1824 # warn "Cached $package is ".$unused_sub_packages{$package}."\n";
cfa4c8ee
VB
1825 delete_unsaved_hashINC($package) unless $unused_sub_packages{$package} ;
1826 return $unused_sub_packages{$package};
66a2622e
NIS
1827 }
1828 # Omit the packages which we use (and which cause grief
1829 # because of fancy "goto &$AUTOLOAD" stuff).
1830 # XXX Surely there must be a nicer way to do this.
1831 if ($package eq "FileHandle" || $package eq "Config" ||
cf86991c 1832 $package eq "SelectSaver" || $package =~/^(B|IO)::/)
66a2622e 1833 {
cfa4c8ee 1834 delete_unsaved_hashINC($package);
66a2622e
NIS
1835 return $unused_sub_packages{$package} = 0;
1836 }
1837 # Now see if current package looks like an OO class this is probably too strong.
1838 foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE))
1839 {
b368a11e 1840 if (UNIVERSAL::can($package, $m))
66a2622e
NIS
1841 {
1842 warn "$package has method $m: saving package\n";#debug
1843 return mark_package($package);
1844 }
1845 }
cfa4c8ee 1846 delete_unsaved_hashINC($package);
66a2622e 1847 return $unused_sub_packages{$package} = 0;
a798dbf2 1848}
cfa4c8ee
VB
1849sub delete_unsaved_hashINC{
1850 my $packname=shift;
1851 $packname =~ s/\:\:/\//g;
1852 $packname .= '.pm';
59c10aa2 1853# warn "deleting $packname" if $INC{$packname} ;# debug
cfa4c8ee
VB
1854 delete $INC{$packname};
1855}
66a2622e
NIS
1856sub walkpackages
1857{
1858 my ($symref, $recurse, $prefix) = @_;
1859 my $sym;
1860 my $ref;
1861 no strict 'vars';
1862 local(*glob);
1863 $prefix = '' unless defined $prefix;
1864 while (($sym, $ref) = each %$symref)
1865 {
1866 *glob = $ref;
1867 if ($sym =~ /::$/)
1868 {
1869 $sym = $prefix . $sym;
b4e94495 1870 if ($sym ne "main::" && $sym ne "<none>::" && &$recurse($sym))
66a2622e
NIS
1871 {
1872 walkpackages(\%glob, $recurse, $sym);
1873 }
1874 }
1875 }
1876}
338a6d08
NIS
1877
1878
66a2622e
NIS
1879sub save_unused_subs
1880{
1881 no strict qw(refs);
a9b6343a 1882 &descend_marked_unused;
66a2622e
NIS
1883 warn "Prescan\n";
1884 walkpackages(\%{"main::"}, sub { should_save($_[0]); return 1 });
1885 warn "Saving methods\n";
1886 walksymtable(\%{"main::"}, "savecv", \&should_save);
a798dbf2
MB
1887}
1888
0cc1d052
NIS
1889sub save_context
1890{
1891 my $curpad_nam = (comppadlist->ARRAY)[0]->save;
1892 my $curpad_sym = (comppadlist->ARRAY)[1]->save;
1893 my $inc_hv = svref_2object(\%INC)->save;
1894 my $inc_av = svref_2object(\@INC)->save;
56eca212 1895 my $amagic_generate= amagic_generation;
0cc1d052
NIS
1896 $init->add( "PL_curpad = AvARRAY($curpad_sym);",
1897 "GvHV(PL_incgv) = $inc_hv;",
1898 "GvAV(PL_incgv) = $inc_av;",
1899 "av_store(CvPADLIST(PL_main_cv),0,SvREFCNT_inc($curpad_nam));",
56eca212
GS
1900 "av_store(CvPADLIST(PL_main_cv),1,SvREFCNT_inc($curpad_sym));",
1901 "PL_amagic_generation= $amagic_generate;" );
0cc1d052
NIS
1902}
1903
a9b6343a
VB
1904sub descend_marked_unused {
1905 foreach my $pack (keys %unused_sub_packages)
1906 {
1907 mark_package($pack);
1908 }
1909}
73544139 1910
a798dbf2 1911sub save_main {
b326da91
MB
1912 # this is mainly for the test suite
1913 my $warner = $SIG{__WARN__};
1914 local $SIG{__WARN__} = sub { print STDERR @_ };
1915
66a2622e 1916 warn "Starting compile\n";
66a2622e 1917 warn "Walking tree\n";
73544139 1918 seek(STDOUT,0,0); #exclude print statements in BEGIN{} into output
a798dbf2
MB
1919 walkoptree(main_root, "save");
1920 warn "done main optree, walking symtable for extras\n" if $debug_cv;
66a2622e 1921 save_unused_subs();
b326da91
MB
1922 # XSLoader was used, force saving of XSLoader::load
1923 if( $use_xsloader ) {
1924 my $cv = svref_2object( \&XSLoader::load );
1925 $cv->save;
1926 }
1927 # save %SIG ( in case it was set in a BEGIN block )
1928 if( $save_sig ) {
1929 local $SIG{__WARN__} = $warner;
9d2bbe64 1930 $init->no_split;
b326da91
MB
1931 $init->add("{", "\tHV* hv = get_hv(\"main::SIG\",1);" );
1932 foreach my $k ( keys %SIG ) {
9d2bbe64 1933 next unless ref $SIG{$k};
b326da91
MB
1934 my $cv = svref_2object( \$SIG{$k} );
1935 my $sv = $cv->save;
1936 $init->add('{',sprintf 'SV* sv = (SV*)%s;', $sv );
1937 $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
1938 cstring($k),length(pack "a*",$k),
1939 'sv', hash($k)));
1940 $init->add('mg_set(sv);','}');
1941 }
1942 $init->add('}');
9d2bbe64 1943 $init->split;
b326da91
MB
1944 }
1945 # honour -w
1946 $init->add( sprintf " PL_dowarn = ( %s ) ? G_WARN_ON : G_WARN_OFF;", $^W );
1947 #
0cc1d052 1948 my $init_av = init_av->save;
b326da91 1949 my $end_av = end_av->save;
81009501
GS
1950 $init->add(sprintf("PL_main_root = s\\_%x;", ${main_root()}),
1951 sprintf("PL_main_start = s\\_%x;", ${main_start()}),
b326da91
MB
1952 "PL_initav = (AV *) $init_av;",
1953 "PL_endav = (AV*) $end_av;");
0cc1d052 1954 save_context();
b326da91
MB
1955 # init op addrs ( must be the last action, otherwise
1956 # some ops might not be initialized
1957 if( $optimize_ppaddr ) {
1958 foreach my $i ( @op_sections ) {
1959 my $section = $$i;
1960 next unless $section->index >= 0;
1961 init_op_addr( $section->name, $section->index + 1);
1962 }
1963 }
1964 init_op_warn( $copsect->name, $copsect->index + 1)
1965 if $optimize_warn_sv && $copsect->index >= 0;
1966
5ed82aed 1967 warn "Writing output\n";
a798dbf2
MB
1968 output_boilerplate();
1969 print "\n";
1970 output_all("perl_init");
1971 print "\n";
1972 output_main();
1973}
1974
1975sub init_sections {
b326da91 1976 my @sections = (decl => \$decl, sym => \$symsect,
a798dbf2 1977 binop => \$binopsect, condop => \$condopsect,
7934575e 1978 cop => \$copsect, padop => \$padopsect,
a798dbf2
MB
1979 listop => \$listopsect, logop => \$logopsect,
1980 loop => \$loopsect, op => \$opsect, pmop => \$pmopsect,
1981 pvop => \$pvopsect, svop => \$svopsect, unop => \$unopsect,
1982 sv => \$svsect, xpv => \$xpvsect, xpvav => \$xpvavsect,
1983 xpvhv => \$xpvhvsect, xpvcv => \$xpvcvsect,
1984 xpviv => \$xpvivsect, xpvnv => \$xpvnvsect,
1985 xpvmg => \$xpvmgsect, xpvlv => \$xpvlvsect,
1986 xrv => \$xrvsect, xpvbm => \$xpvbmsect,
af765ed9 1987 xpvio => \$xpviosect);
a798dbf2
MB
1988 my ($name, $sectref);
1989 while (($name, $sectref) = splice(@sections, 0, 2)) {
66a2622e 1990 $$sectref = new B::C::Section $name, \%symtable, 0;
a798dbf2 1991 }
b326da91
MB
1992 $init = new B::C::InitSection 'init', \%symtable, 0;
1993}
0cc1d052
NIS
1994
1995sub mark_unused
1996{
1997 my ($arg,$val) = @_;
1998 $unused_sub_packages{$arg} = $val;
a798dbf2
MB
1999}
2000
2001sub compile {
2002 my @options = @_;
2003 my ($option, $opt, $arg);
b326da91
MB
2004 my @eval_at_startup;
2005 my %option_map = ( 'cog' => \$pv_copy_on_grow,
2006 'save-data' => \$save_data_fh,
2007 'ppaddr' => \$optimize_ppaddr,
2008 'warn-sv' => \$optimize_warn_sv,
2009 'use-script-name' => \$use_perl_script_name,
2010 'save-sig-hash' => \$save_sig,
2011 );
9d2bbe64
MB
2012 my %optimization_map = ( 0 => [ qw() ], # special case
2013 1 => [ qw(-fcog) ],
2014 2 => [ qw(-fwarn-sv -fppaddr) ],
2015 );
a798dbf2
MB
2016 OPTION:
2017 while ($option = shift @options) {
2018 if ($option =~ /^-(.)(.*)/) {
2019 $opt = $1;
2020 $arg = $2;
2021 } else {
2022 unshift @options, $option;
2023 last OPTION;
2024 }
2025 if ($opt eq "-" && $arg eq "-") {
2026 shift @options;
2027 last OPTION;
2028 }
2029 if ($opt eq "w") {
2030 $warn_undefined_syms = 1;
2031 } elsif ($opt eq "D") {
2032 $arg ||= shift @options;
2033 foreach $arg (split(//, $arg)) {
2034 if ($arg eq "o") {
2035 B->debug(1);
2036 } elsif ($arg eq "c") {
2037 $debug_cops = 1;
2038 } elsif ($arg eq "A") {
2039 $debug_av = 1;
2040 } elsif ($arg eq "C") {
2041 $debug_cv = 1;
2042 } elsif ($arg eq "M") {
2043 $debug_mg = 1;
2044 } else {
2045 warn "ignoring unknown debug option: $arg\n";
2046 }
2047 }
2048 } elsif ($opt eq "o") {
2049 $arg ||= shift @options;
2050 open(STDOUT, ">$arg") or return "$arg: $!\n";
2051 } elsif ($opt eq "v") {
2052 $verbose = 1;
2053 } elsif ($opt eq "u") {
2054 $arg ||= shift @options;
0cc1d052 2055 mark_unused($arg,undef);
a798dbf2
MB
2056 } elsif ($opt eq "f") {
2057 $arg ||= shift @options;
b326da91
MB
2058 $arg =~ m/(no-)?(.*)/;
2059 my $no = defined($1) && $1 eq 'no-';
2060 $arg = $no ? $2 : $arg;
2061 if( exists $option_map{$arg} ) {
2062 ${$option_map{$arg}} = !$no;
2063 } else {
2064 die "Invalid optimization '$arg'";
2065 }
a798dbf2
MB
2066 } elsif ($opt eq "O") {
2067 $arg = 1 if $arg eq "";
9d2bbe64
MB
2068 my @opt;
2069 foreach my $i ( 1 .. $arg ) {
2070 push @opt, @{$optimization_map{$i}}
2071 if exists $optimization_map{$i};
2072 }
2073 unshift @options, @opt;
b326da91
MB
2074 } elsif ($opt eq "e") {
2075 push @eval_at_startup, $arg;
dc333d64
GS
2076 } elsif ($opt eq "l") {
2077 $max_string_len = $arg;
a798dbf2
MB
2078 }
2079 }
2080 init_sections();
b326da91
MB
2081 foreach my $i ( @eval_at_startup ) {
2082 $init->add_eval( $i );
2083 }
a798dbf2
MB
2084 if (@options) {
2085 return sub {
2086 my $objname;
2087 foreach $objname (@options) {
2088 eval "save_object(\\$objname)";
2089 }
2090 output_all();
2091 }
2092 } else {
2093 return sub { save_main() };
2094 }
2095}
2096
20971;
7f20e9dd
GS
2098
2099__END__
2100
2101=head1 NAME
2102
2103B::C - Perl compiler's C backend
2104
2105=head1 SYNOPSIS
2106
2107 perl -MO=C[,OPTIONS] foo.pl
2108
2109=head1 DESCRIPTION
2110
1a52ab62
MB
2111This compiler backend takes Perl source and generates C source code
2112corresponding to the internal structures that perl uses to run
2113your program. When the generated C source is compiled and run, it
2114cuts out the time which perl would have taken to load and parse
2115your program into its internal semi-compiled form. That means that
2116compiling with this backend will not help improve the runtime
2117execution speed of your program but may improve the start-up time.
2118Depending on the environment in which your program runs this may be
2119either a help or a hindrance.
2120
2121=head1 OPTIONS
2122
2123If there are any non-option arguments, they are taken to be
2124names of objects to be saved (probably doesn't work properly yet).
2125Without extra arguments, it saves the main program.
2126
2127=over 4
2128
2129=item B<-ofilename>
2130
2131Output to filename instead of STDOUT
2132
2133=item B<-v>
2134
2135Verbose compilation (currently gives a few compilation statistics).
2136
2137=item B<-->
2138
2139Force end of options
2140
2141=item B<-uPackname>
2142
2143Force apparently unused subs from package Packname to be compiled.
2144This allows programs to use eval "foo()" even when sub foo is never
2145seen to be used at compile time. The down side is that any subs which
2146really are never used also have code generated. This option is
2147necessary, for example, if you have a signal handler foo which you
2148initialise with C<$SIG{BAR} = "foo">. A better fix, though, is just
2149to change it to C<$SIG{BAR} = \&foo>. You can have multiple B<-u>
2150options. The compiler tries to figure out which packages may possibly
2151have subs in which need compiling but the current version doesn't do
2152it very well. In particular, it is confused by nested packages (i.e.
2153of the form C<A::B>) where package C<A> does not contain any subs.
2154
2155=item B<-D>
2156
2157Debug options (concatenated or separate flags like C<perl -D>).
2158
2159=item B<-Do>
2160
2161OPs, prints each OP as it's processed
2162
2163=item B<-Dc>
2164
2165COPs, prints COPs as processed (incl. file & line num)
2166
2167=item B<-DA>
2168
2169prints AV information on saving
2170
2171=item B<-DC>
2172
2173prints CV information on saving
2174
2175=item B<-DM>
2176
2177prints MAGIC information on saving
2178
2179=item B<-f>
2180
b326da91
MB
2181Force options/optimisations on or off one at a time. You can explicitly
2182disable an option using B<-fno-option>. All options default to
2183B<disabled>.
2184
2185=over 4
1a52ab62
MB
2186
2187=item B<-fcog>
2188
2189Copy-on-grow: PVs declared and initialised statically.
2190
b326da91
MB
2191=item B<-fsave-data>
2192
2193Save package::DATA filehandles ( only available with PerlIO ).
1a52ab62 2194
b326da91
MB
2195=item B<-fppaddr>
2196
2197Optimize the initialization of op_ppaddr.
2198
2199=item B<-fwarn-sv>
2200
2201Optimize the initialization of cop_warnings.
2202
2203=item B<-fuse-script-name>
2204
2205Use the script name instead of the program name as $0.
2206
2207=item B<-fsave-sig-hash>
2208
2209Save compile-time modifications to the %SIG hash.
2210
2211=back
1a52ab62
MB
2212
2213=item B<-On>
2214
9d2bbe64
MB
2215Optimisation level (n = 0, 1, 2, ...). B<-O> means B<-O1>.
2216
2217=over 4
2218
2219=item B<-O0>
2220
2221Disable all optimizations.
2222
2223=item B<-O1>
2224
2225Enable B<-fcog>.
2226
2227=item B<-O2>
2228
2229Enable B<-fppaddr>, B<-fwarn-sv>.
2230
2231=back
1a52ab62 2232
dc333d64
GS
2233=item B<-llimit>
2234
2235Some C compilers impose an arbitrary limit on the length of string
2236constants (e.g. 2048 characters for Microsoft Visual C++). The
2237B<-llimit> options tells the C backend not to generate string literals
2238exceeding that limit.
2239
a45bd81d
GS
2240=back
2241
1a52ab62
MB
2242=head1 EXAMPLES
2243
2244 perl -MO=C,-ofoo.c foo.pl
2245 perl cc_harness -o foo foo.c
2246
2247Note that C<cc_harness> lives in the C<B> subdirectory of your perl
2248library directory. The utility called C<perlcc> may also be used to
2249help make use of this compiler.
2250
dc333d64 2251 perl -MO=C,-v,-DcA,-l2048 bar.pl > /dev/null
1a52ab62
MB
2252
2253=head1 BUGS
2254
2255Plenty. Current status: experimental.
7f20e9dd
GS
2256
2257=head1 AUTHOR
2258
2259Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>
2260
2261=cut