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