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