3 # Copyright (c) 1996, 1997, 1998 Malcolm Beattie
5 # You may distribute under the terms of either the GNU General Public
6 # License or the Artistic License, as specified in the README file.
15 my $o = $class->SUPER::new(@_);
23 push(@{$section->[-1]},@_);
29 return scalar(@{$section->[-1]})-1;
34 my ($section, $fh, $format) = @_;
35 my $sym = $section->symtable || {};
36 my $default = $section->default;
37 foreach (@{$section->[-1]})
39 s{(s\\_[0-9a-f]+)}{ exists($sym->{$1}) ? $sym->{$1} : $default; }ge;
40 printf $fh $format, $_;
47 @EXPORT_OK = qw(output_all output_boilerplate output_main mark_unused
48 init_sections set_callback save_unused_subs objsym save_context);
50 use B qw(minus_c sv_undef walkoptree walksymtable main_root main_start peekop
51 class cstring cchar svref_2object compile_stats comppadlist hash
52 threadsv_names main_cv init_av opnumber);
53 use B::Asmdata qw(@specialsv_name);
63 my $anonsub_index = 0;
64 my $initsub_index = 0;
67 my $warn_undefined_syms;
69 my %unused_sub_packages;
71 my $pv_copy_on_grow = 0;
72 my ($debug_cops, $debug_av, $debug_cv, $debug_mg);
76 @threadsv_names = threadsv_names();
80 my ($init, $decl, $symsect, $binopsect, $condopsect, $copsect,
81 $gvopsect, $listopsect, $logopsect, $loopsect, $opsect, $pmopsect,
82 $pvopsect, $svopsect, $unopsect, $svsect, $xpvsect, $xpvavsect,
83 $xpvhvsect, $xpvcvsect, $xpvivsect, $xpvnvsect, $xpvmgsect, $xpvlvsect,
84 $xrvsect, $xpvbmsect, $xpviosect, $bootstrap);
86 sub walk_and_save_optree;
87 my $saveoptree_callback = \&walk_and_save_optree;
88 sub set_callback { $saveoptree_callback = shift }
89 sub saveoptree { &$saveoptree_callback(@_) }
91 sub walk_and_save_optree {
92 my ($name, $root, $start) = @_;
93 walkoptree($root, "save");
94 return objsym($start);
97 # Current workaround/fix for op_free() trying to free statically
98 # defined OPs is to set op_seq = -1 and check for that in op_free().
99 # Instead of hardwiring -1 in place of $op->seq, we use $op_seq
100 # so that it can be changed back easily if necessary. In fact, to
101 # stop compilers from moaning about a U16 being initialised with an
102 # uncast -1 (the printf format is %d so we can't tweak it), we have
103 # to "know" that op_seq is a U16 and use 65535. Ugh.
106 sub AVf_REAL () { 1 }
107 sub define HEf_SVKEY () { -2 }
109 # Look this up here so we can do just a number compare
110 # rather than looking up the name of every BASEOP in B::OP
111 my $OP_THREADSV = opnumber('threadsv');
114 my ($obj, $value) = @_;
115 my $sym = sprintf("s\\_%x", $$obj);
116 $symtable{$sym} = $value;
121 return $symtable{sprintf("s\\_%x", $$obj)};
128 return 0 if $sym eq "sym_0"; # special case
129 $value = $symtable{$sym};
130 if (defined($value)) {
133 warn "warning: undefined symbol $sym\n" if $warn_undefined_syms;
140 $pv = '' unless defined $pv; # Is this sane ?
143 if ($pv_copy_on_grow) {
144 my $cstring = cstring($pv);
145 if ($cstring ne "0") { # sic
146 $pvsym = sprintf("pv%d", $pv_index++);
147 $decl->add(sprintf("static char %s[] = %s;", $pvsym, $cstring));
150 $pvmax = length($pv) + 1;
152 return ($pvsym, $pvmax);
156 my ($op, $level) = @_;
157 my $type = $op->type;
158 $nullop_count++ unless $type;
159 if ($type == $OP_THREADSV) {
160 # saves looking up ppaddr but it's a bit naughty to hard code this
161 $init->add(sprintf("(void)find_threadsv(%s);",
162 cstring($threadsv_names[$op->targ])));
164 $opsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x",
165 ${$op->next}, ${$op->sibling}, $op->ppaddr, $op->targ,
166 $type, $op_seq, $op->flags, $op->private));
167 savesym($op, sprintf("&op_list[%d]", $opsect->index));
171 my ($class, %objdata) = @_;
172 bless \%objdata, $class;
175 sub B::FAKEOP::save {
176 my ($op, $level) = @_;
177 $opsect->add(sprintf("%s, %s, %s, %u, %u, %u, 0x%x, 0x%x",
178 $op->next, $op->sibling, $op->ppaddr, $op->targ,
179 $op->type, $op_seq, $op->flags, $op->private));
180 return sprintf("&op_list[%d]", $opsect->index);
183 sub B::FAKEOP::next { $_[0]->{"next"} || 0 }
184 sub B::FAKEOP::type { $_[0]->{type} || 0}
185 sub B::FAKEOP::sibling { $_[0]->{sibling} || 0 }
186 sub B::FAKEOP::ppaddr { $_[0]->{ppaddr} || 0 }
187 sub B::FAKEOP::targ { $_[0]->{targ} || 0 }
188 sub B::FAKEOP::flags { $_[0]->{flags} || 0 }
189 sub B::FAKEOP::private { $_[0]->{private} || 0 }
192 my ($op, $level) = @_;
193 $unopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x",
194 ${$op->next}, ${$op->sibling}, $op->ppaddr,
195 $op->targ, $op->type, $op_seq, $op->flags,
196 $op->private, ${$op->first}));
197 savesym($op, sprintf("(OP*)&unop_list[%d]", $unopsect->index));
201 my ($op, $level) = @_;
202 $binopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x",
203 ${$op->next}, ${$op->sibling}, $op->ppaddr,
204 $op->targ, $op->type, $op_seq, $op->flags,
205 $op->private, ${$op->first}, ${$op->last}));
206 savesym($op, sprintf("(OP*)&binop_list[%d]", $binopsect->index));
209 sub B::LISTOP::save {
210 my ($op, $level) = @_;
211 $listopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x, %u",
212 ${$op->next}, ${$op->sibling}, $op->ppaddr,
213 $op->targ, $op->type, $op_seq, $op->flags,
214 $op->private, ${$op->first}, ${$op->last},
216 savesym($op, sprintf("(OP*)&listop_list[%d]", $listopsect->index));
220 my ($op, $level) = @_;
221 $logopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x",
222 ${$op->next}, ${$op->sibling}, $op->ppaddr,
223 $op->targ, $op->type, $op_seq, $op->flags,
224 $op->private, ${$op->first}, ${$op->other}));
225 savesym($op, sprintf("(OP*)&logop_list[%d]", $logopsect->index));
228 sub B::CONDOP::save {
229 my ($op, $level) = @_;
230 $condopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x, s\\_%x",
231 ${$op->next}, ${$op->sibling}, $op->ppaddr,
232 $op->targ, $op->type, $op_seq, $op->flags,
233 $op->private, ${$op->first}, ${$op->true},
235 savesym($op, sprintf("(OP*)&condop_list[%d]", $condopsect->index));
239 my ($op, $level) = @_;
240 #warn sprintf("LOOP: redoop %s, nextop %s, lastop %s\n",
241 # peekop($op->redoop), peekop($op->nextop),
242 # peekop($op->lastop)); # debug
243 $loopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x, %u, s\\_%x, s\\_%x, s\\_%x",
244 ${$op->next}, ${$op->sibling}, $op->ppaddr,
245 $op->targ, $op->type, $op_seq, $op->flags,
246 $op->private, ${$op->first}, ${$op->last},
247 $op->children, ${$op->redoop}, ${$op->nextop},
249 savesym($op, sprintf("(OP*)&loop_list[%d]", $loopsect->index));
253 my ($op, $level) = @_;
254 $pvopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, %s",
255 ${$op->next}, ${$op->sibling}, $op->ppaddr,
256 $op->targ, $op->type, $op_seq, $op->flags,
257 $op->private, cstring($op->pv)));
258 savesym($op, sprintf("(OP*)&pvop_list[%d]", $pvopsect->index));
262 my ($op, $level) = @_;
263 my $svsym = $op->sv->save;
264 $svopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, %s",
265 ${$op->next}, ${$op->sibling}, $op->ppaddr,
266 $op->targ, $op->type, $op_seq, $op->flags,
267 $op->private, "(SV*)$svsym"));
268 savesym($op, sprintf("(OP*)&svop_list[%d]", $svopsect->index));
272 my ($op, $level) = @_;
273 my $gvsym = $op->gv->save;
274 $gvopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, Nullgv",
275 ${$op->next}, ${$op->sibling}, $op->ppaddr,
276 $op->targ, $op->type, $op_seq, $op->flags,
278 $init->add(sprintf("gvop_list[%d].op_gv = %s;", $gvopsect->index, $gvsym));
279 savesym($op, sprintf("(OP*)&gvop_list[%d]", $gvopsect->index));
283 my ($op, $level) = @_;
284 my $gvsym = $op->filegv->save;
285 my $stashsym = $op->stash->save;
286 warn sprintf("COP: line %d file %s\n", $op->line, $op->filegv->SV->PV)
288 $copsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, %s, Nullhv, Nullgv, %u, %d, %u",
289 ${$op->next}, ${$op->sibling}, $op->ppaddr,
290 $op->targ, $op->type, $op_seq, $op->flags,
291 $op->private, cstring($op->label), $op->cop_seq,
292 $op->arybase, $op->line));
293 my $copix = $copsect->index;
294 $init->add(sprintf("cop_list[%d].cop_filegv = %s;", $copix, $gvsym),
295 sprintf("cop_list[%d].cop_stash = %s;", $copix, $stashsym));
296 savesym($op, "(OP*)&cop_list[$copix]");
300 my ($op, $level) = @_;
301 my $replroot = $op->pmreplroot;
302 my $replstart = $op->pmreplstart;
303 my $replrootfield = sprintf("s\\_%x", $$replroot);
304 my $replstartfield = sprintf("s\\_%x", $$replstart);
306 my $ppaddr = $op->ppaddr;
308 # OP_PUSHRE (a mutated version of OP_MATCH for the regexp
309 # argument to a split) stores a GV in op_pmreplroot instead
310 # of a substitution syntax tree. We don't want to walk that...
311 if ($ppaddr eq "pp_pushre") {
312 $gvsym = $replroot->save;
313 # warn "PMOP::save saving a pp_pushre with GV $gvsym\n"; # debug
316 $replstartfield = saveoptree("*ignore*", $replroot, $replstart);
319 # pmnext handling is broken in perl itself, I think. Bad op_pmnext
320 # fields aren't noticed in perl's runtime (unless you try reset) but we
321 # segfault when trying to dereference it to find op->op_pmnext->op_type
322 $pmopsect->add(sprintf("s\\_%x, s\\_%x, %s, %u, %u, %u, 0x%x, 0x%x, s\\_%x, s\\_%x, %u, %s, %s, 0, 0, 0x%x, 0x%x",
323 ${$op->next}, ${$op->sibling}, $ppaddr, $op->targ,
324 $op->type, $op_seq, $op->flags, $op->private,
325 ${$op->first}, ${$op->last}, $op->children,
326 $replrootfield, $replstartfield,
327 $op->pmflags, $op->pmpermflags,));
328 my $pm = sprintf("pmop_list[%d]", $pmopsect->index);
329 my $re = $op->precomp;
331 my $resym = sprintf("re%d", $re_index++);
332 $decl->add(sprintf("static char *$resym = %s;", cstring($re)));
333 $init->add(sprintf("$pm.op_pmregexp = pregcomp($resym, $resym + %u, &$pm);",
337 $init->add("$pm.op_pmreplroot = (OP*)$gvsym;");
339 savesym($op, sprintf("(OP*)&pmop_list[%d]", $pmopsect->index));
342 sub B::SPECIAL::save {
344 # special case: $$sv is not the address but an index into specialsv_list
345 # warn "SPECIAL::save specialsv $$sv\n"; # debug
346 my $sym = $specialsv_name[$$sv];
347 if (!defined($sym)) {
348 confess "unknown specialsv index $$sv passed to B::SPECIAL::save";
353 sub B::OBJECT::save {}
357 my $sym = objsym($sv);
358 return $sym if defined $sym;
359 # warn "Saving SVt_NULL SV\n"; # debug
362 # warn "NULL::save for sv = 0 called from @{[(caller(1))[3]]}\n";
364 $svsect->add(sprintf("0, %u, 0x%x", $sv->REFCNT + 1, $sv->FLAGS));
365 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
370 my $sym = objsym($sv);
371 return $sym if defined $sym;
372 $xpvivsect->add(sprintf("0, 0, 0, %d", $sv->IVX));
373 $svsect->add(sprintf("&xpviv_list[%d], %lu, 0x%x",
374 $xpvivsect->index, $sv->REFCNT + 1, $sv->FLAGS));
375 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
380 my $sym = objsym($sv);
381 return $sym if defined $sym;
382 $xpvnvsect->add(sprintf("0, 0, 0, %d, %s", $sv->IVX, $sv->NVX));
383 $svsect->add(sprintf("&xpvnv_list[%d], %lu, 0x%x",
384 $xpvnvsect->index, $sv->REFCNT + 1, $sv->FLAGS));
385 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
390 my $sym = objsym($sv);
391 return $sym if defined $sym;
393 my $len = length($pv);
394 my ($pvsym, $pvmax) = savepv($pv);
395 my ($lvtarg, $lvtarg_sym);
396 $xpvlvsect->add(sprintf("%s, %u, %u, %d, %g, 0, 0, %u, %u, 0, %s",
397 $pvsym, $len, $pvmax, $sv->IVX, $sv->NVX,
398 $sv->TARGOFF, $sv->TARGLEN, cchar($sv->TYPE)));
399 $svsect->add(sprintf("&xpvlv_list[%d], %lu, 0x%x",
400 $xpvlvsect->index, $sv->REFCNT + 1, $sv->FLAGS));
401 if (!$pv_copy_on_grow) {
402 $init->add(sprintf("xpvlv_list[%d].xpv_pv = savepvn(%s, %u);",
403 $xpvlvsect->index, cstring($pv), $len));
406 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
411 my $sym = objsym($sv);
412 return $sym if defined $sym;
414 my $len = length($pv);
415 my ($pvsym, $pvmax) = savepv($pv);
416 $xpvivsect->add(sprintf("%s, %u, %u, %d", $pvsym, $len, $pvmax, $sv->IVX));
417 $svsect->add(sprintf("&xpviv_list[%d], %u, 0x%x",
418 $xpvivsect->index, $sv->REFCNT + 1, $sv->FLAGS));
419 if (!$pv_copy_on_grow) {
420 $init->add(sprintf("xpviv_list[%d].xpv_pv = savepvn(%s, %u);",
421 $xpvivsect->index, cstring($pv), $len));
423 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
428 my $sym = objsym($sv);
429 return $sym if defined $sym;
431 $pv = '' unless defined $pv;
432 my $len = length($pv);
433 my ($pvsym, $pvmax) = savepv($pv);
434 $xpvnvsect->add(sprintf("%s, %u, %u, %d, %s",
435 $pvsym, $len, $pvmax, $sv->IVX, $sv->NVX));
436 $svsect->add(sprintf("&xpvnv_list[%d], %lu, 0x%x",
437 $xpvnvsect->index, $sv->REFCNT + 1, $sv->FLAGS));
438 if (!$pv_copy_on_grow) {
439 $init->add(sprintf("xpvnv_list[%d].xpv_pv = savepvn(%s,%u);",
440 $xpvnvsect->index, cstring($pv), $len));
442 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
447 my $sym = objsym($sv);
448 return $sym if defined $sym;
449 my $pv = $sv->PV . "\0" . $sv->TABLE;
450 my $len = length($pv);
451 $xpvbmsect->add(sprintf("0, %u, %u, %d, %s, 0, 0, %d, %u, 0x%x",
452 $len, $len + 258, $sv->IVX, $sv->NVX,
453 $sv->USEFUL, $sv->PREVIOUS, $sv->RARE));
454 $svsect->add(sprintf("&xpvbm_list[%d], %lu, 0x%x",
455 $xpvbmsect->index, $sv->REFCNT + 1, $sv->FLAGS));
457 $init->add(sprintf("xpvbm_list[%d].xpv_pv = savepvn(%s, %u);",
458 $xpvbmsect->index, cstring($pv), $len),
459 sprintf("xpvbm_list[%d].xpv_cur = %u;",
460 $xpvbmsect->index, $len - 257));
461 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
466 my $sym = objsym($sv);
467 return $sym if defined $sym;
469 my $len = length($pv);
470 my ($pvsym, $pvmax) = savepv($pv);
471 $xpvsect->add(sprintf("%s, %u, %u", $pvsym, $len, $pvmax));
472 $svsect->add(sprintf("&xpv_list[%d], %lu, 0x%x",
473 $xpvsect->index, $sv->REFCNT + 1, $sv->FLAGS));
474 if (!$pv_copy_on_grow) {
475 $init->add(sprintf("xpv_list[%d].xpv_pv = savepvn(%s, %u);",
476 $xpvsect->index, cstring($pv), $len));
478 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
483 my $sym = objsym($sv);
484 return $sym if defined $sym;
486 my $len = length($pv);
487 my ($pvsym, $pvmax) = savepv($pv);
488 $xpvmgsect->add(sprintf("%s, %u, %u, %d, %s, 0, 0",
489 $pvsym, $len, $pvmax, $sv->IVX, $sv->NVX));
490 $svsect->add(sprintf("&xpvmg_list[%d], %lu, 0x%x",
491 $xpvmgsect->index, $sv->REFCNT + 1, $sv->FLAGS));
492 if (!$pv_copy_on_grow) {
493 $init->add(sprintf("xpvmg_list[%d].xpv_pv = savepvn(%s, %u);",
494 $xpvmgsect->index, cstring($pv), $len));
496 $sym = savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
501 sub B::PVMG::save_magic {
503 #warn sprintf("saving magic for %s (0x%x)\n", class($sv), $$sv); # debug
504 my $stash = $sv->SvSTASH;
506 warn sprintf("xmg_stash = %s (0x%x)\n", $stash->NAME, $$stash)
508 # XXX Hope stash is already going to be saved.
509 $init->add(sprintf("SvSTASH(s\\_%x) = s\\_%x;", $$sv, $$stash));
511 my @mgchain = $sv->MAGIC;
512 my ($mg, $type, $obj, $ptr,$len,$ptrsv);
513 foreach $mg (@mgchain) {
519 warn sprintf("magic %s (0x%x), obj %s (0x%x), type %s, ptr %s\n",
520 class($sv), $$sv, class($obj), $$obj,
521 cchar($type), cstring($ptr));
523 if ($len == HEf_SVKEY){
524 #The pointer is an SV*
525 $ptrsv=svref_2object($ptr)->save;
526 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
527 $$sv, $$obj, cchar($type),$ptrsv,$len));
529 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
530 $$sv, $$obj, cchar($type),cstring($ptr),$len));
537 my $sym = objsym($sv);
538 return $sym if defined $sym;
539 my $rv = $sv->RV->save;
540 $rv =~ s/^\([AGHS]V\s*\*\)\s*(\&sv_list.*)$/$1/;
542 $svsect->add(sprintf("&xrv_list[%d], %lu, 0x%x",
543 $xrvsect->index, $sv->REFCNT + 1, $sv->FLAGS));
544 return savesym($sv, sprintf("&sv_list[%d]", $svsect->index));
548 my ($cvstashname, $cvname) = @_;
549 warn sprintf("No definition for sub %s::%s\n", $cvstashname, $cvname);
550 # Handle AutoLoader classes explicitly. Any more general AUTOLOAD
551 # use should be handled by the class itself.
553 my $isa = \@{"$cvstashname\::ISA"};
554 if (grep($_ eq "AutoLoader", @$isa)) {
555 warn "Forcing immediate load of sub derived from AutoLoader\n";
556 # Tweaked version of AutoLoader::AUTOLOAD
557 my $dir = $cvstashname;
559 eval { require "auto/$dir/$cvname.al" };
561 warn qq(failed require "auto/$dir/$cvname.al": $@\n);
571 my $sym = objsym($cv);
573 # warn sprintf("CV 0x%x already saved as $sym\n", $$cv); # debug
576 # Reserve a place in svsect and xpvcvsect and record indices
577 my $sv_ix = $svsect->index + 1;
578 $svsect->add("svix$sv_ix");
579 my $xpvcv_ix = $xpvcvsect->index + 1;
580 $xpvcvsect->add("xpvcvix$xpvcv_ix");
581 # Save symbol now so that GvCV() doesn't recurse back to us via CvGV()
582 $sym = savesym($cv, "&sv_list[$sv_ix]");
583 warn sprintf("saving CV 0x%x as $sym\n", $$cv) if $debug_cv;
585 my $cvstashname = $gv->STASH->NAME;
586 my $cvname = $gv->NAME;
587 my $root = $cv->ROOT;
588 my $cvxsub = $cv->XSUB;
589 if (!$$root && !$cvxsub) {
590 if (try_autoload($cvstashname, $cvname)) {
591 # Recalculate root and xsub
594 if ($$root || $cvxsub) {
595 warn "Successful forced autoload\n";
600 my $padlist = $cv->PADLIST;
603 my $xsubany = "Nullany";
605 warn sprintf("saving op tree for CV 0x%x, root = 0x%x\n",
606 $$cv, $$root) if $debug_cv;
609 my $stashname = $gv->STASH->NAME;
610 my $gvname = $gv->NAME;
611 if ($gvname ne "__ANON__") {
612 $ppname = (${$gv->FORM} == $$cv) ? "pp_form_" : "pp_sub_";
613 $ppname .= ($stashname eq "main") ?
614 $gvname : "$stashname\::$gvname";
615 $ppname =~ s/::/__/g;
616 if ($gvname eq "INIT"){
617 $ppname .= "_$initsub_index";
623 $ppname = "pp_anonsub_$anonsub_index";
626 $startfield = saveoptree($ppname, $root, $cv->START, $padlist->ARRAY);
627 warn sprintf("done saving op tree for CV 0x%x, name %s, root 0x%x\n",
628 $$cv, $ppname, $$root) if $debug_cv;
630 warn sprintf("saving PADLIST 0x%x for CV 0x%x\n",
631 $$padlist, $$cv) if $debug_cv;
633 warn sprintf("done saving PADLIST 0x%x for CV 0x%x\n",
634 $$padlist, $$cv) if $debug_cv;
638 $xsubany = sprintf("ANYINIT((void*)0x%x)", $cv->XSUBANY);
639 # Try to find out canonical name of XSUB function from EGV.
640 # XXX Doesn't work for XSUBs with PREFIX set (or anyone who
641 # calls newXS() manually with weird arguments).
643 my $stashname = $egv->STASH->NAME;
644 $stashname =~ s/::/__/g;
645 $xsub = sprintf("XS_%s_%s", $stashname, $egv->NAME);
646 $decl->add("void $xsub _((CV*));");
649 warn sprintf("No definition for sub %s::%s (unable to autoload)\n",
650 $cvstashname, $cvname); # debug
652 $pv = '' unless defined $pv; # Avoid use of undef warnings
653 $symsect->add(sprintf("xpvcvix%d\t%s, %u, 0, %d, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub, $xsubany, Nullgv, Nullgv, %d, s\\_%x, (CV*)s\\_%x, 0x%x",
654 $xpvcv_ix, cstring($pv), length($pv), $cv->IVX,
655 $cv->NVX, $startfield, ${$cv->ROOT}, $cv->DEPTH,
656 $$padlist, ${$cv->OUTSIDE}, $cv->CvFLAGS));
658 if (${$cv->OUTSIDE} == ${main_cv()}){
659 $init->add(sprintf("CvOUTSIDE(s\\_%x)=PL_main_cv;",$$cv));
664 $init->add(sprintf("CvGV(s\\_%x) = s\\_%x;",$$cv,$$gv));
665 warn sprintf("done saving GV 0x%x for CV 0x%x\n",
666 $$gv, $$cv) if $debug_cv;
668 my $filegv = $cv->FILEGV;
671 $init->add(sprintf("CvFILEGV(s\\_%x) = s\\_%x;", $$cv, $$filegv));
672 warn sprintf("done saving FILEGV 0x%x for CV 0x%x\n",
673 $$filegv, $$cv) if $debug_cv;
675 my $stash = $cv->STASH;
678 $init->add(sprintf("CvSTASH(s\\_%x) = s\\_%x;", $$cv, $$stash));
679 warn sprintf("done saving STASH 0x%x for CV 0x%x\n",
680 $$stash, $$cv) if $debug_cv;
682 $symsect->add(sprintf("svix%d\t(XPVCV*)&xpvcv_list[%u], %lu, 0x%x",
683 $sv_ix, $xpvcv_ix, $cv->REFCNT + 1, $cv->FLAGS));
689 my $sym = objsym($gv);
691 #warn sprintf("GV 0x%x already saved as $sym\n", $$gv); # debug
694 my $ix = $gv_index++;
695 $sym = savesym($gv, "gv_list[$ix]");
696 #warn sprintf("Saving GV 0x%x as $sym\n", $$gv); # debug
698 my $gvname = $gv->NAME;
699 my $name = cstring($gv->STASH->NAME . "::" . $gvname);
700 #warn "GV name is $name\n"; # debug
704 #warn(sprintf("EGV name is %s, saving it now\n",
705 # $egv->STASH->NAME . "::" . $egv->NAME)); # debug
706 $egvsym = $egv->save;
708 $init->add(qq[$sym = gv_fetchpv($name, TRUE, SVt_PV);],
709 sprintf("SvFLAGS($sym) = 0x%x;", $gv->FLAGS),
710 sprintf("GvFLAGS($sym) = 0x%x;", $gv->GvFLAGS),
711 sprintf("GvLINE($sym) = %u;", $gv->LINE));
712 # Shouldn't need to do save_magic since gv_fetchpv handles that
714 my $refcnt = $gv->REFCNT + 1;
715 $init->add(sprintf("SvREFCNT($sym) += %u;", $refcnt - 1)) if $refcnt > 1;
716 my $gvrefcnt = $gv->GvREFCNT;
718 $init->add(sprintf("GvREFCNT($sym) += %u;", $gvrefcnt - 1));
720 if (defined($egvsym)) {
721 # Shared glob *foo = *bar
722 $init->add("gp_free($sym);",
723 "GvGP($sym) = GvGP($egvsym);");
724 } elsif ($gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/) {
725 # Don't save subfields of special GVs (*_, *1, *# and so on)
726 # warn "GV::save saving subfields\n"; # debug
729 $init->add(sprintf("GvSV($sym) = s\\_%x;", $$gvsv));
730 # warn "GV::save \$$name\n"; # debug
735 $init->add(sprintf("GvAV($sym) = s\\_%x;", $$gvav));
736 # warn "GV::save \@$name\n"; # debug
741 $init->add(sprintf("GvHV($sym) = s\\_%x;", $$gvhv));
742 # warn "GV::save \%$name\n"; # debug
747 $init->add(sprintf("GvCV($sym) = (CV*)s\\_%x;", $$gvcv));
748 # warn "GV::save &$name\n"; # debug
751 my $gvfilegv = $gv->FILEGV;
753 $init->add(sprintf("GvFILEGV($sym) = (GV*)s\\_%x;",$$gvfilegv));
754 # warn "GV::save GvFILEGV(*$name)\n"; # debug
757 my $gvform = $gv->FORM;
759 $init->add(sprintf("GvFORM($sym) = (CV*)s\\_%x;", $$gvform));
760 # warn "GV::save GvFORM(*$name)\n"; # debug
765 $init->add(sprintf("GvIOp($sym) = s\\_%x;", $$gvio));
766 # warn "GV::save GvIO(*$name)\n"; # debug
774 my $sym = objsym($av);
775 return $sym if defined $sym;
776 my $avflags = $av->AvFLAGS;
777 $xpvavsect->add(sprintf("0, -1, -1, 0, 0.0, 0, Nullhv, 0, 0, 0x%x",
779 $svsect->add(sprintf("&xpvav_list[%d], %lu, 0x%x",
780 $xpvavsect->index, $av->REFCNT + 1, $av->FLAGS));
781 my $sv_list_index = $svsect->index;
782 my $fill = $av->FILL;
784 warn sprintf("saving AV 0x%x FILL=$fill AvFLAGS=0x%x", $$av, $avflags)
786 # XXX AVf_REAL is wrong test: need to save comppadlist but not stack
787 #if ($fill > -1 && ($avflags & AVf_REAL)) {
789 my @array = $av->ARRAY;
793 foreach $el (@array) {
794 warn sprintf("AV 0x%x[%d] = %s 0x%x\n",
795 $$av, $i++, class($el), $$el);
798 my @names = map($_->save, @array);
799 # XXX Better ways to write loop?
800 # Perhaps svp[0] = ...; svp[1] = ...; svp[2] = ...;
801 # Perhaps I32 i = 0; svp[i++] = ...; svp[i++] = ...; svp[i++] = ...;
804 "\tAV *av = (AV*)&sv_list[$sv_list_index];",
805 "\tav_extend(av, $fill);",
806 "\tsvp = AvARRAY(av);",
807 map("\t*svp++ = (SV*)$_;", @names),
808 "\tAvFILLp(av) = $fill;",
812 $init->add("av_extend((AV*)&sv_list[$sv_list_index], $max);")
815 return savesym($av, "(AV*)&sv_list[$sv_list_index]");
820 my $sym = objsym($hv);
821 return $sym if defined $sym;
822 my $name = $hv->NAME;
826 # A perl bug means HvPMROOT isn't altered when a PMOP is freed. Usually
827 # the only symptom is that sv_reset tries to reset the PMf_USED flag of
828 # a trashed op but we look at the trashed op_type and segfault.
829 #my $adpmroot = ${$hv->PMROOT};
831 $decl->add("static HV *hv$hv_index;");
832 # XXX Beware of weird package names containing double-quotes, \n, ...?
833 $init->add(qq[hv$hv_index = gv_stashpv("$name", TRUE);]);
835 $init->add(sprintf("HvPMROOT(hv$hv_index) = (PMOP*)s\\_%x;",
838 $sym = savesym($hv, "hv$hv_index");
842 # It's just an ordinary HV
843 $xpvhvsect->add(sprintf("0, 0, %d, 0, 0.0, 0, Nullhv, %d, 0, 0, 0",
844 $hv->MAX, $hv->RITER));
845 $svsect->add(sprintf("&xpvhv_list[%d], %lu, 0x%x",
846 $xpvhvsect->index, $hv->REFCNT + 1, $hv->FLAGS));
847 my $sv_list_index = $svsect->index;
848 my @contents = $hv->ARRAY;
851 for ($i = 1; $i < @contents; $i += 2) {
852 $contents[$i] = $contents[$i]->save;
854 $init->add("{", "\tHV *hv = (HV*)&sv_list[$sv_list_index];");
856 my ($key, $value) = splice(@contents, 0, 2);
857 $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
858 cstring($key),length($key),$value, hash($key)));
859 # $init->add(sprintf("\thv_store(hv, %s, %u, %s, %s);",
860 # cstring($key),length($key),$value, 0));
864 return savesym($hv, "(HV*)&sv_list[$sv_list_index]");
869 my $sym = objsym($io);
870 return $sym if defined $sym;
872 $pv = '' unless defined $pv;
873 my $len = length($pv);
874 $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",
875 $len, $len+1, $io->IVX, $io->NVX, $io->LINES,
876 $io->PAGE, $io->PAGE_LEN, $io->LINES_LEFT,
877 cstring($io->TOP_NAME), cstring($io->FMT_NAME),
878 cstring($io->BOTTOM_NAME), $io->SUBPROCESS,
879 cchar($io->IoTYPE), $io->IoFLAGS));
880 $svsect->add(sprintf("&xpvio_list[%d], %lu, 0x%x",
881 $xpviosect->index, $io->REFCNT + 1, $io->FLAGS));
882 $sym = savesym($io, sprintf("(IO*)&sv_list[%d]", $svsect->index));
884 foreach $field (qw(TOP_GV FMT_GV BOTTOM_GV)) {
885 $fsym = $io->$field();
887 $init->add(sprintf("Io$field($sym) = (GV*)s\\_%x;", $$fsym));
897 # This is where we catch an honest-to-goodness Nullsv (which gets
898 # blessed into B::SV explicitly) and any stray erroneous SVs.
899 return 0 unless $$sv;
900 confess sprintf("cannot save that type of SV: %s (0x%x)\n",
905 my $init_name = shift;
907 my @sections = ($opsect, $unopsect, $binopsect, $logopsect, $condopsect,
908 $listopsect, $pmopsect, $svopsect, $gvopsect, $pvopsect,
909 $loopsect, $copsect, $svsect, $xpvsect,
910 $xpvavsect, $xpvhvsect, $xpvcvsect, $xpvivsect, $xpvnvsect,
911 $xpvmgsect, $xpvlvsect, $xrvsect, $xpvbmsect, $xpviosect);
912 $bootstrap->output(\*STDOUT, "/* bootstrap %s */\n");
913 $symsect->output(\*STDOUT, "#define %s\n");
915 output_declarations();
916 foreach $section (@sections) {
917 my $lines = $section->index + 1;
919 my $name = $section->name;
920 my $typename = ($name eq "xpvcv") ? "XPVCV_or_similar" : uc($name);
921 print "Static $typename ${name}_list[$lines];\n";
924 $decl->output(\*STDOUT, "%s\n");
926 foreach $section (@sections) {
927 my $lines = $section->index + 1;
929 my $name = $section->name;
930 my $typename = ($name eq "xpvcv") ? "XPVCV_or_similar" : uc($name);
931 printf "static %s %s_list[%u] = {\n", $typename, $name, $lines;
932 $section->output(\*STDOUT, "\t{ %s },\n");
938 static int $init_name()
942 $init->output(\*STDOUT, "\t%s\n");
943 print "\treturn 0;\n}\n";
945 warn compile_stats();
946 warn "NULLOP count: $nullop_count\n";
950 sub output_declarations {
952 #ifdef BROKEN_STATIC_REDECL
953 #define Static extern
955 #define Static static
956 #endif /* BROKEN_STATIC_REDECL */
958 #ifdef BROKEN_UNION_INIT
960 * Cribbed from cv.h with ANY (a union) replaced by void*.
961 * Some pre-Standard compilers can't cope with initialising unions. Ho hum.
964 char * xpv_pv; /* pointer to malloced string */
965 STRLEN xpv_cur; /* length of xp_pv as a C string */
966 STRLEN xpv_len; /* allocated size */
967 IV xof_off; /* integer value */
968 double xnv_nv; /* numeric value, if any */
969 MAGIC* xmg_magic; /* magic for scalar array */
970 HV* xmg_stash; /* class package */
975 void (*xcv_xsub) _((CV*));
979 long xcv_depth; /* >= 2 indicates recursive call */
983 perl_mutex *xcv_mutexp;
984 struct perl_thread *xcv_owner; /* current owner thread */
985 #endif /* USE_THREADS */
990 #define XPVCV_or_similar XPVCV
991 #define ANYINIT(i) {i}
992 #endif /* BROKEN_UNION_INIT */
993 #define Nullany ANYINIT(0)
999 print "static GV *gv_list[$gv_index];\n" if $gv_index;
1004 sub output_boilerplate {
1009 #include "patchlevel.h"
1012 /* Workaround for mapstart: the only op which needs a different ppaddr */
1014 #define pp_mapstart pp_grepstart
1016 static void xs_init _((void));
1017 static PerlInterpreter *my_perl;
1024 #ifndef CAN_PROTOTYPE
1025 main(argc, argv, env)
1029 #else /* def(CAN_PROTOTYPE) */
1030 main(int argc, char **argv, char **env)
1031 #endif /* def(CAN_PROTOTYPE) */
1037 PERL_SYS_INIT(&argc,&argv);
1039 perl_init_i18nl10n(1);
1041 if (!PL_do_undump) {
1042 my_perl = perl_alloc();
1045 perl_construct( my_perl );
1050 PL_cshlen = strlen(PL_cshname);
1053 #ifdef ALLOW_PERL_OPTIONS
1054 #define EXTRA_OPTIONS 2
1056 #define EXTRA_OPTIONS 3
1057 #endif /* ALLOW_PERL_OPTIONS */
1058 New(666, fakeargv, argc + EXTRA_OPTIONS + 1, char *);
1059 fakeargv[0] = argv[0];
1062 #ifndef ALLOW_PERL_OPTIONS
1064 #endif /* ALLOW_PERL_OPTIONS */
1065 for (i = 1; i < argc; i++)
1066 fakeargv[i + EXTRA_OPTIONS] = argv[i];
1067 fakeargv[argc + EXTRA_OPTIONS] = 0;
1069 exitstatus = perl_parse(my_perl, xs_init, argc + EXTRA_OPTIONS,
1074 sv_setpv(GvSV(gv_fetchpv("0", TRUE, SVt_PV)), argv[0]);
1075 PL_main_cv = PL_compcv;
1078 exitstatus = perl_init();
1082 exitstatus = perl_run( my_perl );
1084 perl_destruct( my_perl );
1085 perl_free( my_perl );
1100 warn "----Symbol table:\n";
1101 while (($sym, $val) = each %symtable) {
1102 warn "$sym => $val\n";
1104 warn "---End of symbol table\n";
1110 svref_2object($sv)->save;
1114 sub Dummy_BootStrap { }
1119 my $package=$gv->STASH->NAME;
1120 my $name = $gv->NAME;
1122 return unless ($$cv || $name eq 'ISA');
1123 # We may be looking at this package just because it is a branch in the
1124 # symbol table which is on the path to a package which we need to save
1125 # e.g. this is 'Getopt' and wee need to save 'Getopt::Long'
1127 if ($$cv && $name eq "bootstrap" && $cv->XSUB)
1129 my $file = $cv->FILEGV->SV->PV;
1130 $bootstrap->add($file);
1132 unless ($unused_sub_packages{$package})
1134 warn sprintf("omitting cv $name in %s\n", $package) if $$cv; # if $debug_cv;
1139 if ($name eq "bootstrap" && $cv->XSUB)
1141 my $name = $gv->STASH->NAME.'::'.$name;
1143 *{$name} = \&Dummy_BootStrap;
1146 warn sprintf("saving extra CV &%s::%s (0x%x) from GV 0x%x\n",
1147 $package, $name, $$cv, $$gv) if ($debug_cv);
1150 elsif ($name eq 'ISA')
1158 my $package = shift;
1159 unless ($unused_sub_packages{$package})
1162 $unused_sub_packages{$package} = 1;
1163 if (defined(@{$package.'::ISA'}))
1165 foreach my $isa (@{$package.'::ISA'})
1167 if ($isa eq 'DynaLoader')
1169 unless (defined(&{$package.'::bootstrap'}))
1171 warn "Forcing bootstrap of $package\n";
1172 eval { $package->bootstrap };
1177 unless ($unused_sub_packages{$isa})
1179 warn "$isa saved (it is in $package\'s \@ISA)\n";
1191 no strict qw(vars refs);
1192 my $package = shift;
1193 $package =~ s/::$//;
1194 return $unused_sub_packages{$package} = 0 if ($package =~ /::::/); # skip ::::ISA::CACHE etc.
1195 # warn "Considering $package\n";#debug
1196 foreach my $u (grep($unused_sub_packages{$_},keys %unused_sub_packages))
1198 # If this package is a prefix to something we are saving, traverse it
1199 # but do not mark it for saving if it is not already
1200 # e.g. to get to Getopt::Long we need to traverse Getopt but need
1202 return 1 if ($u =~ /^$package\:\:/);
1204 if (exists $unused_sub_packages{$package})
1206 # warn "Cached $package is ".$unused_sub_packages{$package}."\n";
1207 return $unused_sub_packages{$package}
1209 # Omit the packages which we use (and which cause grief
1210 # because of fancy "goto &$AUTOLOAD" stuff).
1211 # XXX Surely there must be a nicer way to do this.
1212 if ($package eq "FileHandle" || $package eq "Config" ||
1213 $package eq "SelectSaver" || $package =~/^(B|IO)::/)
1215 return $unused_sub_packages{$package} = 0;
1217 # Now see if current package looks like an OO class this is probably too strong.
1218 foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE))
1220 if ($package->can($m))
1222 warn "$package has method $m: saving package\n";#debug
1223 return mark_package($package);
1226 return $unused_sub_packages{$package} = 0;
1231 my ($symref, $recurse, $prefix) = @_;
1236 $prefix = '' unless defined $prefix;
1237 while (($sym, $ref) = each %$symref)
1242 $sym = $prefix . $sym;
1243 if ($sym ne "main::" && &$recurse($sym))
1245 walkpackages(\%glob, $recurse, $sym);
1252 sub save_unused_subs
1255 &descend_marked_unused;
1257 walkpackages(\%{"main::"}, sub { should_save($_[0]); return 1 });
1258 warn "Saving methods\n";
1259 walksymtable(\%{"main::"}, "savecv", \&should_save);
1264 my $curpad_nam = (comppadlist->ARRAY)[0]->save;
1265 my $curpad_sym = (comppadlist->ARRAY)[1]->save;
1266 my $inc_hv = svref_2object(\%INC)->save;
1267 my $inc_av = svref_2object(\@INC)->save;
1268 $init->add( "PL_curpad = AvARRAY($curpad_sym);",
1269 "GvHV(PL_incgv) = $inc_hv;",
1270 "GvAV(PL_incgv) = $inc_av;",
1271 "av_store(CvPADLIST(PL_main_cv),0,SvREFCNT_inc($curpad_nam));",
1272 "av_store(CvPADLIST(PL_main_cv),1,SvREFCNT_inc($curpad_sym));");
1275 sub descend_marked_unused {
1276 foreach my $pack (keys %unused_sub_packages)
1278 mark_package($pack);
1283 warn "Starting compile\n";
1284 warn "Walking tree\n";
1285 seek(STDOUT,0,0); #exclude print statements in BEGIN{} into output
1286 walkoptree(main_root, "save");
1287 warn "done main optree, walking symtable for extras\n" if $debug_cv;
1289 my $init_av = init_av->save;
1290 $init->add(sprintf("PL_main_root = s\\_%x;", ${main_root()}),
1291 sprintf("PL_main_start = s\\_%x;", ${main_start()}),
1292 "PL_initav = $init_av;");
1294 warn "Writing output\n";
1295 output_boilerplate();
1297 output_all("perl_init");
1303 my @sections = (init => \$init, decl => \$decl, sym => \$symsect,
1304 binop => \$binopsect, condop => \$condopsect,
1305 cop => \$copsect, gvop => \$gvopsect,
1306 listop => \$listopsect, logop => \$logopsect,
1307 loop => \$loopsect, op => \$opsect, pmop => \$pmopsect,
1308 pvop => \$pvopsect, svop => \$svopsect, unop => \$unopsect,
1309 sv => \$svsect, xpv => \$xpvsect, xpvav => \$xpvavsect,
1310 xpvhv => \$xpvhvsect, xpvcv => \$xpvcvsect,
1311 xpviv => \$xpvivsect, xpvnv => \$xpvnvsect,
1312 xpvmg => \$xpvmgsect, xpvlv => \$xpvlvsect,
1313 xrv => \$xrvsect, xpvbm => \$xpvbmsect,
1314 xpvio => \$xpviosect, bootstrap => \$bootstrap);
1315 my ($name, $sectref);
1316 while (($name, $sectref) = splice(@sections, 0, 2)) {
1317 $$sectref = new B::C::Section $name, \%symtable, 0;
1323 my ($arg,$val) = @_;
1324 $unused_sub_packages{$arg} = $val;
1329 my ($option, $opt, $arg);
1331 while ($option = shift @options) {
1332 if ($option =~ /^-(.)(.*)/) {
1336 unshift @options, $option;
1339 if ($opt eq "-" && $arg eq "-") {
1344 $warn_undefined_syms = 1;
1345 } elsif ($opt eq "D") {
1346 $arg ||= shift @options;
1347 foreach $arg (split(//, $arg)) {
1350 } elsif ($arg eq "c") {
1352 } elsif ($arg eq "A") {
1354 } elsif ($arg eq "C") {
1356 } elsif ($arg eq "M") {
1359 warn "ignoring unknown debug option: $arg\n";
1362 } elsif ($opt eq "o") {
1363 $arg ||= shift @options;
1364 open(STDOUT, ">$arg") or return "$arg: $!\n";
1365 } elsif ($opt eq "v") {
1367 } elsif ($opt eq "u") {
1368 $arg ||= shift @options;
1369 mark_unused($arg,undef);
1370 } elsif ($opt eq "f") {
1371 $arg ||= shift @options;
1372 if ($arg eq "cog") {
1373 $pv_copy_on_grow = 1;
1374 } elsif ($arg eq "no-cog") {
1375 $pv_copy_on_grow = 0;
1377 } elsif ($opt eq "O") {
1378 $arg = 1 if $arg eq "";
1379 $pv_copy_on_grow = 0;
1381 # Optimisations for -O1
1382 $pv_copy_on_grow = 1;
1390 foreach $objname (@options) {
1391 eval "save_object(\\$objname)";
1396 return sub { save_main() };
1406 B::C - Perl compiler's C backend
1410 perl -MO=C[,OPTIONS] foo.pl
1414 This compiler backend takes Perl source and generates C source code
1415 corresponding to the internal structures that perl uses to run
1416 your program. When the generated C source is compiled and run, it
1417 cuts out the time which perl would have taken to load and parse
1418 your program into its internal semi-compiled form. That means that
1419 compiling with this backend will not help improve the runtime
1420 execution speed of your program but may improve the start-up time.
1421 Depending on the environment in which your program runs this may be
1422 either a help or a hindrance.
1426 If there are any non-option arguments, they are taken to be
1427 names of objects to be saved (probably doesn't work properly yet).
1428 Without extra arguments, it saves the main program.
1434 Output to filename instead of STDOUT
1438 Verbose compilation (currently gives a few compilation statistics).
1442 Force end of options
1446 Force apparently unused subs from package Packname to be compiled.
1447 This allows programs to use eval "foo()" even when sub foo is never
1448 seen to be used at compile time. The down side is that any subs which
1449 really are never used also have code generated. This option is
1450 necessary, for example, if you have a signal handler foo which you
1451 initialise with C<$SIG{BAR} = "foo">. A better fix, though, is just
1452 to change it to C<$SIG{BAR} = \&foo>. You can have multiple B<-u>
1453 options. The compiler tries to figure out which packages may possibly
1454 have subs in which need compiling but the current version doesn't do
1455 it very well. In particular, it is confused by nested packages (i.e.
1456 of the form C<A::B>) where package C<A> does not contain any subs.
1460 Debug options (concatenated or separate flags like C<perl -D>).
1464 OPs, prints each OP as it's processed
1468 COPs, prints COPs as processed (incl. file & line num)
1472 prints AV information on saving
1476 prints CV information on saving
1480 prints MAGIC information on saving
1484 Force optimisations on or off one at a time.
1488 Copy-on-grow: PVs declared and initialised statically.
1496 Optimisation level (n = 0, 1, 2, ...). B<-O> means B<-O1>. Currently,
1497 B<-O1> and higher set B<-fcog>.
1501 perl -MO=C,-ofoo.c foo.pl
1502 perl cc_harness -o foo foo.c
1504 Note that C<cc_harness> lives in the C<B> subdirectory of your perl
1505 library directory. The utility called C<perlcc> may also be used to
1506 help make use of this compiler.
1508 perl -MO=C,-v,-DcA bar.pl > /dev/null
1512 Plenty. Current status: experimental.
1516 Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>