deparse -wl0 -i.bak
[p5sagit/p5-mst-13.2.git] / ext / B / B / C.pm
CommitLineData
a798dbf2 1# C.pm
2#
1a52ab62 3# Copyright (c) 1996, 1997, 1998 Malcolm Beattie
a798dbf2 4#
5# You may distribute under the terms of either the GNU General Public
6# License or the Artistic License, as specified in the README file.
7#
66a2622e 8package B::C::Section;
28b605d8 9
10our $VERSION = '1.00';
11
66a2622e 12use B ();
13use base B::Section;
14
15sub new
16{
17 my $class = shift;
18 my $o = $class->SUPER::new(@_);
19 push(@$o,[]);
20 return $o;
21}
22
23sub add
24{
25 my $section = shift;
26 push(@{$section->[-1]},@_);
27}
28
29sub index
30{
31 my $section = shift;
32 return scalar(@{$section->[-1]})-1;
33}
34
35sub output
36{
37 my ($section, $fh, $format) = @_;
38 my $sym = $section->symtable || {};
39 my $default = $section->default;
40 foreach (@{$section->[-1]})
41 {
42 s{(s\\_[0-9a-f]+)}{ exists($sym->{$1}) ? $sym->{$1} : $default; }ge;
43 printf $fh $format, $_;
44 }
45}
46
a798dbf2 47package B::C;
48use Exporter ();
49@ISA = qw(Exporter);
0cc1d052 50@EXPORT_OK = qw(output_all output_boilerplate output_main mark_unused
51 init_sections set_callback save_unused_subs objsym save_context);
a798dbf2 52
53use B qw(minus_c sv_undef walkoptree walksymtable main_root main_start peekop
54 class cstring cchar svref_2object compile_stats comppadlist hash
56eca212 55 threadsv_names main_cv init_av opnumber amagic_generation
b874ff32 56 AVf_REAL HEf_SVKEY);
a798dbf2 57use B::Asmdata qw(@specialsv_name);
58
59use FileHandle;
60use Carp;
61use strict;
f0cd5c3a 62use Config;
a798dbf2 63
64my $hv_index = 0;
65my $gv_index = 0;
66my $re_index = 0;
67my $pv_index = 0;
68my $anonsub_index = 0;
44887cfa 69my $initsub_index = 0;
a798dbf2 70
71my %symtable;
af765ed9 72my %xsub;
a798dbf2 73my $warn_undefined_syms;
74my $verbose;
66a2622e 75my %unused_sub_packages;
a798dbf2 76my $nullop_count;
66a2622e 77my $pv_copy_on_grow = 0;
a798dbf2 78my ($debug_cops, $debug_av, $debug_cv, $debug_mg);
dc333d64 79my $max_string_len;
a798dbf2 80
81my @threadsv_names;
82BEGIN {
83 @threadsv_names = threadsv_names();
84}
85
86# Code sections
66a2622e 87my ($init, $decl, $symsect, $binopsect, $condopsect, $copsect,
7934575e 88 $padopsect, $listopsect, $logopsect, $loopsect, $opsect, $pmopsect,
a798dbf2 89 $pvopsect, $svopsect, $unopsect, $svsect, $xpvsect, $xpvavsect,
90 $xpvhvsect, $xpvcvsect, $xpvivsect, $xpvnvsect, $xpvmgsect, $xpvlvsect,
af765ed9 91 $xrvsect, $xpvbmsect, $xpviosect );
a798dbf2 92
93sub walk_and_save_optree;
94my $saveoptree_callback = \&walk_and_save_optree;
95sub set_callback { $saveoptree_callback = shift }
96sub saveoptree { &$saveoptree_callback(@_) }
97
98sub walk_and_save_optree {
99 my ($name, $root, $start) = @_;
100 walkoptree($root, "save");
101 return objsym($start);
102}
103
104# Current workaround/fix for op_free() trying to free statically
105# defined OPs is to set op_seq = -1 and check for that in op_free().
106# Instead of hardwiring -1 in place of $op->seq, we use $op_seq
107# so that it can be changed back easily if necessary. In fact, to
108# stop compilers from moaning about a U16 being initialised with an
109# uncast -1 (the printf format is %d so we can't tweak it), we have
110# to "know" that op_seq is a U16 and use 65535. Ugh.
111my $op_seq = 65535;
112
0cc1d052 113# Look this up here so we can do just a number compare
114# rather than looking up the name of every BASEOP in B::OP
115my $OP_THREADSV = opnumber('threadsv');
a798dbf2 116
117sub savesym {
118 my ($obj, $value) = @_;
119 my $sym = sprintf("s\\_%x", $$obj);
120 $symtable{$sym} = $value;
121}
122
123sub objsym {
124 my $obj = shift;
125 return $symtable{sprintf("s\\_%x", $$obj)};
126}
127
128sub getsym {
129 my $sym = shift;
130 my $value;
131
132 return 0 if $sym eq "sym_0"; # special case
133 $value = $symtable{$sym};
134 if (defined($value)) {
135 return $value;
136 } else {
137 warn "warning: undefined symbol $sym\n" if $warn_undefined_syms;
138 return "UNUSED";
139 }
140}
141
142sub savepv {
66a2622e 143 my $pv = shift;
144 $pv = '' unless defined $pv; # Is this sane ?
a798dbf2 145 my $pvsym = 0;
146 my $pvmax = 0;
66a2622e 147 if ($pv_copy_on_grow) {
a798dbf2 148 my $cstring = cstring($pv);
149 if ($cstring ne "0") { # sic
150 $pvsym = sprintf("pv%d", $pv_index++);
151 $decl->add(sprintf("static char %s[] = %s;", $pvsym, $cstring));
152 }
153 } else {
154 $pvmax = length($pv) + 1;
155 }
156 return ($pvsym, $pvmax);
157}
158
159sub B::OP::save {
160 my ($op, $level) = @_;
2c0b28dd 161 my $sym = objsym($op);
162 return $sym if defined $sym;
a798dbf2 163 my $type = $op->type;
164 $nullop_count++ unless $type;
0cc1d052 165 if ($type == $OP_THREADSV) {
a798dbf2 166 # saves looking up ppaddr but it's a bit naughty to hard code this
167 $init->add(sprintf("(void)find_threadsv(%s);",
168 cstring($threadsv_names[$op->targ])));
169 }
dc333d64 170 $opsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x",
171 ${$op->next}, ${$op->sibling}, $op->targ,
a798dbf2 172 $type, $op_seq, $op->flags, $op->private));
dc333d64 173 my $ix = $opsect->index;
174 $init->add(sprintf("op_list[$ix].op_ppaddr = %s;", $op->ppaddr));
175 savesym($op, "&op_list[$ix]");
a798dbf2 176}
177
178sub B::FAKEOP::new {
179 my ($class, %objdata) = @_;
180 bless \%objdata, $class;
181}
182
183sub B::FAKEOP::save {
184 my ($op, $level) = @_;
dc333d64 185 $opsect->add(sprintf("%s, %s, NULL, %u, %u, %u, 0x%x, 0x%x",
186 $op->next, $op->sibling, $op->targ,
a798dbf2 187 $op->type, $op_seq, $op->flags, $op->private));
dc333d64 188 my $ix = $opsect->index;
189 $init->add(sprintf("op_list[$ix].op_ppaddr = %s;", $op->ppaddr));
190 return "&op_list[$ix]";
a798dbf2 191}
192
193sub B::FAKEOP::next { $_[0]->{"next"} || 0 }
194sub B::FAKEOP::type { $_[0]->{type} || 0}
195sub B::FAKEOP::sibling { $_[0]->{sibling} || 0 }
196sub B::FAKEOP::ppaddr { $_[0]->{ppaddr} || 0 }
197sub B::FAKEOP::targ { $_[0]->{targ} || 0 }
198sub B::FAKEOP::flags { $_[0]->{flags} || 0 }
199sub B::FAKEOP::private { $_[0]->{private} || 0 }
200
201sub B::UNOP::save {
202 my ($op, $level) = @_;
2c0b28dd 203 my $sym = objsym($op);
204 return $sym if defined $sym;
dc333d64 205 $unopsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x, s\\_%x",
206 ${$op->next}, ${$op->sibling},
a798dbf2 207 $op->targ, $op->type, $op_seq, $op->flags,
208 $op->private, ${$op->first}));
dc333d64 209 my $ix = $unopsect->index;
210 $init->add(sprintf("unop_list[$ix].op_ppaddr = %s;", $op->ppaddr));
211 savesym($op, "(OP*)&unop_list[$ix]");
a798dbf2 212}
213
214sub B::BINOP::save {
215 my ($op, $level) = @_;
2c0b28dd 216 my $sym = objsym($op);
217 return $sym if defined $sym;
dc333d64 218 $binopsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x",
219 ${$op->next}, ${$op->sibling},
a798dbf2 220 $op->targ, $op->type, $op_seq, $op->flags,
221 $op->private, ${$op->first}, ${$op->last}));
dc333d64 222 my $ix = $binopsect->index;
223 $init->add(sprintf("binop_list[$ix].op_ppaddr = %s;", $op->ppaddr));
224 savesym($op, "(OP*)&binop_list[$ix]");
a798dbf2 225}
226
227sub B::LISTOP::save {
228 my ($op, $level) = @_;
2c0b28dd 229 my $sym = objsym($op);
230 return $sym if defined $sym;
117dada2 231 $listopsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x",
dc333d64 232 ${$op->next}, ${$op->sibling},
a798dbf2 233 $op->targ, $op->type, $op_seq, $op->flags,
117dada2 234 $op->private, ${$op->first}, ${$op->last}));
dc333d64 235 my $ix = $listopsect->index;
236 $init->add(sprintf("listop_list[$ix].op_ppaddr = %s;", $op->ppaddr));
237 savesym($op, "(OP*)&listop_list[$ix]");
a798dbf2 238}
239
240sub B::LOGOP::save {
241 my ($op, $level) = @_;
2c0b28dd 242 my $sym = objsym($op);
243 return $sym if defined $sym;
dc333d64 244 $logopsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x",
245 ${$op->next}, ${$op->sibling},
a798dbf2 246 $op->targ, $op->type, $op_seq, $op->flags,
247 $op->private, ${$op->first}, ${$op->other}));
dc333d64 248 my $ix = $logopsect->index;
249 $init->add(sprintf("logop_list[$ix].op_ppaddr = %s;", $op->ppaddr));
250 savesym($op, "(OP*)&logop_list[$ix]");
a798dbf2 251}
252
a798dbf2 253sub B::LOOP::save {
254 my ($op, $level) = @_;
2c0b28dd 255 my $sym = objsym($op);
256 return $sym if defined $sym;
a798dbf2 257 #warn sprintf("LOOP: redoop %s, nextop %s, lastop %s\n",
258 # peekop($op->redoop), peekop($op->nextop),
259 # peekop($op->lastop)); # debug
117dada2 260 $loopsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x, s\\_%x, s\\_%x, s\\_%x",
dc333d64 261 ${$op->next}, ${$op->sibling},
a798dbf2 262 $op->targ, $op->type, $op_seq, $op->flags,
263 $op->private, ${$op->first}, ${$op->last},
117dada2 264 ${$op->redoop}, ${$op->nextop},
a798dbf2 265 ${$op->lastop}));
dc333d64 266 my $ix = $loopsect->index;
267 $init->add(sprintf("loop_list[$ix].op_ppaddr = %s;", $op->ppaddr));
268 savesym($op, "(OP*)&loop_list[$ix]");
a798dbf2 269}
270
271sub B::PVOP::save {
272 my ($op, $level) = @_;
2c0b28dd 273 my $sym = objsym($op);
274 return $sym if defined $sym;
dc333d64 275 $pvopsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x, %s",
276 ${$op->next}, ${$op->sibling},
a798dbf2 277 $op->targ, $op->type, $op_seq, $op->flags,
278 $op->private, cstring($op->pv)));
dc333d64 279 my $ix = $pvopsect->index;
280 $init->add(sprintf("pvop_list[$ix].op_ppaddr = %s;", $op->ppaddr));
281 savesym($op, "(OP*)&pvop_list[$ix]");
a798dbf2 282}
283
284sub B::SVOP::save {
285 my ($op, $level) = @_;
2c0b28dd 286 my $sym = objsym($op);
287 return $sym if defined $sym;
a798dbf2 288 my $svsym = $op->sv->save;
dc333d64 289 $svopsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x, Nullsv",
290 ${$op->next}, ${$op->sibling},
a798dbf2 291 $op->targ, $op->type, $op_seq, $op->flags,
5712119f 292 $op->private));
dc333d64 293 my $ix = $svopsect->index;
294 $init->add(sprintf("svop_list[$ix].op_ppaddr = %s;", $op->ppaddr));
295 $init->add("svop_list[$ix].op_sv = (SV*)$svsym;");
296 savesym($op, "(OP*)&svop_list[$ix]");
a798dbf2 297}
298
7934575e 299sub B::PADOP::save {
a798dbf2 300 my ($op, $level) = @_;
2c0b28dd 301 my $sym = objsym($op);
302 return $sym if defined $sym;
93865851 303 $padopsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x, 0",
dc333d64 304 ${$op->next}, ${$op->sibling},
a798dbf2 305 $op->targ, $op->type, $op_seq, $op->flags,
306 $op->private));
dc333d64 307 $init->add(sprintf("padop_list[%d].op_ppaddr = %s;", $padopsect->index, $op->ppaddr));
308 my $ix = $padopsect->index;
309 $init->add(sprintf("padop_list[$ix].op_padix = %ld;", $op->padix));
310 savesym($op, "(OP*)&padop_list[$ix]");
a798dbf2 311}
312
313sub B::COP::save {
314 my ($op, $level) = @_;
2c0b28dd 315 my $sym = objsym($op);
316 return $sym if defined $sym;
57843af0 317 warn sprintf("COP: line %d file %s\n", $op->line, $op->file)
a798dbf2 318 if $debug_cops;
93865851 319 $copsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x, %s, NULL, NULL, %u, %d, %u",
dc333d64 320 ${$op->next}, ${$op->sibling},
a798dbf2 321 $op->targ, $op->type, $op_seq, $op->flags,
322 $op->private, cstring($op->label), $op->cop_seq,
323 $op->arybase, $op->line));
dc333d64 324 my $ix = $copsect->index;
325 $init->add(sprintf("cop_list[$ix].op_ppaddr = %s;", $op->ppaddr));
326 $init->add(sprintf("CopFILE_set(&cop_list[$ix], %s);", cstring($op->file)),
327 sprintf("CopSTASHPV_set(&cop_list[$ix], %s);", cstring($op->stashpv)));
328 savesym($op, "(OP*)&cop_list[$ix]");
a798dbf2 329}
330
331sub B::PMOP::save {
332 my ($op, $level) = @_;
2c0b28dd 333 my $sym = objsym($op);
334 return $sym if defined $sym;
a798dbf2 335 my $replroot = $op->pmreplroot;
336 my $replstart = $op->pmreplstart;
337 my $replrootfield = sprintf("s\\_%x", $$replroot);
338 my $replstartfield = sprintf("s\\_%x", $$replstart);
339 my $gvsym;
340 my $ppaddr = $op->ppaddr;
341 if ($$replroot) {
342 # OP_PUSHRE (a mutated version of OP_MATCH for the regexp
343 # argument to a split) stores a GV in op_pmreplroot instead
344 # of a substitution syntax tree. We don't want to walk that...
3f872cb9 345 if ($op->name eq "pushre") {
a798dbf2 346 $gvsym = $replroot->save;
347# warn "PMOP::save saving a pp_pushre with GV $gvsym\n"; # debug
348 $replrootfield = 0;
349 } else {
350 $replstartfield = saveoptree("*ignore*", $replroot, $replstart);
351 }
352 }
353 # pmnext handling is broken in perl itself, I think. Bad op_pmnext
354 # fields aren't noticed in perl's runtime (unless you try reset) but we
355 # segfault when trying to dereference it to find op->op_pmnext->op_type
117dada2 356 $pmopsect->add(sprintf("s\\_%x, s\\_%x, NULL, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x, %s, %s, 0, 0, 0x%x, 0x%x",
dc333d64 357 ${$op->next}, ${$op->sibling}, $op->targ,
a798dbf2 358 $op->type, $op_seq, $op->flags, $op->private,
117dada2 359 ${$op->first}, ${$op->last},
a798dbf2 360 $replrootfield, $replstartfield,
361 $op->pmflags, $op->pmpermflags,));
362 my $pm = sprintf("pmop_list[%d]", $pmopsect->index);
dc333d64 363 $init->add(sprintf("$pm.op_ppaddr = %s;", $ppaddr));
a798dbf2 364 my $re = $op->precomp;
365 if (defined($re)) {
366 my $resym = sprintf("re%d", $re_index++);
367 $decl->add(sprintf("static char *$resym = %s;", cstring($re)));
f5eac215 368 $init->add(sprintf("PM_SETRE(&$pm,pregcomp($resym, $resym + %u, &$pm));",
a798dbf2 369 length($re)));
370 }
371 if ($gvsym) {
372 $init->add("$pm.op_pmreplroot = (OP*)$gvsym;");
373 }
dc333d64 374 savesym($op, "(OP*)&$pm");
a798dbf2 375}
376
377sub B::SPECIAL::save {
378 my ($sv) = @_;
379 # special case: $$sv is not the address but an index into specialsv_list
380# warn "SPECIAL::save specialsv $$sv\n"; # debug
381 my $sym = $specialsv_name[$$sv];
382 if (!defined($sym)) {
383 confess "unknown specialsv index $$sv passed to B::SPECIAL::save";
384 }
385 return $sym;
386}
387
388sub B::OBJECT::save {}
389
390sub B::NULL::save {
391 my ($sv) = @_;
392 my $sym = objsym($sv);
393 return $sym if defined $sym;
394# warn "Saving SVt_NULL SV\n"; # debug
395 # debug
87d7fd28 396 if ($$sv == 0) {
397 warn "NULL::save for sv = 0 called from @{[(caller(1))[3]]}\n";
398 return savesym($sv, "Nullsv /* XXX */");
399 }
932e9ff9 400 $svsect->add(sprintf("0, %u, 0x%x", $sv->REFCNT , $sv->FLAGS));
a798dbf2 401 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
402}
403
404sub B::IV::save {
405 my ($sv) = @_;
406 my $sym = objsym($sv);
407 return $sym if defined $sym;
408 $xpvivsect->add(sprintf("0, 0, 0, %d", $sv->IVX));
409 $svsect->add(sprintf("&xpviv_list[%d], %lu, 0x%x",
932e9ff9 410 $xpvivsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 411 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
412}
413
414sub B::NV::save {
415 my ($sv) = @_;
416 my $sym = objsym($sv);
417 return $sym if defined $sym;
56eca212 418 my $val= $sv->NVX;
419 $val .= '.00' if $val =~ /^-?\d+$/;
420 $xpvnvsect->add(sprintf("0, 0, 0, %d, %s", $sv->IVX, $val));
a798dbf2 421 $svsect->add(sprintf("&xpvnv_list[%d], %lu, 0x%x",
932e9ff9 422 $xpvnvsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 423 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
424}
425
dc333d64 426sub savepvn {
427 my ($dest,$pv) = @_;
428 my @res;
429 if (defined $max_string_len && length($pv) > $max_string_len) {
430 push @res, sprintf("New(0,%s,%u,char);", $dest, length($pv)+1);
431 my $offset = 0;
432 while (length $pv) {
433 my $str = substr $pv, 0, $max_string_len, '';
434 push @res, sprintf("Copy(%s,$dest+$offset,%u,char);",
435 cstring($str), length($str));
436 $offset += length $str;
437 }
438 push @res, sprintf("%s[%u] = '\\0';", $dest, $offset);
439 }
440 else {
441 push @res, sprintf("%s = savepvn(%s, %u);", $dest,
442 cstring($pv), length($pv));
443 }
444 return @res;
445}
446
a798dbf2 447sub B::PVLV::save {
448 my ($sv) = @_;
449 my $sym = objsym($sv);
450 return $sym if defined $sym;
451 my $pv = $sv->PV;
452 my $len = length($pv);
453 my ($pvsym, $pvmax) = savepv($pv);
454 my ($lvtarg, $lvtarg_sym);
455 $xpvlvsect->add(sprintf("%s, %u, %u, %d, %g, 0, 0, %u, %u, 0, %s",
456 $pvsym, $len, $pvmax, $sv->IVX, $sv->NVX,
457 $sv->TARGOFF, $sv->TARGLEN, cchar($sv->TYPE)));
458 $svsect->add(sprintf("&xpvlv_list[%d], %lu, 0x%x",
932e9ff9 459 $xpvlvsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 460 if (!$pv_copy_on_grow) {
dc333d64 461 $init->add(savepvn(sprintf("xpvlv_list[%d].xpv_pv",
462 $xpvlvsect->index), $pv));
a798dbf2 463 }
464 $sv->save_magic;
465 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
466}
467
468sub B::PVIV::save {
469 my ($sv) = @_;
470 my $sym = objsym($sv);
471 return $sym if defined $sym;
472 my $pv = $sv->PV;
473 my $len = length($pv);
474 my ($pvsym, $pvmax) = savepv($pv);
475 $xpvivsect->add(sprintf("%s, %u, %u, %d", $pvsym, $len, $pvmax, $sv->IVX));
476 $svsect->add(sprintf("&xpviv_list[%d], %u, 0x%x",
932e9ff9 477 $xpvivsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 478 if (!$pv_copy_on_grow) {
dc333d64 479 $init->add(savepvn(sprintf("xpviv_list[%d].xpv_pv",
480 $xpvivsect->index), $pv));
a798dbf2 481 }
482 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
483}
484
485sub B::PVNV::save {
486 my ($sv) = @_;
487 my $sym = objsym($sv);
488 return $sym if defined $sym;
66a2622e 489 my $pv = $sv->PV;
490 $pv = '' unless defined $pv;
a798dbf2 491 my $len = length($pv);
492 my ($pvsym, $pvmax) = savepv($pv);
56eca212 493 my $val= $sv->NVX;
494 $val .= '.00' if $val =~ /^-?\d+$/;
a798dbf2 495 $xpvnvsect->add(sprintf("%s, %u, %u, %d, %s",
56eca212 496 $pvsym, $len, $pvmax, $sv->IVX, $val));
a798dbf2 497 $svsect->add(sprintf("&xpvnv_list[%d], %lu, 0x%x",
932e9ff9 498 $xpvnvsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 499 if (!$pv_copy_on_grow) {
dc333d64 500 $init->add(savepvn(sprintf("xpvnv_list[%d].xpv_pv",
501 $xpvnvsect->index), $pv));
a798dbf2 502 }
503 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
504}
505
506sub B::BM::save {
507 my ($sv) = @_;
508 my $sym = objsym($sv);
509 return $sym if defined $sym;
510 my $pv = $sv->PV . "\0" . $sv->TABLE;
511 my $len = length($pv);
512 $xpvbmsect->add(sprintf("0, %u, %u, %d, %s, 0, 0, %d, %u, 0x%x",
513 $len, $len + 258, $sv->IVX, $sv->NVX,
514 $sv->USEFUL, $sv->PREVIOUS, $sv->RARE));
515 $svsect->add(sprintf("&xpvbm_list[%d], %lu, 0x%x",
932e9ff9 516 $xpvbmsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 517 $sv->save_magic;
dc333d64 518 $init->add(savepvn(sprintf("xpvbm_list[%d].xpv_pv",
519 $xpvbmsect->index), $pv),
a798dbf2 520 sprintf("xpvbm_list[%d].xpv_cur = %u;",
521 $xpvbmsect->index, $len - 257));
522 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
523}
524
525sub B::PV::save {
526 my ($sv) = @_;
527 my $sym = objsym($sv);
528 return $sym if defined $sym;
529 my $pv = $sv->PV;
530 my $len = length($pv);
531 my ($pvsym, $pvmax) = savepv($pv);
532 $xpvsect->add(sprintf("%s, %u, %u", $pvsym, $len, $pvmax));
533 $svsect->add(sprintf("&xpv_list[%d], %lu, 0x%x",
932e9ff9 534 $xpvsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 535 if (!$pv_copy_on_grow) {
dc333d64 536 $init->add(savepvn(sprintf("xpv_list[%d].xpv_pv",
537 $xpvsect->index), $pv));
a798dbf2 538 }
539 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
540}
541
542sub B::PVMG::save {
543 my ($sv) = @_;
544 my $sym = objsym($sv);
545 return $sym if defined $sym;
546 my $pv = $sv->PV;
547 my $len = length($pv);
548 my ($pvsym, $pvmax) = savepv($pv);
549 $xpvmgsect->add(sprintf("%s, %u, %u, %d, %s, 0, 0",
550 $pvsym, $len, $pvmax, $sv->IVX, $sv->NVX));
551 $svsect->add(sprintf("&xpvmg_list[%d], %lu, 0x%x",
932e9ff9 552 $xpvmgsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 553 if (!$pv_copy_on_grow) {
dc333d64 554 $init->add(savepvn(sprintf("xpvmg_list[%d].xpv_pv",
555 $xpvmgsect->index), $pv));
a798dbf2 556 }
557 $sym = savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
558 $sv->save_magic;
559 return $sym;
560}
561
562sub B::PVMG::save_magic {
563 my ($sv) = @_;
564 #warn sprintf("saving magic for %s (0x%x)\n", class($sv), $$sv); # debug
565 my $stash = $sv->SvSTASH;
56eca212 566 $stash->save;
a798dbf2 567 if ($$stash) {
568 warn sprintf("xmg_stash = %s (0x%x)\n", $stash->NAME, $$stash)
569 if $debug_mg;
570 # XXX Hope stash is already going to be saved.
571 $init->add(sprintf("SvSTASH(s\\_%x) = s\\_%x;", $$sv, $$stash));
572 }
573 my @mgchain = $sv->MAGIC;
88b39979 574 my ($mg, $type, $obj, $ptr,$len,$ptrsv);
a798dbf2 575 foreach $mg (@mgchain) {
576 $type = $mg->TYPE;
577 $obj = $mg->OBJ;
578 $ptr = $mg->PTR;
88b39979 579 $len=$mg->LENGTH;
a798dbf2 580 if ($debug_mg) {
581 warn sprintf("magic %s (0x%x), obj %s (0x%x), type %s, ptr %s\n",
582 class($sv), $$sv, class($obj), $$obj,
583 cchar($type), cstring($ptr));
584 }
56eca212 585 $obj->save;
88b39979 586 if ($len == HEf_SVKEY){
587 #The pointer is an SV*
588 $ptrsv=svref_2object($ptr)->save;
5ab5c7a4 589 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s,(char *) %s, %d);",
88b39979 590 $$sv, $$obj, cchar($type),$ptrsv,$len));
591 }else{
592 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
a798dbf2 593 $$sv, $$obj, cchar($type),cstring($ptr),$len));
88b39979 594 }
a798dbf2 595 }
596}
597
598sub B::RV::save {
599 my ($sv) = @_;
600 my $sym = objsym($sv);
601 return $sym if defined $sym;
66a2622e 602 my $rv = $sv->RV->save;
603 $rv =~ s/^\([AGHS]V\s*\*\)\s*(\&sv_list.*)$/$1/;
604 $xrvsect->add($rv);
a798dbf2 605 $svsect->add(sprintf("&xrv_list[%d], %lu, 0x%x",
932e9ff9 606 $xrvsect->index, $sv->REFCNT , $sv->FLAGS));
a798dbf2 607 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
608}
609
610sub try_autoload {
611 my ($cvstashname, $cvname) = @_;
612 warn sprintf("No definition for sub %s::%s\n", $cvstashname, $cvname);
613 # Handle AutoLoader classes explicitly. Any more general AUTOLOAD
614 # use should be handled by the class itself.
615 no strict 'refs';
616 my $isa = \@{"$cvstashname\::ISA"};
617 if (grep($_ eq "AutoLoader", @$isa)) {
618 warn "Forcing immediate load of sub derived from AutoLoader\n";
619 # Tweaked version of AutoLoader::AUTOLOAD
620 my $dir = $cvstashname;
621 $dir =~ s(::)(/)g;
622 eval { require "auto/$dir/$cvname.al" };
623 if ($@) {
624 warn qq(failed require "auto/$dir/$cvname.al": $@\n);
625 return 0;
626 } else {
627 return 1;
628 }
629 }
630}
e9a14d94 631sub Dummy_initxs{};
a798dbf2 632sub B::CV::save {
633 my ($cv) = @_;
634 my $sym = objsym($cv);
635 if (defined($sym)) {
636# warn sprintf("CV 0x%x already saved as $sym\n", $$cv); # debug
637 return $sym;
638 }
639 # Reserve a place in svsect and xpvcvsect and record indices
af765ed9 640 my $gv = $cv->GV;
6771324e 641 my ($cvname, $cvstashname);
642 if ($$gv){
643 $cvname = $gv->NAME;
644 $cvstashname = $gv->STASH->NAME;
645 }
af765ed9 646 my $root = $cv->ROOT;
647 my $cvxsub = $cv->XSUB;
e9a14d94 648 #INIT is removed from the symbol table, so this call must come
649 # from PL_initav->save. Re-bootstrapping will push INIT back in
650 # so nullop should be sent.
651 if ($cvxsub && ($cvname ne "INIT")) {
af765ed9 652 my $egv = $gv->EGV;
653 my $stashname = $egv->STASH->NAME;
be6f3502 654 if ($cvname eq "bootstrap")
655 {
b195d487 656 my $file = $gv->FILE;
be6f3502 657 $decl->add("/* bootstrap $file */");
658 warn "Bootstrap $stashname $file\n";
659 $xsub{$stashname}='Dynamic';
660 # $xsub{$stashname}='Static' unless $xsub{$stashname};
a0e9c8c7 661 return qq/NULL/;
be6f3502 662 }
a0e9c8c7 663 warn sprintf("stub for XSUB $cvstashname\:\:$cvname CV 0x%x\n", $$cv) if $debug_cv;
be6f3502 664 return qq/(perl_get_cv("$stashname\:\:$cvname",TRUE))/;
e9a14d94 665 }
666 if ($cvxsub && $cvname eq "INIT") {
667 no strict 'refs';
668 return svref_2object(\&Dummy_initxs)->save;
af765ed9 669 }
a798dbf2 670 my $sv_ix = $svsect->index + 1;
671 $svsect->add("svix$sv_ix");
672 my $xpvcv_ix = $xpvcvsect->index + 1;
673 $xpvcvsect->add("xpvcvix$xpvcv_ix");
674 # Save symbol now so that GvCV() doesn't recurse back to us via CvGV()
675 $sym = savesym($cv, "&sv_list[$sv_ix]");
a0e9c8c7 676 warn sprintf("saving $cvstashname\:\:$cvname CV 0x%x as $sym\n", $$cv) if $debug_cv;
a798dbf2 677 if (!$$root && !$cvxsub) {
678 if (try_autoload($cvstashname, $cvname)) {
679 # Recalculate root and xsub
680 $root = $cv->ROOT;
681 $cvxsub = $cv->XSUB;
682 if ($$root || $cvxsub) {
683 warn "Successful forced autoload\n";
684 }
685 }
686 }
687 my $startfield = 0;
688 my $padlist = $cv->PADLIST;
689 my $pv = $cv->PV;
690 my $xsub = 0;
691 my $xsubany = "Nullany";
692 if ($$root) {
693 warn sprintf("saving op tree for CV 0x%x, root = 0x%x\n",
694 $$cv, $$root) if $debug_cv;
695 my $ppname = "";
696 if ($$gv) {
697 my $stashname = $gv->STASH->NAME;
698 my $gvname = $gv->NAME;
699 if ($gvname ne "__ANON__") {
700 $ppname = (${$gv->FORM} == $$cv) ? "pp_form_" : "pp_sub_";
701 $ppname .= ($stashname eq "main") ?
702 $gvname : "$stashname\::$gvname";
703 $ppname =~ s/::/__/g;
44887cfa 704 if ($gvname eq "INIT"){
705 $ppname .= "_$initsub_index";
706 $initsub_index++;
707 }
a798dbf2 708 }
709 }
710 if (!$ppname) {
711 $ppname = "pp_anonsub_$anonsub_index";
712 $anonsub_index++;
713 }
714 $startfield = saveoptree($ppname, $root, $cv->START, $padlist->ARRAY);
715 warn sprintf("done saving op tree for CV 0x%x, name %s, root 0x%x\n",
716 $$cv, $ppname, $$root) if $debug_cv;
717 if ($$padlist) {
718 warn sprintf("saving PADLIST 0x%x for CV 0x%x\n",
719 $$padlist, $$cv) if $debug_cv;
720 $padlist->save;
721 warn sprintf("done saving PADLIST 0x%x for CV 0x%x\n",
722 $$padlist, $$cv) if $debug_cv;
723 }
724 }
a798dbf2 725 else {
726 warn sprintf("No definition for sub %s::%s (unable to autoload)\n",
727 $cvstashname, $cvname); # debug
66a2622e 728 }
729 $pv = '' unless defined $pv; # Avoid use of undef warnings
5712119f 730 $symsect->add(sprintf("xpvcvix%d\t%s, %u, 0, %d, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub, $xsubany, Nullgv, \"\", %d, s\\_%x, (CV*)s\\_%x, 0x%x",
a798dbf2 731 $xpvcv_ix, cstring($pv), length($pv), $cv->IVX,
732 $cv->NVX, $startfield, ${$cv->ROOT}, $cv->DEPTH,
5cfd8ad4 733 $$padlist, ${$cv->OUTSIDE}, $cv->CvFLAGS));
734
735 if (${$cv->OUTSIDE} == ${main_cv()}){
736 $init->add(sprintf("CvOUTSIDE(s\\_%x)=PL_main_cv;",$$cv));
358b5eb8 737 $init->add(sprintf("SvREFCNT_inc(PL_main_cv);"));
5cfd8ad4 738 }
739
a798dbf2 740 if ($$gv) {
741 $gv->save;
742 $init->add(sprintf("CvGV(s\\_%x) = s\\_%x;",$$cv,$$gv));
743 warn sprintf("done saving GV 0x%x for CV 0x%x\n",
744 $$gv, $$cv) if $debug_cv;
745 }
57843af0 746 $init->add(sprintf("CvFILE($sym) = %s;", cstring($cv->FILE)));
a798dbf2 747 my $stash = $cv->STASH;
748 if ($$stash) {
749 $stash->save;
750 $init->add(sprintf("CvSTASH(s\\_%x) = s\\_%x;", $$cv, $$stash));
751 warn sprintf("done saving STASH 0x%x for CV 0x%x\n",
752 $$stash, $$cv) if $debug_cv;
753 }
754 $symsect->add(sprintf("svix%d\t(XPVCV*)&xpvcv_list[%u], %lu, 0x%x",
932e9ff9 755 $sv_ix, $xpvcv_ix, $cv->REFCNT +1 , $cv->FLAGS));
a798dbf2 756 return $sym;
757}
758
759sub B::GV::save {
be6f3502 760 my ($gv) = @_;
a798dbf2 761 my $sym = objsym($gv);
762 if (defined($sym)) {
763 #warn sprintf("GV 0x%x already saved as $sym\n", $$gv); # debug
764 return $sym;
765 } else {
766 my $ix = $gv_index++;
767 $sym = savesym($gv, "gv_list[$ix]");
768 #warn sprintf("Saving GV 0x%x as $sym\n", $$gv); # debug
769 }
87d7fd28 770 my $is_empty = $gv->is_empty;
a798dbf2 771 my $gvname = $gv->NAME;
772 my $name = cstring($gv->STASH->NAME . "::" . $gvname);
773 #warn "GV name is $name\n"; # debug
a798dbf2 774 my $egvsym;
87d7fd28 775 unless ($is_empty) {
776 my $egv = $gv->EGV;
777 if ($$gv != $$egv) {
778 #warn(sprintf("EGV name is %s, saving it now\n",
779 # $egv->STASH->NAME . "::" . $egv->NAME)); # debug
780 $egvsym = $egv->save;
781 }
a798dbf2 782 }
783 $init->add(qq[$sym = gv_fetchpv($name, TRUE, SVt_PV);],
784 sprintf("SvFLAGS($sym) = 0x%x;", $gv->FLAGS),
87d7fd28 785 sprintf("GvFLAGS($sym) = 0x%x;", $gv->GvFLAGS));
786 $init->add(sprintf("GvLINE($sym) = %u;", $gv->LINE)) unless $is_empty;
787
a798dbf2 788 # Shouldn't need to do save_magic since gv_fetchpv handles that
789 #$gv->save_magic;
790 my $refcnt = $gv->REFCNT + 1;
791 $init->add(sprintf("SvREFCNT($sym) += %u;", $refcnt - 1)) if $refcnt > 1;
87d7fd28 792
793 return $sym if $is_empty;
794
a798dbf2 795 my $gvrefcnt = $gv->GvREFCNT;
796 if ($gvrefcnt > 1) {
797 $init->add(sprintf("GvREFCNT($sym) += %u;", $gvrefcnt - 1));
798 }
799 if (defined($egvsym)) {
800 # Shared glob *foo = *bar
801 $init->add("gp_free($sym);",
802 "GvGP($sym) = GvGP($egvsym);");
803 } elsif ($gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/) {
804 # Don't save subfields of special GVs (*_, *1, *# and so on)
805# warn "GV::save saving subfields\n"; # debug
806 my $gvsv = $gv->SV;
807 if ($$gvsv) {
cfa4c8ee 808 $gvsv->save;
a798dbf2 809 $init->add(sprintf("GvSV($sym) = s\\_%x;", $$gvsv));
810# warn "GV::save \$$name\n"; # debug
a798dbf2 811 }
812 my $gvav = $gv->AV;
813 if ($$gvav) {
cfa4c8ee 814 $gvav->save;
a798dbf2 815 $init->add(sprintf("GvAV($sym) = s\\_%x;", $$gvav));
816# warn "GV::save \@$name\n"; # debug
a798dbf2 817 }
818 my $gvhv = $gv->HV;
819 if ($$gvhv) {
cfa4c8ee 820 $gvhv->save;
a798dbf2 821 $init->add(sprintf("GvHV($sym) = s\\_%x;", $$gvhv));
822# warn "GV::save \%$name\n"; # debug
a798dbf2 823 }
824 my $gvcv = $gv->CV;
be6f3502 825 if ($$gvcv) {
826 my $origname=cstring($gvcv->GV->EGV->STASH->NAME .
827 "::" . $gvcv->GV->EGV->NAME);
828 if (0 && $gvcv->XSUB && $name ne $origname) { #XSUB alias
829 # must save as a 'stub' so newXS() has a CV to populate
af765ed9 830 $init->add("{ CV *cv;");
be6f3502 831 $init->add("\tcv=perl_get_cv($origname,TRUE);");
af765ed9 832 $init->add("\tGvCV($sym)=cv;");
833 $init->add("\tSvREFCNT_inc((SV *)cv);");
be6f3502 834 $init->add("}");
835 } else {
836 $init->add(sprintf("GvCV($sym) = (CV*)(%s);", $gvcv->save));
837# warn "GV::save &$name\n"; # debug
838 }
af765ed9 839 }
b195d487 840 $init->add(sprintf("GvFILE($sym) = %s;", cstring($gv->FILE)));
841# warn "GV::save GvFILE(*$name)\n"; # debug
a798dbf2 842 my $gvform = $gv->FORM;
843 if ($$gvform) {
cfa4c8ee 844 $gvform->save;
a798dbf2 845 $init->add(sprintf("GvFORM($sym) = (CV*)s\\_%x;", $$gvform));
846# warn "GV::save GvFORM(*$name)\n"; # debug
a798dbf2 847 }
848 my $gvio = $gv->IO;
849 if ($$gvio) {
cfa4c8ee 850 $gvio->save;
a798dbf2 851 $init->add(sprintf("GvIOp($sym) = s\\_%x;", $$gvio));
852# warn "GV::save GvIO(*$name)\n"; # debug
a798dbf2 853 }
854 }
855 return $sym;
856}
857sub B::AV::save {
858 my ($av) = @_;
859 my $sym = objsym($av);
860 return $sym if defined $sym;
861 my $avflags = $av->AvFLAGS;
862 $xpvavsect->add(sprintf("0, -1, -1, 0, 0.0, 0, Nullhv, 0, 0, 0x%x",
863 $avflags));
864 $svsect->add(sprintf("&xpvav_list[%d], %lu, 0x%x",
932e9ff9 865 $xpvavsect->index, $av->REFCNT , $av->FLAGS));
a798dbf2 866 my $sv_list_index = $svsect->index;
867 my $fill = $av->FILL;
868 $av->save_magic;
869 warn sprintf("saving AV 0x%x FILL=$fill AvFLAGS=0x%x", $$av, $avflags)
870 if $debug_av;
871 # XXX AVf_REAL is wrong test: need to save comppadlist but not stack
872 #if ($fill > -1 && ($avflags & AVf_REAL)) {
873 if ($fill > -1) {
874 my @array = $av->ARRAY;
875 if ($debug_av) {
876 my $el;
877 my $i = 0;
878 foreach $el (@array) {
879 warn sprintf("AV 0x%x[%d] = %s 0x%x\n",
880 $$av, $i++, class($el), $$el);
881 }
882 }
883 my @names = map($_->save, @array);
884 # XXX Better ways to write loop?
885 # Perhaps svp[0] = ...; svp[1] = ...; svp[2] = ...;
886 # Perhaps I32 i = 0; svp[i++] = ...; svp[i++] = ...; svp[i++] = ...;
887 $init->add("{",
888 "\tSV **svp;",
889 "\tAV *av = (AV*)&sv_list[$sv_list_index];",
890 "\tav_extend(av, $fill);",
891 "\tsvp = AvARRAY(av);",
892 map("\t*svp++ = (SV*)$_;", @names),
893 "\tAvFILLp(av) = $fill;",
894 "}");
895 } else {
896 my $max = $av->MAX;
897 $init->add("av_extend((AV*)&sv_list[$sv_list_index], $max);")
898 if $max > -1;
899 }
900 return savesym($av, "(AV*)&sv_list[$sv_list_index]");
901}
902
903sub B::HV::save {
904 my ($hv) = @_;
905 my $sym = objsym($hv);
906 return $sym if defined $sym;
907 my $name = $hv->NAME;
908 if ($name) {
909 # It's a stash
910
911 # A perl bug means HvPMROOT isn't altered when a PMOP is freed. Usually
912 # the only symptom is that sv_reset tries to reset the PMf_USED flag of
913 # a trashed op but we look at the trashed op_type and segfault.
914 #my $adpmroot = ${$hv->PMROOT};
915 my $adpmroot = 0;
916 $decl->add("static HV *hv$hv_index;");
917 # XXX Beware of weird package names containing double-quotes, \n, ...?
918 $init->add(qq[hv$hv_index = gv_stashpv("$name", TRUE);]);
919 if ($adpmroot) {
920 $init->add(sprintf("HvPMROOT(hv$hv_index) = (PMOP*)s\\_%x;",
921 $adpmroot));
922 }
923 $sym = savesym($hv, "hv$hv_index");
924 $hv_index++;
925 return $sym;
926 }
927 # It's just an ordinary HV
928 $xpvhvsect->add(sprintf("0, 0, %d, 0, 0.0, 0, Nullhv, %d, 0, 0, 0",
929 $hv->MAX, $hv->RITER));
930 $svsect->add(sprintf("&xpvhv_list[%d], %lu, 0x%x",
932e9ff9 931 $xpvhvsect->index, $hv->REFCNT , $hv->FLAGS));
a798dbf2 932 my $sv_list_index = $svsect->index;
933 my @contents = $hv->ARRAY;
934 if (@contents) {
935 my $i;
936 for ($i = 1; $i < @contents; $i += 2) {
937 $contents[$i] = $contents[$i]->save;
938 }
939 $init->add("{", "\tHV *hv = (HV*)&sv_list[$sv_list_index];");
940 while (@contents) {
941 my ($key, $value) = splice(@contents, 0, 2);
942 $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
943 cstring($key),length($key),$value, hash($key)));
cf86991c 944# $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
945# cstring($key),length($key),$value, 0));
a798dbf2 946 }
947 $init->add("}");
948 }
56eca212 949 $hv->save_magic();
a798dbf2 950 return savesym($hv, "(HV*)&sv_list[$sv_list_index]");
951}
952
953sub B::IO::save {
954 my ($io) = @_;
955 my $sym = objsym($io);
956 return $sym if defined $sym;
957 my $pv = $io->PV;
66a2622e 958 $pv = '' unless defined $pv;
a798dbf2 959 my $len = length($pv);
960 $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",
961 $len, $len+1, $io->IVX, $io->NVX, $io->LINES,
962 $io->PAGE, $io->PAGE_LEN, $io->LINES_LEFT,
963 cstring($io->TOP_NAME), cstring($io->FMT_NAME),
964 cstring($io->BOTTOM_NAME), $io->SUBPROCESS,
965 cchar($io->IoTYPE), $io->IoFLAGS));
966 $svsect->add(sprintf("&xpvio_list[%d], %lu, 0x%x",
932e9ff9 967 $xpviosect->index, $io->REFCNT , $io->FLAGS));
a798dbf2 968 $sym = savesym($io, sprintf("(IO*)&sv_list[%d]", $svsect->index));
969 my ($field, $fsym);
970 foreach $field (qw(TOP_GV FMT_GV BOTTOM_GV)) {
971 $fsym = $io->$field();
972 if ($$fsym) {
973 $init->add(sprintf("Io$field($sym) = (GV*)s\\_%x;", $$fsym));
974 $fsym->save;
975 }
976 }
977 $io->save_magic;
978 return $sym;
979}
980
981sub B::SV::save {
982 my $sv = shift;
983 # This is where we catch an honest-to-goodness Nullsv (which gets
984 # blessed into B::SV explicitly) and any stray erroneous SVs.
985 return 0 unless $$sv;
986 confess sprintf("cannot save that type of SV: %s (0x%x)\n",
987 class($sv), $$sv);
988}
989
990sub output_all {
991 my $init_name = shift;
992 my $section;
993 my @sections = ($opsect, $unopsect, $binopsect, $logopsect, $condopsect,
7934575e 994 $listopsect, $pmopsect, $svopsect, $padopsect, $pvopsect,
66a2622e 995 $loopsect, $copsect, $svsect, $xpvsect,
a798dbf2 996 $xpvavsect, $xpvhvsect, $xpvcvsect, $xpvivsect, $xpvnvsect,
997 $xpvmgsect, $xpvlvsect, $xrvsect, $xpvbmsect, $xpviosect);
998 $symsect->output(\*STDOUT, "#define %s\n");
999 print "\n";
1000 output_declarations();
1001 foreach $section (@sections) {
1002 my $lines = $section->index + 1;
1003 if ($lines) {
1004 my $name = $section->name;
1005 my $typename = ($name eq "xpvcv") ? "XPVCV_or_similar" : uc($name);
1006 print "Static $typename ${name}_list[$lines];\n";
1007 }
1008 }
1009 $decl->output(\*STDOUT, "%s\n");
1010 print "\n";
1011 foreach $section (@sections) {
1012 my $lines = $section->index + 1;
1013 if ($lines) {
1014 my $name = $section->name;
1015 my $typename = ($name eq "xpvcv") ? "XPVCV_or_similar" : uc($name);
1016 printf "static %s %s_list[%u] = {\n", $typename, $name, $lines;
1017 $section->output(\*STDOUT, "\t{ %s },\n");
1018 print "};\n\n";
1019 }
1020 }
1021
1022 print <<"EOT";
1023static int $init_name()
1024{
af765ed9 1025 dTARG;
39644a26 1026 dSP;
a798dbf2 1027EOT
1028 $init->output(\*STDOUT, "\t%s\n");
1029 print "\treturn 0;\n}\n";
1030 if ($verbose) {
1031 warn compile_stats();
1032 warn "NULLOP count: $nullop_count\n";
1033 }
1034}
1035
1036sub output_declarations {
1037 print <<'EOT';
1038#ifdef BROKEN_STATIC_REDECL
1039#define Static extern
1040#else
1041#define Static static
1042#endif /* BROKEN_STATIC_REDECL */
1043
1044#ifdef BROKEN_UNION_INIT
1045/*
1046 * Cribbed from cv.h with ANY (a union) replaced by void*.
1047 * Some pre-Standard compilers can't cope with initialising unions. Ho hum.
1048 */
1049typedef struct {
1050 char * xpv_pv; /* pointer to malloced string */
1051 STRLEN xpv_cur; /* length of xp_pv as a C string */
1052 STRLEN xpv_len; /* allocated size */
1053 IV xof_off; /* integer value */
76ef7183 1054 NV xnv_nv; /* numeric value, if any */
a798dbf2 1055 MAGIC* xmg_magic; /* magic for scalar array */
1056 HV* xmg_stash; /* class package */
1057
1058 HV * xcv_stash;
1059 OP * xcv_start;
1060 OP * xcv_root;
acfe0abc 1061 void (*xcv_xsub) (pTHX_ CV*);
76ef7183 1062 ANY xcv_xsubany;
a798dbf2 1063 GV * xcv_gv;
57843af0 1064 char * xcv_file;
b195d487 1065 long xcv_depth; /* >= 2 indicates recursive call */
a798dbf2 1066 AV * xcv_padlist;
1067 CV * xcv_outside;
4d1ff10f 1068#ifdef USE_5005THREADS
a798dbf2 1069 perl_mutex *xcv_mutexp;
1070 struct perl_thread *xcv_owner; /* current owner thread */
4d1ff10f 1071#endif /* USE_5005THREADS */
fc290457 1072 cv_flags_t xcv_flags;
a798dbf2 1073} XPVCV_or_similar;
1074#define ANYINIT(i) i
1075#else
1076#define XPVCV_or_similar XPVCV
1077#define ANYINIT(i) {i}
1078#endif /* BROKEN_UNION_INIT */
1079#define Nullany ANYINIT(0)
1080
1081#define UNUSED 0
1082#define sym_0 0
1083
1084EOT
1085 print "static GV *gv_list[$gv_index];\n" if $gv_index;
1086 print "\n";
1087}
1088
1089
1090sub output_boilerplate {
1091 print <<'EOT';
1092#include "EXTERN.h"
1093#include "perl.h"
93865851 1094#include "XSUB.h"
a798dbf2 1095
1096/* Workaround for mapstart: the only op which needs a different ppaddr */
3f872cb9 1097#undef Perl_pp_mapstart
1098#define Perl_pp_mapstart Perl_pp_grepstart
511dd457 1099#define XS_DynaLoader_boot_DynaLoader boot_DynaLoader
5712119f 1100EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
a798dbf2 1101
5712119f 1102static void xs_init (pTHX);
1103static void dl_init (pTHX);
a798dbf2 1104static PerlInterpreter *my_perl;
1105EOT
1106}
1107
1108sub output_main {
1109 print <<'EOT';
1110int
a798dbf2 1111main(int argc, char **argv, char **env)
a798dbf2 1112{
1113 int exitstatus;
1114 int i;
1115 char **fakeargv;
1116
5712119f 1117 PERL_SYS_INIT3(&argc,&argv,&env);
a798dbf2 1118
81009501 1119 if (!PL_do_undump) {
a798dbf2 1120 my_perl = perl_alloc();
1121 if (!my_perl)
1122 exit(1);
1123 perl_construct( my_perl );
5712119f 1124 PL_perl_destruct_level = 0;
a798dbf2 1125 }
1126
1127#ifdef CSH
81009501 1128 if (!PL_cshlen)
1129 PL_cshlen = strlen(PL_cshname);
a798dbf2 1130#endif
1131
1132#ifdef ALLOW_PERL_OPTIONS
1133#define EXTRA_OPTIONS 2
1134#else
1135#define EXTRA_OPTIONS 3
1136#endif /* ALLOW_PERL_OPTIONS */
1137 New(666, fakeargv, argc + EXTRA_OPTIONS + 1, char *);
1138 fakeargv[0] = argv[0];
1139 fakeargv[1] = "-e";
1140 fakeargv[2] = "";
1141#ifndef ALLOW_PERL_OPTIONS
1142 fakeargv[3] = "--";
1143#endif /* ALLOW_PERL_OPTIONS */
1144 for (i = 1; i < argc; i++)
1145 fakeargv[i + EXTRA_OPTIONS] = argv[i];
1146 fakeargv[argc + EXTRA_OPTIONS] = 0;
1147
1148 exitstatus = perl_parse(my_perl, xs_init, argc + EXTRA_OPTIONS,
1149 fakeargv, NULL);
1150 if (exitstatus)
1151 exit( exitstatus );
1152
1153 sv_setpv(GvSV(gv_fetchpv("0", TRUE, SVt_PV)), argv[0]);
81009501 1154 PL_main_cv = PL_compcv;
1155 PL_compcv = 0;
a798dbf2 1156
1157 exitstatus = perl_init();
1158 if (exitstatus)
1159 exit( exitstatus );
5712119f 1160 dl_init(aTHX);
a798dbf2 1161
1162 exitstatus = perl_run( my_perl );
1163
1164 perl_destruct( my_perl );
1165 perl_free( my_perl );
1166
5712119f 1167 PERL_SYS_TERM();
1168
a798dbf2 1169 exit( exitstatus );
1170}
1171
511dd457 1172/* yanked from perl.c */
a798dbf2 1173static void
5712119f 1174xs_init(pTHX)
a798dbf2 1175{
511dd457 1176 char *file = __FILE__;
af765ed9 1177 dTARG;
39644a26 1178 dSP;
a798dbf2 1179EOT
af765ed9 1180 print "\n#ifdef USE_DYNAMIC_LOADING";
1181 print qq/\n\tnewXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);/;
1182 print "\n#endif\n" ;
a0e9c8c7 1183 # delete $xsub{'DynaLoader'};
af765ed9 1184 delete $xsub{'UNIVERSAL'};
be6f3502 1185 print("/* bootstrapping code*/\n\tSAVETMPS;\n");
af765ed9 1186 print("\ttarg=sv_newmortal();\n");
a0e9c8c7 1187 print "#ifdef DYNALOADER_BOOTSTRAP\n";
1188 print "\tPUSHMARK(sp);\n";
1189 print qq/\tXPUSHp("DynaLoader",strlen("DynaLoader"));\n/;
1190 print qq/\tPUTBACK;\n/;
5712119f 1191 print "\tboot_DynaLoader(aTHX_ NULL);\n";
a0e9c8c7 1192 print qq/\tSPAGAIN;\n/;
1193 print "#endif\n";
1194 foreach my $stashname (keys %xsub){
be6f3502 1195 if ($xsub{$stashname} ne 'Dynamic') {
1196 my $stashxsub=$stashname;
1197 $stashxsub =~ s/::/__/g;
1198 print "\tPUSHMARK(sp);\n";
a0e9c8c7 1199 print qq/\tXPUSHp("$stashname",strlen("$stashname"));\n/;
1200 print qq/\tPUTBACK;\n/;
5712119f 1201 print "\tboot_$stashxsub(aTHX_ NULL);\n";
a0e9c8c7 1202 print qq/\tSPAGAIN;\n/;
be6f3502 1203 }
1204 }
1205 print("\tFREETMPS;\n/* end bootstrapping code */\n");
a0e9c8c7 1206 print "}\n";
be6f3502 1207
1208print <<'EOT';
1209static void
5712119f 1210dl_init(pTHX)
be6f3502 1211{
1212 char *file = __FILE__;
1213 dTARG;
39644a26 1214 dSP;
be6f3502 1215EOT
1216 print("/* Dynamicboot strapping code*/\n\tSAVETMPS;\n");
1217 print("\ttarg=sv_newmortal();\n");
1218 foreach my $stashname (@DynaLoader::dl_modules) {
1219 warn "Loaded $stashname\n";
1220 if (exists($xsub{$stashname}) && $xsub{$stashname} eq 'Dynamic') {
1221 my $stashxsub=$stashname;
1222 $stashxsub =~ s/::/__/g;
1223 print "\tPUSHMARK(sp);\n";
a0e9c8c7 1224 print qq/\tXPUSHp("$stashname",/,length($stashname),qq/);\n/;
be6f3502 1225 print qq/\tPUTBACK;\n/;
af765ed9 1226 print "#ifdef DYNALOADER_BOOTSTRAP\n";
1227 warn "bootstrapping $stashname added to xs_init\n";
be6f3502 1228 print qq/\tperl_call_method("bootstrap",G_DISCARD);\n/;
af765ed9 1229 print "\n#else\n";
5712119f 1230 print "\tboot_$stashxsub(aTHX_ NULL);\n";
be6f3502 1231 print "#endif\n";
1232 print qq/\tSPAGAIN;\n/;
1233 }
af765ed9 1234 }
be6f3502 1235 print("\tFREETMPS;\n/* end Dynamic bootstrapping code */\n");
a0e9c8c7 1236 print "}\n";
af765ed9 1237}
a798dbf2 1238sub dump_symtable {
1239 # For debugging
1240 my ($sym, $val);
1241 warn "----Symbol table:\n";
1242 while (($sym, $val) = each %symtable) {
1243 warn "$sym => $val\n";
1244 }
1245 warn "---End of symbol table\n";
1246}
1247
1248sub save_object {
1249 my $sv;
1250 foreach $sv (@_) {
1251 svref_2object($sv)->save;
1252 }
338a6d08 1253}
1254
1255sub Dummy_BootStrap { }
a798dbf2 1256
66a2622e 1257sub B::GV::savecv
1258{
1259 my $gv = shift;
1260 my $package=$gv->STASH->NAME;
1261 my $name = $gv->NAME;
1262 my $cv = $gv->CV;
7cf11ee8 1263 my $sv = $gv->SV;
1264 my $av = $gv->AV;
1265 my $hv = $gv->HV;
7cf11ee8 1266
66a2622e 1267 # We may be looking at this package just because it is a branch in the
1268 # symbol table which is on the path to a package which we need to save
7cf11ee8 1269 # e.g. this is 'Getopt' and we need to save 'Getopt::Long'
66a2622e 1270 #
7cf11ee8 1271 return unless ($unused_sub_packages{$package});
be6f3502 1272 return unless ($$cv || $$av || $$sv || $$hv);
1273 $gv->save;
66a2622e 1274}
5ed82aed 1275
66a2622e 1276sub mark_package
1277{
1278 my $package = shift;
1279 unless ($unused_sub_packages{$package})
1280 {
1281 no strict 'refs';
1282 $unused_sub_packages{$package} = 1;
6771324e 1283 if (defined @{$package.'::ISA'})
66a2622e 1284 {
1285 foreach my $isa (@{$package.'::ISA'})
1286 {
1287 if ($isa eq 'DynaLoader')
1288 {
1289 unless (defined(&{$package.'::bootstrap'}))
1290 {
1291 warn "Forcing bootstrap of $package\n";
1292 eval { $package->bootstrap };
1293 }
1294 }
a0e9c8c7 1295# else
66a2622e 1296 {
1297 unless ($unused_sub_packages{$isa})
1298 {
1299 warn "$isa saved (it is in $package\'s \@ISA)\n";
1300 mark_package($isa);
1301 }
1302 }
1303 }
1304 }
1305 }
1306 return 1;
1307}
1308
1309sub should_save
1310{
1311 no strict qw(vars refs);
1312 my $package = shift;
1313 $package =~ s/::$//;
1314 return $unused_sub_packages{$package} = 0 if ($package =~ /::::/); # skip ::::ISA::CACHE etc.
cf86991c 1315 # warn "Considering $package\n";#debug
66a2622e 1316 foreach my $u (grep($unused_sub_packages{$_},keys %unused_sub_packages))
1317 {
1318 # If this package is a prefix to something we are saving, traverse it
1319 # but do not mark it for saving if it is not already
1320 # e.g. to get to Getopt::Long we need to traverse Getopt but need
1321 # not save Getopt
1322 return 1 if ($u =~ /^$package\:\:/);
1323 }
1324 if (exists $unused_sub_packages{$package})
1325 {
cf86991c 1326 # warn "Cached $package is ".$unused_sub_packages{$package}."\n";
cfa4c8ee 1327 delete_unsaved_hashINC($package) unless $unused_sub_packages{$package} ;
1328 return $unused_sub_packages{$package};
66a2622e 1329 }
1330 # Omit the packages which we use (and which cause grief
1331 # because of fancy "goto &$AUTOLOAD" stuff).
1332 # XXX Surely there must be a nicer way to do this.
1333 if ($package eq "FileHandle" || $package eq "Config" ||
cf86991c 1334 $package eq "SelectSaver" || $package =~/^(B|IO)::/)
66a2622e 1335 {
cfa4c8ee 1336 delete_unsaved_hashINC($package);
66a2622e 1337 return $unused_sub_packages{$package} = 0;
1338 }
1339 # Now see if current package looks like an OO class this is probably too strong.
1340 foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE))
1341 {
b368a11e 1342 if (UNIVERSAL::can($package, $m))
66a2622e 1343 {
1344 warn "$package has method $m: saving package\n";#debug
1345 return mark_package($package);
1346 }
1347 }
cfa4c8ee 1348 delete_unsaved_hashINC($package);
66a2622e 1349 return $unused_sub_packages{$package} = 0;
a798dbf2 1350}
cfa4c8ee 1351sub delete_unsaved_hashINC{
1352 my $packname=shift;
1353 $packname =~ s/\:\:/\//g;
1354 $packname .= '.pm';
59c10aa2 1355# warn "deleting $packname" if $INC{$packname} ;# debug
cfa4c8ee 1356 delete $INC{$packname};
1357}
66a2622e 1358sub walkpackages
1359{
1360 my ($symref, $recurse, $prefix) = @_;
1361 my $sym;
1362 my $ref;
1363 no strict 'vars';
1364 local(*glob);
1365 $prefix = '' unless defined $prefix;
1366 while (($sym, $ref) = each %$symref)
1367 {
1368 *glob = $ref;
1369 if ($sym =~ /::$/)
1370 {
1371 $sym = $prefix . $sym;
b4e94495 1372 if ($sym ne "main::" && $sym ne "<none>::" && &$recurse($sym))
66a2622e 1373 {
1374 walkpackages(\%glob, $recurse, $sym);
1375 }
1376 }
1377 }
1378}
338a6d08 1379
1380
66a2622e 1381sub save_unused_subs
1382{
1383 no strict qw(refs);
a9b6343a 1384 &descend_marked_unused;
66a2622e 1385 warn "Prescan\n";
1386 walkpackages(\%{"main::"}, sub { should_save($_[0]); return 1 });
1387 warn "Saving methods\n";
1388 walksymtable(\%{"main::"}, "savecv", \&should_save);
a798dbf2 1389}
1390
0cc1d052 1391sub save_context
1392{
1393 my $curpad_nam = (comppadlist->ARRAY)[0]->save;
1394 my $curpad_sym = (comppadlist->ARRAY)[1]->save;
1395 my $inc_hv = svref_2object(\%INC)->save;
1396 my $inc_av = svref_2object(\@INC)->save;
56eca212 1397 my $amagic_generate= amagic_generation;
0cc1d052 1398 $init->add( "PL_curpad = AvARRAY($curpad_sym);",
1399 "GvHV(PL_incgv) = $inc_hv;",
1400 "GvAV(PL_incgv) = $inc_av;",
1401 "av_store(CvPADLIST(PL_main_cv),0,SvREFCNT_inc($curpad_nam));",
56eca212 1402 "av_store(CvPADLIST(PL_main_cv),1,SvREFCNT_inc($curpad_sym));",
1403 "PL_amagic_generation= $amagic_generate;" );
0cc1d052 1404}
1405
a9b6343a 1406sub descend_marked_unused {
1407 foreach my $pack (keys %unused_sub_packages)
1408 {
1409 mark_package($pack);
1410 }
1411}
73544139 1412
a798dbf2 1413sub save_main {
66a2622e 1414 warn "Starting compile\n";
66a2622e 1415 warn "Walking tree\n";
73544139 1416 seek(STDOUT,0,0); #exclude print statements in BEGIN{} into output
a798dbf2 1417 walkoptree(main_root, "save");
1418 warn "done main optree, walking symtable for extras\n" if $debug_cv;
66a2622e 1419 save_unused_subs();
0cc1d052 1420 my $init_av = init_av->save;
81009501 1421 $init->add(sprintf("PL_main_root = s\\_%x;", ${main_root()}),
1422 sprintf("PL_main_start = s\\_%x;", ${main_start()}),
5ab5c7a4 1423 "PL_initav = (AV *) $init_av;");
0cc1d052 1424 save_context();
5ed82aed 1425 warn "Writing output\n";
a798dbf2 1426 output_boilerplate();
1427 print "\n";
1428 output_all("perl_init");
1429 print "\n";
1430 output_main();
1431}
1432
1433sub init_sections {
1434 my @sections = (init => \$init, decl => \$decl, sym => \$symsect,
1435 binop => \$binopsect, condop => \$condopsect,
7934575e 1436 cop => \$copsect, padop => \$padopsect,
a798dbf2 1437 listop => \$listopsect, logop => \$logopsect,
1438 loop => \$loopsect, op => \$opsect, pmop => \$pmopsect,
1439 pvop => \$pvopsect, svop => \$svopsect, unop => \$unopsect,
1440 sv => \$svsect, xpv => \$xpvsect, xpvav => \$xpvavsect,
1441 xpvhv => \$xpvhvsect, xpvcv => \$xpvcvsect,
1442 xpviv => \$xpvivsect, xpvnv => \$xpvnvsect,
1443 xpvmg => \$xpvmgsect, xpvlv => \$xpvlvsect,
1444 xrv => \$xrvsect, xpvbm => \$xpvbmsect,
af765ed9 1445 xpvio => \$xpviosect);
a798dbf2 1446 my ($name, $sectref);
1447 while (($name, $sectref) = splice(@sections, 0, 2)) {
66a2622e 1448 $$sectref = new B::C::Section $name, \%symtable, 0;
a798dbf2 1449 }
0cc1d052 1450}
1451
1452sub mark_unused
1453{
1454 my ($arg,$val) = @_;
1455 $unused_sub_packages{$arg} = $val;
a798dbf2 1456}
1457
1458sub compile {
1459 my @options = @_;
1460 my ($option, $opt, $arg);
1461 OPTION:
1462 while ($option = shift @options) {
1463 if ($option =~ /^-(.)(.*)/) {
1464 $opt = $1;
1465 $arg = $2;
1466 } else {
1467 unshift @options, $option;
1468 last OPTION;
1469 }
1470 if ($opt eq "-" && $arg eq "-") {
1471 shift @options;
1472 last OPTION;
1473 }
1474 if ($opt eq "w") {
1475 $warn_undefined_syms = 1;
1476 } elsif ($opt eq "D") {
1477 $arg ||= shift @options;
1478 foreach $arg (split(//, $arg)) {
1479 if ($arg eq "o") {
1480 B->debug(1);
1481 } elsif ($arg eq "c") {
1482 $debug_cops = 1;
1483 } elsif ($arg eq "A") {
1484 $debug_av = 1;
1485 } elsif ($arg eq "C") {
1486 $debug_cv = 1;
1487 } elsif ($arg eq "M") {
1488 $debug_mg = 1;
1489 } else {
1490 warn "ignoring unknown debug option: $arg\n";
1491 }
1492 }
1493 } elsif ($opt eq "o") {
1494 $arg ||= shift @options;
1495 open(STDOUT, ">$arg") or return "$arg: $!\n";
1496 } elsif ($opt eq "v") {
1497 $verbose = 1;
1498 } elsif ($opt eq "u") {
1499 $arg ||= shift @options;
0cc1d052 1500 mark_unused($arg,undef);
a798dbf2 1501 } elsif ($opt eq "f") {
1502 $arg ||= shift @options;
1503 if ($arg eq "cog") {
1504 $pv_copy_on_grow = 1;
1505 } elsif ($arg eq "no-cog") {
1506 $pv_copy_on_grow = 0;
1507 }
1508 } elsif ($opt eq "O") {
1509 $arg = 1 if $arg eq "";
1510 $pv_copy_on_grow = 0;
1511 if ($arg >= 1) {
1512 # Optimisations for -O1
1513 $pv_copy_on_grow = 1;
1514 }
dc333d64 1515 } elsif ($opt eq "l") {
1516 $max_string_len = $arg;
a798dbf2 1517 }
1518 }
1519 init_sections();
1520 if (@options) {
1521 return sub {
1522 my $objname;
1523 foreach $objname (@options) {
1524 eval "save_object(\\$objname)";
1525 }
1526 output_all();
1527 }
1528 } else {
1529 return sub { save_main() };
1530 }
1531}
1532
15331;
7f20e9dd 1534
1535__END__
1536
1537=head1 NAME
1538
1539B::C - Perl compiler's C backend
1540
1541=head1 SYNOPSIS
1542
1543 perl -MO=C[,OPTIONS] foo.pl
1544
1545=head1 DESCRIPTION
1546
1a52ab62 1547This compiler backend takes Perl source and generates C source code
1548corresponding to the internal structures that perl uses to run
1549your program. When the generated C source is compiled and run, it
1550cuts out the time which perl would have taken to load and parse
1551your program into its internal semi-compiled form. That means that
1552compiling with this backend will not help improve the runtime
1553execution speed of your program but may improve the start-up time.
1554Depending on the environment in which your program runs this may be
1555either a help or a hindrance.
1556
1557=head1 OPTIONS
1558
1559If there are any non-option arguments, they are taken to be
1560names of objects to be saved (probably doesn't work properly yet).
1561Without extra arguments, it saves the main program.
1562
1563=over 4
1564
1565=item B<-ofilename>
1566
1567Output to filename instead of STDOUT
1568
1569=item B<-v>
1570
1571Verbose compilation (currently gives a few compilation statistics).
1572
1573=item B<-->
1574
1575Force end of options
1576
1577=item B<-uPackname>
1578
1579Force apparently unused subs from package Packname to be compiled.
1580This allows programs to use eval "foo()" even when sub foo is never
1581seen to be used at compile time. The down side is that any subs which
1582really are never used also have code generated. This option is
1583necessary, for example, if you have a signal handler foo which you
1584initialise with C<$SIG{BAR} = "foo">. A better fix, though, is just
1585to change it to C<$SIG{BAR} = \&foo>. You can have multiple B<-u>
1586options. The compiler tries to figure out which packages may possibly
1587have subs in which need compiling but the current version doesn't do
1588it very well. In particular, it is confused by nested packages (i.e.
1589of the form C<A::B>) where package C<A> does not contain any subs.
1590
1591=item B<-D>
1592
1593Debug options (concatenated or separate flags like C<perl -D>).
1594
1595=item B<-Do>
1596
1597OPs, prints each OP as it's processed
1598
1599=item B<-Dc>
1600
1601COPs, prints COPs as processed (incl. file & line num)
1602
1603=item B<-DA>
1604
1605prints AV information on saving
1606
1607=item B<-DC>
1608
1609prints CV information on saving
1610
1611=item B<-DM>
1612
1613prints MAGIC information on saving
1614
1615=item B<-f>
1616
1617Force optimisations on or off one at a time.
1618
1619=item B<-fcog>
1620
1621Copy-on-grow: PVs declared and initialised statically.
1622
1623=item B<-fno-cog>
1624
1625No copy-on-grow.
1626
1627=item B<-On>
1628
1629Optimisation level (n = 0, 1, 2, ...). B<-O> means B<-O1>. Currently,
1630B<-O1> and higher set B<-fcog>.
1631
dc333d64 1632=item B<-llimit>
1633
1634Some C compilers impose an arbitrary limit on the length of string
1635constants (e.g. 2048 characters for Microsoft Visual C++). The
1636B<-llimit> options tells the C backend not to generate string literals
1637exceeding that limit.
1638
a45bd81d 1639=back
1640
1a52ab62 1641=head1 EXAMPLES
1642
1643 perl -MO=C,-ofoo.c foo.pl
1644 perl cc_harness -o foo foo.c
1645
1646Note that C<cc_harness> lives in the C<B> subdirectory of your perl
1647library directory. The utility called C<perlcc> may also be used to
1648help make use of this compiler.
1649
dc333d64 1650 perl -MO=C,-v,-DcA,-l2048 bar.pl > /dev/null
1a52ab62 1651
1652=head1 BUGS
1653
1654Plenty. Current status: experimental.
7f20e9dd 1655
1656=head1 AUTHOR
1657
1658Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>
1659
1660=cut