File Coverage

blib/lib/B/C.pm
Criterion Covered Total %
statement 186 4451 4.1
branch 14 3642 0.3
condition 5 1923 0.2
subroutine 56 237 23.6
pod 0 97 0.0
total 261 10350 2.5


line stmt bran cond sub pod time code
1             # C.pm
2             #
3             # Copyright (c) 1996, 1997, 1998 Malcolm Beattie
4             # Copyright (c) 2008, 2009, 2010, 2011 Reini Urban
5             # Copyright (c) 2010 Nick Koston
6             # Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 cPanel Inc
7             #
8             # You may distribute under the terms of either the GNU General Public
9             # License or the Artistic License, as specified in the README file.
10             #
11              
12             package B::C;
13 55     55   5433350 use strict;
  55         82  
  55         6439  
14              
15             our $VERSION = '1.55';
16             our (%debug, $check, %Config);
17             BEGIN {
18 55     55   862 require B::C::Config;
19 55         146 *Config = \%B::C::Config::Config;
20 55 50 33     3263 if (!keys %Config or !exists $Config{usecperl}) {
21 0         0 warn "Empty \%B::C::Config::Config";
22 0         0 require Config;
23 0         0 Config->import;
24             }
25             # make it a restricted hash
26 55 50       4997 Internals::SvREADONLY(%Config, 1) if $] >= 5.008004;
27             }
28              
29             # Thanks to Mattia Barbon for the C99 tip to init any union members
30             my $C99 = $Config{d_c99_variadic_macros}; # http://docs.sun.com/source/819-3688/c99.app.html#pgfId-1003962
31              
32             package B::C::Section;
33 55     55   256 use strict;
  55         59  
  55         44983  
34              
35             my %sections;
36              
37             sub new {
38 0     0   0 my ($class, $section, $symtable, $default) = @_;
39 0         0 my $o = bless [-1, $section, $symtable, $default], $class;
40 0         0 $sections{$section} = $o;
41              
42 0         0 push @$o, { values => [] };
43              
44             # if sv add a dummy sv_arenaroot to support global destruction
45 0 0       0 if ($section eq 'sv') {
46             # 0 refcnt placeholder for the static arenasize later adjusted
47 0 0       0 $o->add( "NULL, 0, SVTYPEMASK|0x01000000".($] >= 5.009005?", {0}":'')); # SVf_FAKE
48 0         0 $o->[-1]{dbg}->[0] = "PL_sv_arenaroot";
49             }
50 0         0 return $o;
51             }
52              
53             sub get {
54 0     0   0 my ($class, $section) = @_;
55 0         0 return $sections{$section};
56             }
57              
58             sub add {
59 0     0   0 my $section = shift;
60 0         0 push( @{ $section->[-1]{values} }, @_ );
  0         0  
61             }
62              
63             sub remove {
64 0     0   0 my $section = shift;
65 0         0 pop @{ $section->[-1]{values} };
  0         0  
66             }
67              
68             sub index {
69 0     0   0 my $section = shift;
70 0         0 return scalar( @{ $section->[-1]{values} } ) - 1;
  0         0  
71             }
72              
73             sub name {
74 0     0   0 my $section = shift;
75 0         0 return $section->[1];
76             }
77              
78             sub symtable {
79 0     0   0 my $section = shift;
80 0         0 return $section->[2];
81             }
82              
83             sub default {
84 0     0   0 my $section = shift;
85 0         0 return $section->[3];
86             }
87              
88             sub typename {
89 0     0   0 my $section = shift;
90 0         0 my $name = $section->name;
91 0         0 my $typename = uc($name);
92             # -fcog hack to statically initialize PVs (SVPV for 5.10-5.11 only)
93 0 0 0     0 $typename = 'SVPV' if $typename eq 'SV' and $] > 5.009005 and $] < 5.012 and !$C99;
      0        
      0        
94             # $typename = 'const '.$typename if $name !~ /^(cop_|sv_)/;
95 0 0       0 $typename = 'UNOP_AUX' if $typename eq 'UNOPAUX';
96 0 0       0 $typename = 'SV*' if $typename =~ /^AVCO[WG]_/;
97             #$typename = 'MyPADNAME' if $typename eq 'PADNAME' and $] >= 5.018;
98 0         0 return $typename;
99             }
100              
101             sub comment {
102 0     0   0 my $section = shift;
103 0 0       0 $section->[-1]{comment} = join( "", @_ ) if @_;
104 0         0 $section->[-1]{comment};
105             }
106              
107             # add debugging info - stringified flags on -DF
108             sub debug {
109 0     0   0 my $section = shift;
110 0         0 my $dbg = join( " ", @_ );
111 0 0       0 $section->[-1]{dbg}->[ $section->index ] = $dbg if $dbg;
112             }
113              
114             sub output {
115 0     0   0 my ( $section, $fh, $format ) = @_;
116 0   0     0 my $sym = $section->symtable || {};
117 0         0 my $default = $section->default;
118 0 0       0 return if $B::C::check;
119 0         0 my $i = 0;
120 0 0 0     0 my $dodbg = 1 if $debug{flags} and $section->[-1]{dbg};
121 0 0       0 if ($section->name eq 'sv') { #fixup arenaroot refcnt
122 0         0 my $len = scalar @{ $section->[-1]{values} };
  0         0  
123 0         0 $section->[-1]{values}->[0] =~ s/^NULL, 0/NULL, $len/;
124             }
125 0         0 foreach ( @{ $section->[-1]{values} } ) {
  0         0  
126 0         0 my $dbg = "";
127 0         0 my $ref = "";
128 0 0       0 if (m/(s\\_[0-9a-f]+)/) {
129 0 0 0     0 if (!exists($sym->{$1}) and $1 ne 's\_0') {
130 0         0 $ref = $1;
131 0         0 $B::C::unresolved_count++;
132 0 0       0 if ($B::C::verbose) {
133 0         0 my $caller = caller(1);
134 0 0       0 warn "Warning: unresolved ".$section->name." symbol $ref\n"
135             if $caller eq 'B::C';
136             }
137             }
138             }
139 0 0       0 s{(s\\_[0-9a-f]+)}{ exists($sym->{$1}) ? $sym->{$1} : $default; }ge;
  0         0  
140 0 0 0     0 if ($dodbg and $section->[-1]{dbg}->[$i]) {
141 0         0 $dbg = " /* ".$section->[-1]{dbg}->[$i]." ".$ref." */";
142             }
143 0 0       0 if ($format eq "\t{ %s }, /* %s_list[%d] %s */%s\n") {
144 0         0 printf $fh $format, $_, $section->name, $i, $ref, $dbg;
145             } else {
146 0         0 printf $fh $format, $_;
147             }
148 0         0 ++$i;
149             }
150             }
151              
152             package B::C::InitSection;
153 55     55   276 use strict;
  55         70  
  55         39018  
154              
155             # avoid use vars
156             @B::C::InitSection::ISA = qw(B::C::Section);
157              
158             sub new {
159 0     0   0 my $class = shift;
160 0         0 my $max_lines = 10000; #pop;
161 0         0 my $section = $class->SUPER::new(@_);
162              
163 0         0 $section->[-1]{evals} = [];
164 0         0 $section->[-1]{initav} = [];
165 0         0 $section->[-1]{chunks} = [];
166 0         0 $section->[-1]{nosplit} = 0;
167 0         0 $section->[-1]{current} = [];
168 0         0 $section->[-1]{count} = 0;
169 0         0 $section->[-1]{size} = 0;
170 0         0 $section->[-1]{max_lines} = $max_lines;
171              
172 0         0 return $section;
173             }
174              
175             sub split {
176 0     0   0 my $section = shift;
177             $section->[-1]{nosplit}--
178 0 0       0 if $section->[-1]{nosplit} > 0;
179             }
180              
181             sub no_split {
182 0     0   0 shift->[-1]{nosplit}++;
183             }
184              
185             sub inc_count {
186 0     0   0 my $section = shift;
187              
188 0         0 $section->[-1]{count} += $_[0];
189              
190             # this is cheating
191 0         0 $section->add();
192             }
193              
194             sub add {
195 0     0   0 my $section = shift->[-1];
196 0         0 my $current = $section->{current};
197 0         0 my $nosplit = $section->{nosplit};
198              
199 0         0 push @$current, @_;
200 0         0 $section->{count} += scalar(@_);
201 0 0 0     0 if ( !$nosplit && $section->{count} >= $section->{max_lines} ) {
202 0         0 push @{ $section->{chunks} }, $current;
  0         0  
203 0         0 $section->{current} = [];
204 0         0 $section->{count} = 0;
205             }
206             }
207              
208             sub add_eval {
209 0     0   0 my $section = shift;
210 0         0 my @strings = @_;
211              
212 0         0 foreach my $i (@strings) {
213 0         0 $i =~ s/\"/\\\"/g;
214             }
215 0         0 push @{ $section->[-1]{evals} }, @strings;
  0         0  
216             }
217              
218             sub pre_destruct {
219 0     0   0 my $section = shift;
220 0         0 push @{ $section->[-1]{pre_destruct} }, @_;
  0         0  
221             }
222              
223             sub add_initav {
224 0     0   0 my $section = shift;
225 0         0 push @{ $section->[-1]{initav} }, @_;
  0         0  
226             }
227              
228             sub output {
229 0     0   0 my ( $section, $fh, $format, $init_name ) = @_;
230 0   0     0 my $sym = $section->symtable || {};
231 0         0 my $default = $section->default;
232 0 0       0 return if $B::C::check;
233 0         0 push @{ $section->[-1]{chunks} }, $section->[-1]{current};
  0         0  
234              
235 0         0 my $name = "aaaa";
236 0         0 foreach my $i ( @{ $section->[-1]{chunks} } ) {
  0         0  
237             # dTARG and dSP unused -nt
238 0         0 print $fh <<"EOT";
239             static void ${init_name}_${name}(pTHX)
240             {
241             EOT
242 0         0 foreach my $i ( @{ $section->[-1]{initav} } ) {
  0         0  
243 0         0 print $fh "\t",$i,"\n";
244             }
245 0         0 foreach my $j (@$i) {
246 0         0 $j =~ s{(s\\_[0-9a-f]+)}
247 0 0       0 { exists($sym->{$1}) ? $sym->{$1} : $default; }ge;
248 0         0 print $fh "\t$j\n";
249             }
250 0 0       0 if (@{ $section->[-1]{evals} }) {
  0         0  
251             # We need to output evals after dl_init, in init2
252 0 0       0 if ($section->name ne 'init2') {
253 0         0 die "Invalid section ".$section->name."->add_eval, use init2";
254             } else {
255 0         0 foreach my $s ( @{ $section->[-1]{evals} } ) {
  0         0  
256 0         0 print $fh "\teval_pv(\"$s\",1);\n";
257             }
258             }
259             }
260 0         0 print $fh "}\n";
261              
262 0         0 $section->SUPER::add("${init_name}_${name}(aTHX);");
263 0         0 ++$name;
264             }
265              
266 0         0 print $fh <<"EOT";
267             PERL_STATIC_INLINE int ${init_name}(pTHX)
268             {
269             EOT
270 0 0       0 if ($section->name eq 'init') {
271 0         0 print $fh "\tperl_init0(aTHX);\n";
272             }
273 0         0 $section->SUPER::output( $fh, $format );
274 0         0 print $fh "\treturn 0;\n}\n";
275             }
276              
277             package B::C;
278 55     55   255 use strict;
  55         703  
  55         2490  
279 55     55   509 use Exporter ();
  55         69  
  55         725  
280 55     55   24780 use Errno (); #needed since 5.14
  55         70468  
  55         5559  
281             our %Regexp;
282              
283             { # block necessary for caller to work
284             my $caller = caller;
285             if ( $caller eq 'O' or $caller eq 'Od' ) {
286             require XSLoader;
287             XSLoader::load('B::C'); # for r-magic and for utf8-keyed B::HV->ARRAY
288             }
289             }
290              
291             our @ISA = qw(Exporter);
292             our @EXPORT_OK =
293             qw(output_all output_boilerplate output_main output_main_rest mark_unused mark_skip
294             init_sections set_callback save_unused_subs objsym save_context fixup_ppaddr
295             save_sig svop_or_padop_pv inc_cleanup ivx nvx curcv set_curcv);
296              
297             # for 5.6.[01] better use the native B::C
298             # but 5.6.2 works fine
299             use B
300 55         24783 qw(minus_c sv_undef walkoptree walkoptree_slow main_root main_start peekop
301             cchar svref_2object compile_stats comppadlist hash
302             threadsv_names main_cv init_av end_av opnumber cstring
303 55     55   252 HEf_SVKEY SVf_POK SVp_POK SVf_ROK SVf_IOK SVf_NOK SVf_IVisUV SVf_READONLY);
  55         64  
304              
305             # usually 0x400000, but can be as low as 0x10000
306             # http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/compdirsimagebaseaddress_xml.html
307             # called mapped_base on linux (usually 0xa38000)
308             sub LOWEST_IMAGEBASE() {0x10000}
309              
310             sub _load_mro {
311 0 0 0 0   0 eval q/require mro; 1/ or die if $] >= 5.010;
312 0     0   0 *_load_mro = sub {};
313             }
314              
315             sub is_using_mro {
316 0 0   0 0 0 return keys %{mro::} > 10 ? 1 : 0;
317             }
318              
319             BEGIN {
320 55 50   55   217 if ($] >= 5.008) {
321 55         6254 @B::NV::ISA = 'B::IV'; # add IVX to nv. This fixes test 23 for Perl 5.8
322 55         2307 B->import(qw(regex_padav SVp_NOK SVp_IOK CVf_CONST CVf_ANON
323             SVf_FAKE)); # both unsupported for 5.6
324 55         2802 eval q[
325             sub SVs_OBJECT() {0x00100000}
326             sub SVf_AMAGIC() {0x10000000}
327             ];
328             } else {
329 0         0 eval q[
330             sub SVp_NOK() {0}; # unused
331             sub SVp_IOK() {0};
332             sub CVf_ANON() {4};
333             sub CVf_CONST() {0}; # unused
334             sub PMf_ONCE() {0xff}; # unused
335             sub SVf_FAKE() {0x00100000}; # unused
336             sub SVs_OBJECT() {0x00001000}
337             sub SVf_AMAGIC() {0x10000000}
338             ];
339 0         0 @B::PVMG::ISA = qw(B::PVNV B::RV);
340             }
341 0     0 0 0 sub SVf_UTF8 { 0x20000000 }
342 55 50       214 if ($] >= 5.008001) {
343 55         1157 B->import(qw(SVt_PVGV CVf_WEAKOUTSIDE)); # added with 5.8.1
344             } else {
345 0         0 eval q[sub SVt_PVGV() {13}];
346 0         0 eval q[sub CVf_WEAKOUTSIDE() { 0x0 }]; # unused
347             }
348 55 50       135 if ($] >= 5.010) {
349             #require mro; # mro->import();
350             # not exported:
351 0     0 0 0 sub SVf_OOK { 0x02000000 }
352 55         2226 eval q[sub SVs_GMG() { 0x00200000 }
353             sub SVs_SMG() { 0x00400000 }];
354 55 50       172 if ($] >= 5.018) {
    0          
    0          
355 55         985 B->import(qw(PMf_EVAL RXf_EVAL_SEEN));
356 55         1419 eval q[sub PMf_ONCE(){ 0x10000 }]; # PMf_ONCE also not exported
357             } elsif ($] >= 5.014) {
358 0         0 eval q[sub PMf_ONCE(){ 0x8000 }];
359             } elsif ($] >= 5.012) {
360 0         0 eval q[sub PMf_ONCE(){ 0x0080 }];
361             } else { # 5.10. not used with <= 5.8
362 0         0 eval q[sub PMf_ONCE(){ 0x0002 }];
363             }
364 55 50       175 if ($] > 5.021006) {
365 55         1028 B->import(qw(SVf_PROTECT CVf_ANONCONST SVs_PADSTALE));
366             } else {
367 0         0 eval q[sub SVf_PROTECT() { 0x0 }
368             sub CVf_ANONCONST(){ 0x0 }
369             sub SVs_PADSTALE() { 0x0 }
370             ]; # unused
371             }
372             } else {
373 0         0 eval q[sub SVs_GMG() { 0x00002000 }
374             sub SVs_SMG() { 0x00004000 }
375             sub SVf_PROTECT(){ 0x0 }
376             sub CVf_ANONCONST(){ 0x0 }
377             sub SVs_PADSTALE() { 0x0 }
378             ]; # unused
379             }
380 55 50       143 if ($] < 5.018) {
381 0         0 eval q[sub RXf_EVAL_SEEN() { 0x0 }
382             sub PMf_EVAL() { 0x0 }
383             sub SVf_IsCOW() { 0x0 }
384             ]; # unused
385             } else {
386             # 5.18
387 55         767 B->import(qw(SVf_IsCOW));
388             #if (exists ${B::}{PADNAME::}) {
389 55         496 @B::PADNAME::ISA = qw(B::PV);
390             #}
391             #if (exists ${B::}{PADLIST::}) {
392 55         588 @B::PADLIST::ISA = qw(B::AV);
393             #}
394             #if (exists ${B::}{PADNAMELIST::}) {
395 55 50       209 if ($] > 5.021005) { # 5.22
396 55         266 @B::PADNAME::ISA = ();
397 55         422 @B::PADNAMELIST::ISA = qw(B::AV);
398             }
399 55 50 33     1303 if ($Config{usecperl} and $] >= 5.022002) {
400 0         0 eval q[sub SVpav_REAL () { 0x40000000 }
401             sub SVpav_REIFY (){ 0x80000000 }
402             ];
403             }
404             }
405             }
406 55     55   22427 use B::Asmdata qw(@specialsv_name);
  55         107  
  55         5116  
407              
408 55     55   23595 use FileHandle;
  55         413204  
  55         266  
409              
410             my $hv_index = 0;
411             my $gv_index = 0;
412             my $re_index = 0;
413             my $pv_index = 0;
414             my $cv_index = 0;
415             my $hek_index = 0;
416             my $anonsub_index = 0;
417             my $initsub_index = 0;
418             my $padlist_index = 0;
419             my $padname_index = 0;
420             my $padnl_index = 0;
421              
422             # exclude all not B::C:: prefixed subs
423             my %all_bc_subs = map {$_=>1}
424             qw(B::AV::save B::BINOP::save B::BM::save B::COP::save B::CV::save
425             B::FAKEOP::fake_ppaddr B::FAKEOP::flags B::FAKEOP::new B::FAKEOP::next
426             B::FAKEOP::ppaddr B::FAKEOP::private B::FAKEOP::save B::FAKEOP::sibling
427             B::FAKEOP::targ B::FAKEOP::type B::GV::save B::GV::savecv B::HV::save
428             B::IO::save B::IO::save_data B::IV::save B::LISTOP::save B::LOGOP::save
429             B::LOOP::save B::NULL::save B::NV::save B::OBJECT::save
430             B::OP::_save_common B::OP::fake_ppaddr B::OP::isa B::OP::save
431             B::PADOP::save B::PMOP::save B::PV::save
432             B::PVIV::save B::PVLV::save B::PVMG::save B::PVMG::save_magic B::PVNV::save
433             B::PVOP::save B::REGEXP::save B::RV::save B::SPECIAL::save B::SPECIAL::savecv
434             B::SV::save B::SVOP::save B::UNOP::save B::UV::save B::REGEXP::EXTFLAGS);
435              
436             # track all internally used packages. all other may not be deleted automatically
437             # - hidden methods
438             # uses now @B::C::Config::deps
439             our %all_bc_deps = map {$_=>1}
440             @B::C::Config::deps ? @B::C::Config::deps
441             : qw(AnyDBM_File AutoLoader B B::AV B::Asmdata B::BINOP B::BM B::C B::C::Config B::C::InitSection B::C::Section B::CC B::COP B::CV B::FAKEOP B::FM B::GV B::HE B::HV B::IO B::IV B::LEXWARN B::LISTOP B::LOGOP B::LOOP B::MAGIC B::NULL B::NV B::OBJECT B::OP B::PADLIST B::PADNAME B::PADNAMELIST B::PADOP B::PMOP B::PV B::PVIV B::PVLV B::PVMG B::PVNV B::PVOP B::REGEXP B::RHE B::RV B::SPECIAL B::STASHGV B::SV B::SVOP B::UNOP B::UV CORE CORE::GLOBAL Carp DB DynaLoader Errno Exporter Exporter::Heavy ExtUtils ExtUtils::Constant ExtUtils::Constant::ProxySubs Fcntl FileHandle IO IO::File IO::Handle IO::Poll IO::Seekable IO::Socket Internals O POSIX PerlIO PerlIO::Layer PerlIO::scalar Regexp SelectSaver Symbol UNIVERSAL XSLoader __ANON__ arybase arybase::mg base fields main maybe maybe::next mro next overload re strict threads utf8 vars version warnings warnings::register);
442             $all_bc_deps{Socket} = 1 if !@B::C::Config::deps and $] > 5.021;
443              
444             # B::C stash footprint: mainly caused by blib, warnings, and Carp loaded with DynaLoader
445             # perl5.15.7d-nt -MO=C,-o/dev/null -MO=Stash -e0
446             # -umain,-ure,-umro,-ustrict,-uAnyDBM_File,-uFcntl,-uRegexp,-uoverload,-uErrno,-uExporter,-uExporter::Heavy,-uConfig,-uwarnings,-uwarnings::register,-uDB,-unext,-umaybe,-umaybe::next,-uFileHandle,-ufields,-uvars,-uAutoLoader,-uCarp,-uSymbol,-uPerlIO,-uPerlIO::scalar,-uSelectSaver,-uExtUtils,-uExtUtils::Constant,-uExtUtils::Constant::ProxySubs,-uthreads,-ubase
447             # perl5.15.7d-nt -MErrno -MO=Stash -e0
448             # -umain,-ure,-umro,-ustrict,-uRegexp,-uoverload,-uErrno,-uExporter,-uExporter::Heavy,-uwarnings,-uwarnings::register,-uConfig,-uDB,-uvars,-uCarp,-uPerlIO,-uthreads
449             # perl5.15.7d-nt -Mblib -MO=Stash -e0
450             # -umain,-ure,-umro,-ustrict,-uCwd,-uRegexp,-uoverload,-uFile,-uFile::Spec,-uFile::Spec::Unix,-uDos,-uExporter,-uExporter::Heavy,-uConfig,-uwarnings,-uwarnings::register,-uDB,-uEPOC,-ublib,-uScalar,-uScalar::Util,-uvars,-uCarp,-uVMS,-uVMS::Filespec,-uVMS::Feature,-uWin32,-uPerlIO,-uthreads
451             # perl -MO=Stash -e0
452             # -umain,-uTie,-uTie::Hash,-ure,-umro,-ustrict,-uRegexp,-uoverload,-uExporter,-uExporter::Heavy,-uwarnings,-uDB,-uCarp,-uPerlIO,-uthreads
453             # pb -MB::Stash -e0
454             # -umain,-ure,-umro,-uRegexp,-uPerlIO,-uExporter,-uDB
455              
456             my ($prev_op, $package_pv, @package_pv); # global stash for methods since 5.13
457             my (%symtable, %cvforward, %lexwarnsym);
458             my (%strtable, %stashtable, %hektable, %statichektable, %gptable, %cophhtable, %copgvtable);
459             my (%xsub, %init2_remap);
460             my ($warn_undefined_syms, $swash_init, $swash_ToCf);
461             my ($staticxs, $outfile);
462             my (%include_package, %dumped_package, %skip_package, %isa_cache, %static_ext);
463             my ($use_xsloader, $Devel_Peek_Dump_added);
464             my $nullop_count = 0;
465             my $unresolved_count = 0;
466             # options and optimizations shared with B::CC
467             our ($module, $init_name, %savINC, %curINC, $mainfile, @static_free);
468             our ($use_av_undef_speedup, $use_svpop_speedup) = (1, 1);
469             our ($optimize_ppaddr, $optimize_warn_sv, $use_perl_script_name,
470             $save_data_fh, $save_sig, $optimize_cop, $av_init, $av_init2, $ro_inc, $destruct,
471             $fold, $warnings, $const_strings, $stash, $can_delete_pkg, $pv_copy_on_grow, $dyn_padlist,
472             $walkall, $cow);
473             our $verbose = 0;
474             our %option_map = (
475             #ignored until IsCOW has a seperate COWREFCNT field (5.22 maybe)
476             'cog' => \$B::C::pv_copy_on_grow,
477             'const-strings' => \$B::C::const_strings,
478             'save-data' => \$B::C::save_data_fh,
479             'ppaddr' => \$B::C::optimize_ppaddr,
480             'walkall' => \$B::C::walkall,
481             'warn-sv' => \$B::C::optimize_warn_sv,
482             'av-init' => \$B::C::av_init,
483             'av-init2' => \$B::C::av_init2,
484             'delete-pkg' => \$B::C::can_delete_pkg,
485             'ro-inc' => \$B::C::ro_inc,
486             # if to disable the COW flag since 5.18
487             'cow' => \$B::C::cow, # enable with -O2
488             'stash' => \$B::C::stash, # enable with -fstash
489             'destruct' => \$B::C::destruct, # disable with -fno-destruct
490             'fold' => \$B::C::fold, # disable with -fno-fold
491             'warnings' => \$B::C::warnings, # disable with -fno-warnings
492             'use-script-name' => \$use_perl_script_name,
493             'save-sig-hash' => \$B::C::save_sig,
494             'dyn-padlist' => \$B::C::dyn_padlist, # with -O4, needed for cv cleanup with non-local exits since 5.18
495             'cop' => \$optimize_cop, # XXX very unsafe!
496             # Better do it in CC, but get rid of
497             # NULL cops also there.
498             );
499             our %optimization_map = (
500             0 => [qw()], # special case
501             1 => [qw(-fppaddr -fav-init2)], # falls back to -fav-init
502             2 => [qw(-fro-inc -fsave-data)],
503             3 => [qw(-fno-destruct -fconst-strings -fno-fold -fno-warnings)],
504             4 => [qw(-fcop -fno-dyn-padlist)],
505             );
506             push @{$optimization_map{2}}, '-fcow' if $] >= 5.020;
507             our %debug_map = (
508             'O' => 'op',
509             'A' => 'av',
510             'H' => 'hv',
511             'C' => 'cv',
512             'M' => 'mg',
513             'R' => 'rx',
514             'G' => 'gv',
515             'S' => 'sv',
516             'P' => 'pv',
517             'W' => 'walk',
518             'c' => 'cops',
519             's' => 'sub',
520             'p' => 'pkg',
521             # 'm' => 'meth',
522             'u' => 'unused',
523             );
524              
525             my @xpvav_sizes;
526             my ($max_string_len, $in_endav);
527             my %static_core_pkg; # = map {$_ => 1} static_core_packages();
528              
529             my $MULTI = $Config{usemultiplicity};
530             my $ITHREADS = $Config{useithreads};
531             my $DEBUGGING = ($Config{ccflags} =~ m/-DDEBUGGING/);
532             my $DEBUG_LEAKING_SCALARS = $Config{ccflags} =~ m/-DDEBUG_LEAKING_SCALARS/;
533             my $CPERL56 = ( $Config{usecperl} and $] >= 5.025003 ); #sibparent, xpad_cop_seq
534             my $CPERL55 = ( $Config{usecperl} and $] >= 5.025001 ); #HVMAX_T, RITER_T, ...
535             my $CPERL52 = ( $Config{usecperl} and $] >= 5.022002 ); #sv_objcount, AvSTATIC, sigs
536             my $CPERL51 = ( $Config{usecperl} );
537             my $PERL524 = ( $] >= 5.023005 ); #xpviv sharing assertion
538             my $PERL522 = ( $] >= 5.021006 ); #PADNAMELIST, IsCOW, padname_with_str, compflags
539             my $PERL518 = ( $] >= 5.017010 );
540             my $PERL514 = ( $] >= 5.013002 );
541             my $PERL512 = ( $] >= 5.011 );
542             my $PERL510 = ( $] >= 5.009005 );
543             my $PERL56 = ( $] < 5.008001 ); # yes. 5.8.0 is a 5.6.x
544             #my $C99 = $Config{d_c99_variadic_macros}; # http://docs.sun.com/source/819-3688/c99.app.html#pgfId-1003962
545             my $MAD = $Config{mad};
546             my $MYMALLOC = $Config{usemymalloc} eq 'define';
547             my $HAVE_DLFCN_DLOPEN = $Config{i_dlfcn} && $Config{d_dlopen};
548             # %Lu is not supported on older 32bit systems
549             my $u32fmt = $Config{ivsize} == 4 ? "%lu" : "%u";
550 0 0   0 0 0 sub IS_MSVC () { $^O eq 'MSWin32' and $Config{cc} eq 'cl' }
551             my $have_sibparent = ($] >= 5.025006
552             or $Config{ccflags} =~ /-DPERL_OP_PARENT/
553             or ($CPERL55 && $] >= 5.025003)) ? 1 : 0;
554              
555             my @threadsv_names;
556              
557             BEGIN {
558 55     55   106387 @threadsv_names = threadsv_names();
559             }
560              
561             # This the Carp free workaround for DynaLoader::bootstrap
562 0     0 0 0 sub DynaLoader::croak {die @_}
563              
564             # needed for init2 remap and Dynamic annotation
565             sub dl_module_to_sofile {
566 0 0   0 0 0 my $module = shift or die "missing module name";
567 0 0       0 my $modlibname = shift or die "missing module filepath";
568 0         0 my @modparts = split(/::/,$module);
569 0         0 my $modfname = $modparts[-1];
570 0         0 my $modpname = join('/',@modparts);
571 0         0 my $c = @modparts;
572 0         0 $modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename
573 0 0       0 die "missing module filepath" unless $modlibname;
574 0         0 my $sofile = "$modlibname/auto/$modpname/$modfname.".$Config{dlext};
575 0         0 return $sofile;
576             }
577              
578             # 5.15.3 workaround [perl #101336], without .bs support
579             # XSLoader::load_file($module, $modlibname, ...)
580             my $dlext = $Config{dlext};
581 0 0 0 0 0 0 eval q|
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
582             sub XSLoader::load_file {
583             #package DynaLoader;
584             my $module = shift or die "missing module name";
585             my $modlibname = shift or die "missing module filepath";
586             print STDOUT "XSLoader::load_file(\"$module\", \"$modlibname\" @_)\n"
587             if ${DynaLoader::dl_debug};
588              
589             push @_, $module;
590             # works with static linking too
591             my $boots = "$module\::bootstrap";
592             goto &$boots if defined &$boots;
593              
594             my @modparts = split(/::/,$module); # crashes threaded, issue 100
595             my $modfname = $modparts[-1];
596             my $modpname = join('/',@modparts);
597             my $c = @modparts;
598             $modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename
599             die "missing module filepath" unless $modlibname;
600             my $file = "$modlibname/auto/$modpname/$modfname."|.qq(."$dlext").q|;
601              
602             # skip the .bs "bullshit" part, needed for some old solaris ages ago
603              
604             print STDOUT "goto DynaLoader::bootstrap_inherit\n"
605             if ${DynaLoader::dl_debug} and not -f $file;
606             goto \&DynaLoader::bootstrap_inherit if not -f $file;
607             my $modxsname = $module;
608             $modxsname =~ s/\W/_/g;
609             my $bootname = "boot_".$modxsname;
610             @DynaLoader::dl_require_symbols = ($bootname);
611              
612             my $boot_symbol_ref;
613             if ($boot_symbol_ref = DynaLoader::dl_find_symbol(0, $bootname)) {
614             print STDOUT "dl_find_symbol($bootname) ok => goto boot\n"
615             if ${DynaLoader::dl_debug};
616             goto boot; #extension library has already been loaded, e.g. darwin
617             }
618             # Many dynamic extension loading problems will appear to come from
619             # this section of code: XYZ failed at line 123 of DynaLoader.pm.
620             # Often these errors are actually occurring in the initialisation
621             # C code of the extension XS file. Perl reports the error as being
622             # in this perl code simply because this was the last perl code
623             # it executed.
624              
625             my $libref = DynaLoader::dl_load_file($file, 0) or do {
626             die("Can't load '$file' for module $module: " . DynaLoader::dl_error());
627             };
628             push(@DynaLoader::dl_librefs,$libref); # record loaded object
629              
630             my @unresolved = DynaLoader::dl_undef_symbols();
631             if (@unresolved) {
632             die("Undefined symbols present after loading $file: @unresolved\n");
633             }
634              
635             $boot_symbol_ref = DynaLoader::dl_find_symbol($libref, $bootname) or do {
636             die("Can't find '$bootname' symbol in $file\n");
637             };
638             print STDOUT "dl_find_symbol($libref, $bootname) ok => goto boot\n"
639             if ${DynaLoader::dl_debug};
640             push(@DynaLoader::dl_modules, $module); # record loaded module
641              
642             boot:
643             my $xs = DynaLoader::dl_install_xsub($boots, $boot_symbol_ref, $file);
644             print STDOUT "dl_install_xsub($boots, $boot_symbol_ref, $file)\n"
645             if ${DynaLoader::dl_debug};
646             # See comment block above
647             push(@DynaLoader::dl_shared_objects, $file); # record files loaded
648             return &$xs(@_);
649             }
650             | if $] >= 5.015003 and !$CPERL51;
651             # Note: cperl uses a different API: the 2nd arg is the sofile directly
652              
653             # Code sections
654             my (
655             $init, $decl, $symsect, $binopsect, $condopsect,
656             $copsect, $padopsect, $listopsect, $logopsect, $loopsect,
657             $opsect, $pmopsect, $pvopsect, $svopsect, $unopsect,
658             $methopsect, $unopauxsect,
659             $svsect, $xpvsect, $xpvavsect, $xpvhvsect, $xpvcvsect,
660             $xpvivsect, $xpvuvsect, $xpvnvsect, $xpvmgsect, $xpvlvsect,
661             $xrvsect, $xpvbmsect, $xpviosect, $heksect, $free,
662             $padlistsect, $padnamesect, $padnlsect, $init0, $init1, $init2
663             );
664             my (%padnamesect, %avcowsect, %avcogsect);
665             my @padnamesect_sizes = (8, 16, 24, 32, 40, 48, 56, 64);
666              
667             my @op_sections =
668             \(
669             $binopsect, $condopsect, $copsect, $padopsect,
670             $listopsect, $logopsect, $loopsect, $opsect,
671             $pmopsect, $pvopsect, $svopsect, $unopsect,
672             $methopsect, $unopauxsect
673             );
674             # push @op_sections, ($resect) if $PERL512;
675             sub walk_and_save_optree;
676             my $saveoptree_callback = \&walk_and_save_optree;
677 14     14 0 105034 sub set_callback { $saveoptree_callback = shift }
678 0     0 0 0 sub saveoptree { &$saveoptree_callback(@_) }
679             sub save_main_rest;
680 0 0   0 0 0 sub verbose { if (@_) { $verbose = shift; } else { $verbose; } }
  0         0  
  0         0  
681 0 0   0 0 0 sub module { if (@_) { $module = shift; } else { $module; } }
  0         0  
  0         0  
682              
683             sub walk_and_save_optree {
684 0     0 0 0 my ( $name, $root, $start ) = @_;
685 0 0       0 if ($root) {
686             # B.xs: walkoptree does more, reifying refs. rebless or recreating it.
687             # TODO: add walkoptree_debug support.
688 0 0       0 $verbose ? walkoptree_slow( $root, "save" ) : walkoptree( $root, "save" );
689             }
690 0         0 return objsym($start);
691             }
692              
693             # Look this up here so we can do just a number compare
694             # rather than looking up the name of every BASEOP in B::OP
695             my $OP_THREADSV = opnumber('threadsv');
696             my $OP_DBMOPEN = opnumber('dbmopen');
697             my $OP_FORMLINE = opnumber('formline');
698             my $OP_UCFIRST = opnumber('ucfirst');
699             my $OP_CUSTOM = opnumber('custom');
700              
701             # special handling for nullified COP's.
702             my %OP_COP = ( opnumber('nextstate') => 1 );
703             $OP_COP{ opnumber('setstate') } = 1 if $] > 5.005003 and $] < 5.005062;
704             $OP_COP{ opnumber('dbstate') } = 1 unless $PERL512;
705             warn %OP_COP if $debug{cops};
706              
707             # 1. called from method_named, so hashp should be defined
708             # 2. called from svop before method_named to cache the $package_pv
709             sub svop_or_padop_pv {
710 0     0 0 0 my $op = shift;
711 0         0 my $sv;
712 0 0       0 if (!$op->can("sv")) {
713 0 0 0     0 if ($op->can('name') and $op->name eq 'padsv') {
714 0         0 my @c = comppadlist->ARRAY;
715 0         0 my @pad = $c[1]->ARRAY;
716 0 0 0     0 return $pad[$op->targ]->PV if $pad[$op->targ] and $pad[$op->targ]->can("PV");
717             # This might fail with B::NULL (optimized ex-const pv) entries in the pad.
718             }
719             # $op->can('pmreplroot') fails for 5.14
720 0 0 0     0 if (ref($op) eq 'B::PMOP' and $op->pmreplroot->can("sv")) {
721 0         0 $sv = $op->pmreplroot->sv;
722             } else {
723 0 0       0 return $package_pv unless $op->flags & 4;
724             # op->first is disallowed for !KIDS and OPpCONST_BARE
725 0 0 0     0 return $package_pv if $op->name eq 'const' and $op->flags & 64;
726 0 0       0 return $package_pv unless $op->first->can("sv");
727 0         0 $sv = $op->first->sv;
728             }
729             } else {
730 0         0 $sv = $op->sv;
731             }
732             # XXX see SvSHARED_HEK_FROM_PV for the stash in S_method_common pp_hot.c
733             # In this hash the CV is stored directly
734 0 0 0     0 if ($sv and $$sv) {
735             #if ($PERL510) { # PVX->hek_hash - STRUCT_OFFSET(struct hek, hek_key)
736             #} else { # UVX
737             #}
738 0 0       0 return $sv->PV if $sv->can("PV");
739 0 0       0 if (ref($sv) eq "B::SPECIAL") { # DateTime::TimeZone
740             # XXX null -> method_named
741 0 0       0 warn "NYI S_method_common op->sv==B::SPECIAL, keep $package_pv\n" if $debug{gv};
742 0         0 return $package_pv;
743             }
744 0 0       0 if ($sv->FLAGS & SVf_ROK) {
745 0 0       0 goto missing if $sv->isa("B::NULL");
746 0         0 my $rv = $sv->RV;
747 0 0       0 if ($rv->isa("B::PVGV")) {
748 0         0 my $o = $rv->IO;
749 0 0       0 return $o->STASH->NAME if $$o;
750             }
751 0 0       0 goto missing if $rv->isa("B::PVMG");
752 0         0 return $rv->STASH->NAME;
753             } else {
754             missing:
755 0 0       0 if ($op->name ne 'method_named') {
    0          
756             # Called from first const/padsv before method_named. no magic pv string, so a method arg.
757             # The first const pv as method_named arg is always the $package_pv.
758 0         0 return $package_pv;
759             } elsif ($sv->isa("B::IV")) {
760 0         0 warn sprintf("Experimentally try method_cv(sv=$sv,$package_pv) flags=0x%x",
761             $sv->FLAGS);
762             # XXX untested!
763 0         0 return svref_2object(method_cv($$sv, $package_pv));
764             }
765             }
766             } else {
767 0         0 my @c = comppadlist->ARRAY;
768 0         0 my @pad = $c[1]->ARRAY;
769 0 0 0     0 return $pad[$op->targ]->PV if $pad[$op->targ] and $pad[$op->targ]->can("PV");
770             }
771             }
772              
773             sub IsCOW {
774 0 0   0 0 0 if ($PERL522) {
775 0         0 return $_[0]->FLAGS & SVf_IsCOW;
776             }
777 0   0     0 return ($] >= 5.017008 and $_[0]->FLAGS & SVf_IsCOW); # since 5.17.8
778             }
779             sub IsCOW_hek {
780 0   0 0 0 0 return IsCOW($_[0]) && !$_[0]->LEN;
781             }
782              
783             if ($Config{usecperl} and $] >= 5.022002) {
784             eval q[sub isAvSTATIC {
785             my $flags = shift->FLAGS;
786             return !($flags & SVpav_REAL) && !($flags & SVpav_REIFY)
787             }];
788             } else {
789             eval q[sub isAvSTATIC () { 0 }];
790             }
791              
792             sub canAvSTATIC {
793 0     0 0 0 my ($av, $fullname) = @_;
794 0         0 my $flags = $av->FLAGS;
795 0         0 return 1;
796             }
797              
798             sub savesym {
799 0     0 0 0 my ( $obj, $value ) = @_;
800 55     55   322 no strict 'refs';
  55         66  
  55         3942  
801 0         0 my $sym = sprintf( "s\\_%x", $$obj );
802 0         0 $symtable{$sym} = $value;
803 0         0 return $value;
804             }
805              
806             sub objsym {
807 0     0 0 0 my $obj = shift;
808 55     55   222 no strict 'refs';
  55         75  
  55         17759  
809 0         0 return $symtable{ sprintf( "s\\_%x", $$obj ) };
810             }
811              
812             sub getsym {
813 0     0 0 0 my $sym = shift;
814 0         0 my $value;
815              
816 0 0       0 return 0 if $sym eq "sym_0"; # special case
817 0         0 $value = $symtable{$sym};
818 0 0       0 if ( defined($value) ) {
819 0         0 return $value;
820             }
821             else {
822 0 0       0 warn "warning: undefined symbol $sym\n" if $warn_undefined_syms;
823 0         0 return "UNUSED";
824             }
825             }
826              
827             sub delsym {
828 0     0 0 0 my ( $obj ) = @_;
829 0         0 my $sym = sprintf( "s\\_%x", $$obj );
830 0         0 delete $symtable{$sym};
831             }
832              
833 0     0 0 0 sub curcv { $B::C::curcv }
834 0     0 0 0 sub set_curcv($) { $B::C::curcv = shift; }
835              
836             # returns cstring, len, utf8 flags of a string
837             sub strlen_flags {
838 0     0 0 0 my $s = shift;
839 0         0 my ($len, $flags) = (0,"0");
840 0 0 0     0 if (!$PERL56 and utf8::is_utf8($s)) {
841 0         0 my $us = $s;
842 0         0 $flags = 'SVf_UTF8';
843 0         0 $len = utf8::upgrade($us);
844             } else {
845 0         0 $len = length $s;
846             }
847 0         0 return (cstring($s), $len, $flags);
848             }
849              
850             sub savestash_flags {
851 0     0 0 0 my ($name, $cstring, $len, $flags) = @_;
852 0 0       0 return $stashtable{$name} if exists $stashtable{$name};
853             #return '(HV*)&PL_sv_undef' if $name =~ /^(|B::CC?)$/; # protect against empty stashes
854 0 0       0 $flags = $flags ? "$flags|GV_ADD" : "GV_ADD";
855 0         0 my $sym = "hv$hv_index";
856 0         0 $decl->add("Static HV *$sym;");
857 0         0 $hv_index++;
858 0 0 0     0 if ($PERL518 and $name) { # since 5.18 save @ISA before calling stashpv
859 0         0 my @isa = get_isa($name);
860 55     55   236 no strict 'refs';
  55         67  
  55         46485  
861 0 0 0     0 if (@isa and exists ${$name.'::'}{ISA} ) {
  0         0  
862 0         0 svref_2object( \@{"$name\::ISA"} )->save("$name\::ISA");
  0         0  
863             }
864             }
865 0 0       0 my $pvsym = $len ? constpv($name) : '""';
866 0         0 $stashtable{$name} = $sym;
867 0         0 $init->add( sprintf( "%s = gv_stashpvn(%s, %u, %s); /* $name */",
868             $sym, $pvsym, $len, $flags));
869 0         0 return $sym;
870             }
871              
872             sub savestashpv {
873 0     0 0 0 my $name = shift;
874 0         0 return savestash_flags($name, strlen_flags($name));
875             }
876              
877             sub savere {
878 0     0 0 0 my $re = shift;
879 0   0     0 my $flags = shift || 0;
880 0         0 my $sym;
881 0         0 my $pv = $re;
882 0         0 my ($cstring, $cur, $utf8) = strlen_flags($pv);
883 0         0 my $len = 0; # static buffer
884 0 0       0 if ($PERL514) {
    0          
885 0         0 $xpvsect->add( sprintf( "Nullhv, {0}, %u, %u", $cur, $len ) );
886 0 0       0 $svsect->add( sprintf( "&xpv_list[%d], 1, %x, {%s}", $xpvsect->index,
887             0x4405, ($C99?".svu_pv=":"").'(char*)'.savepv($pv) ) );
888 0         0 $sym = sprintf( "&sv_list[%d]", $svsect->index );
889             }
890             elsif ($PERL510) {
891             # BUG! Should be the same as newSVpvn($resym, $relen) but is not
892             #$sym = sprintf("re_list[%d]", $re_index++);
893             #$resect->add(sprintf("0,0,0,%s", $cstring));
894 0 0       0 my $s1 = ($PERL514 ? "NULL," : "") . "{0}, %u, %u";
895 0         0 $xpvsect->add( sprintf( $s1, $cur, $len ) );
896 0 0       0 $svsect->add( sprintf( "&xpv_list[%d], 1, %x, {%s}", $xpvsect->index,
897             0x4405, ($C99?".svu_pv=":"").'(char*)'.savepv($pv) ) );
898 0         0 my $s = "sv_list[".$svsect->index."]";
899 0         0 $sym = "&$s";
900 0 0       0 push @B::C::static_free, $s if $len; # and $B::C::pv_copy_on_grow;
901             # $resect->add(sprintf("&xpv_list[%d], $u32fmt, 0x%x", $xpvsect->index, 1, 0x4405));
902             }
903             else {
904 0         0 $sym = sprintf( "re%d", $re_index++ );
905 0         0 $decl->add( sprintf( "Static const char *%s = %s;", $sym, $cstring ) );
906             }
907 0         0 return ( $sym, $cur );
908             }
909              
910             sub constpv {
911 0     0 0 0 return savepv(shift, 1);
912             }
913              
914             sub savepv {
915 0     0 0 0 my $pv = shift;
916 0         0 my $const = shift;
917 0         0 my ($cstring, $cur, $utf8) = strlen_flags($pv);
918             # $decl->add( sprintf( "/* %s */", $cstring) ) if $debug{pv};
919 0 0       0 return $strtable{$cstring} if defined $strtable{$cstring};
920 0         0 my $pvsym = sprintf( "pv%d", $pv_index++ );
921 0 0       0 $const = $const ? " const" : "";
922 0 0 0     0 if ( defined $max_string_len && $cur > $max_string_len ) {
923 0         0 my $chars = join ', ', map { cchar $_ } split //, pack("a*", $pv);
  0         0  
924 0         0 $decl->add( sprintf( "Static%s char %s[] = { %s };", $const, $pvsym, $chars ) );
925 0         0 $strtable{$cstring} = $pvsym;
926             } else {
927 0 0       0 if ( $cstring ne "0" ) { # sic
928 0         0 $decl->add( sprintf( "Static%s char %s[] = %s;", $const, $pvsym, $cstring ) );
929 0         0 $strtable{$cstring} = $pvsym;
930             }
931             }
932 0         0 return $pvsym;
933             }
934              
935             sub save_rv {
936 0     0 0 0 my ($sv, $fullname) = @_;
937 0 0       0 if (!$fullname) {
938 0         0 $fullname = '(unknown)';
939             }
940             # confess "Can't save RV: not ROK" unless $sv->FLAGS & SVf_ROK;
941             # 5.6: Can't locate object method "RV" via package "B::PVMG"
942             # since 5.11 it must be a PV, the RV was removed from the IV
943 0         0 my $rv;
944             #if ($] >= 5.011 and ref($sv) =~ /^B::[IP]V$/) {
945             # warn "$sv is no IV nor PV\n" if $debug{sv};
946             # $sv = bless $sv, 'B::PV'; # only observed with DB::args[0]
947             #}
948             #elsif ($] < 5.011 and ref($sv) =~ /^B::[RP]V$/) {
949             # warn "$sv is no RV nor PV\n" if $debug{sv};
950             # $sv = bless $sv, 'B::RV';
951             #}
952 0         0 $rv = $sv->RV->save($fullname);
953 0         0 $rv =~ s/^\(([AGHS]V|IO)\s*\*\)\s*(\&sv_list.*)$/$2/;
954              
955 0         0 return $rv;
956             }
957              
958             # => savesym, cur, len, pv, static, flags
959             sub save_pv_or_rv {
960 0     0 0 0 my ($sv, $fullname) = @_;
961              
962 0         0 my $flags = $sv->FLAGS;
963 0         0 my $rok = $flags & SVf_ROK;
964 0         0 my $pok = $flags & SVf_POK;
965 0         0 my $gmg = $flags & SVs_GMG;
966 0 0 0     0 my $iscow = (IsCOW($sv) or ($B::C::cow and $PERL518)) ? 1 : 0;
967             #my $wascow = IsCOW($sv) ? 1 : 0;
968 0         0 my ( $cur, $len, $savesym, $pv ) = ( 0, 1, 'NULL', "" );
969 0         0 my ($static, $shared_hek);
970             # overloaded VERSION symbols fail to xs boot: ExtUtils::CBuilder with Fcntl::VERSION (i91)
971             # 5.6: Can't locate object method "RV" via package "B::PV" Carp::Clan
972 0 0 0     0 if ($rok and !$PERL56) {
973             # this returns us a SV*. 5.8 expects a char* in xpvmg.xpv_pv
974 0 0       0 warn "save_pv_or_rv: save_rv(",$sv,")\n" if $debug{sv};
975 0 0       0 $savesym = ($PERL510 ? "" : "(char*)") . save_rv($sv, $fullname);
976 0         0 $static = 1; # avoid run-time overwrite of the PV/RV slot (#273)
977 0 0       0 if ($savesym =~ /get_cv/) { # Moose::Util::TypeConstraints::Builtins::_RegexpRef
978 0         0 $static = 0;
979 0         0 $pv = $savesym;
980 0         0 $savesym = 'NULL';
981             }
982             }
983             else {
984 0 0       0 if ($pok) {
985 0         0 $pv = pack "a*", $sv->PV; # XXX!
986 0 0 0     0 $cur = ($sv and $sv->can('CUR') and ref($sv) ne 'B::GV') ? $sv->CUR : length($pv);
987             # comppadname bug with overlong strings
988 0 0 0     0 if ($] < 5.008008 and $cur > 100 and $fullname =~ m/ :pad\[0\]/ and $pv =~ m/\0\0/) {
      0        
      0        
989 0         0 my $i = index($pv,"\0");
990 0 0       0 if ($i > -1) {
991 0         0 $pv = substr($pv,0,$i);
992 0         0 $cur = $i;
993 0 0       0 warn "Warning: stripped wrong comppad name for $fullname to ".cstring($pv)."\n"
994             if $verbose;
995             }
996             }
997             } else {
998 0 0 0     0 if ($gmg && $fullname) {
999 55     55   265 no strict 'refs';
  55         65  
  55         102147  
1000 0 0 0     0 $pv = ($fullname and ref($fullname)) ? "${$fullname}" : '';
  0         0  
1001 0         0 $cur = length (pack "a*", $pv);
1002 0         0 $pok = 1;
1003             } else {
1004 0         0 ($pv,$cur) = ("",0);
1005             }
1006             }
1007 0 0       0 $shared_hek = $PERL510 ? (($flags & 0x09000000) == 0x09000000) : undef;
1008 0 0       0 $shared_hek = $shared_hek ? 1 : IsCOW_hek($sv);
1009 0 0 0     0 $static = ($B::C::const_strings or $iscow or ($flags & SVf_READONLY))
1010             ? 1 : 0;
1011 0 0 0     0 $static = 0 if $shared_hek
      0        
      0        
1012             or ($fullname and ($fullname =~ m/ :pad/
1013             or ($fullname =~ m/^DynaLoader/ and $pv =~ m/^boot_/)));
1014 0 0 0     0 $static = 0 if $static and $pv =~ /::bootstrap$/;
1015 0 0 0     0 $static = 0 if $static and $] > 5.017 and ref($sv) eq 'B::PVMG'; # 242: e.g. $1
      0        
1016 0 0 0     0 $static = 0 if $static and $B::C::const_strings and $fullname and
      0        
      0        
      0        
1017             ($fullname =~ /^warnings::(Dead)?Bits/ or $fullname =~ /::AUTOLOAD$/);
1018 0 0 0     0 if ($shared_hek and $pok and !$cur) { #272 empty key
      0        
1019 0 0 0     0 warn "use emptystring for empty shared key $fullname\n" if $debug{pv} or $debug{hv};
1020 0 0       0 $savesym = "emptystring" unless $fullname =~ /unopaux_item.* const/;
1021 0         0 $static = 0;
1022             }
1023 0 0 0     0 if ($static and $PERL510) { # force dynamic PADNAME strings
1024 0 0 0     0 if ($] < 5.016) { $static = 0 if $flags & 0x40000000; } # SVpad_NAME
  0 0 0     0  
    0          
    0          
1025             # w. 5.18 even const and VERSION
1026             elsif ($] < 5.020 and $fullname =~ /(^svop const|::VERSION)$/) {
1027 0 0       0 warn "static=0 for $fullname\n" if $debug{pv};
1028 0         0 $static = 0;
1029             }
1030             elsif ($] < 5.022 and ($flags & 0x40008000 == 0x40008000)) { # SVpad_NAME
1031 0 0       0 warn "static=0 for SVpad_NAME $fullname\n" if $debug{pv};
1032 0         0 $static = 0;
1033             }
1034             }
1035 0 0       0 if ($pok) {
1036 0         0 my $s = "sv_list[" . ($svsect->index + 1) . "]";
1037             # static pv (!SvLEN) only valid since cd84013aab030da47b76a44fb3 (sv.c: !SvLEN does not mean undefined)
1038             # i.e. since v5.17.6. because conversion to IV would fail.
1039             # But a "" or "0" or "[a-z]+" string can have SvLEN=0
1040             # since its is converted to 0.
1041             # Only a readonly "" or "0" string can have SvLEN=0 since it's
1042             # converted to 0, which leads to the same result.
1043             # perlcc -O3 -r -e'print "ok" if 1 == "1"'
1044             # vs
1045             # perlcc -O2 -r -e'print "ok" if 1 == "1"'
1046             # ok
1047 0 0 0     0 if ($static and $] < 5.017006 and $pv !~ /^0?$/) {
      0        
1048 0         0 $static = 0;
1049             }
1050             # but we can optimize static set-magic ISA entries. #263, #91
1051 0 0 0     0 if ($B::C::const_strings and ref($sv) eq 'B::PVMG'
      0        
      0        
1052             and $flags & SVs_SMG and $fullname =~ /ISA/) {
1053 0         0 $static = 1; # warn "static $fullname";
1054             }
1055 0 0       0 if ($static) {
1056 0         0 $len = 0;
1057             #warn cstring($sv->PV)." $iscow $wascow";
1058 0 0 0     0 if ($iscow and $PERL518) { # 5.18 COW logic
1059 0 0       0 if ($B::C::Config::have_HEK_STATIC) {
    0          
1060 0         0 $iscow = 1;
1061 0         0 $shared_hek = 1;
1062             # $pv .= "\000\001";
1063 0         0 $savesym = save_hek($pv,$fullname,0);
1064             # warn "static shared hek: $savesym";
1065             # $savesym =~ s/&\(HEK\)(hek\d+)/&($1.hek_key)/;
1066             } elsif ($B::C::cow) {
1067             # wrong in many cases but saves a lot of memory, only do this with -O2
1068 0         0 $len = $cur+2;
1069 0         0 $pv .= "\000\001";
1070 0         0 $savesym = savepv($pv);
1071             } else {
1072 0         0 $iscow = 0;
1073 0         0 $savesym = constpv($pv);
1074             }
1075             } else {
1076 0         0 $savesym = constpv($pv);
1077             }
1078 0 0       0 if ($savesym =~ /\)?get_cv/) { # Moose::Util::TypeConstraints::Builtins::_RegexpRef
1079 0         0 $static = 0;
1080 0         0 $len = $cur +1;
1081 0         0 $pv = $savesym;
1082 0         0 $savesym = 'NULL';
1083             }
1084 0 0       0 if ($iscow) {
1085 0         0 $flags |= SVf_IsCOW;
1086             } else {
1087 0         0 $flags &= ~SVf_IsCOW;
1088             }
1089             #push @B::C::static_free, $savesym if $len and $savesym =~ /^pv/ and !$B::C::in_endav;
1090             } else {
1091 0         0 $len = $cur+1;
1092 0 0       0 if ($shared_hek) {
1093 0 0       0 if ($savesym eq "emptystring") {
1094 0         0 $free->add(" SvLEN(&$s) = 0;");
1095 0 0       0 $len = 0 if $PERL518;
1096             } else {
1097 0         0 $len = 0;
1098             }
1099 0         0 $free->add(" SvFAKE_off(&$s);");
1100             } else {
1101 0 0 0     0 if ($iscow and $cur and $PERL518) {
      0        
1102 0         0 $len++;
1103 0         0 $pv .= "\000\001";
1104 0         0 $flags |= SVf_IsCOW;
1105             }
1106             }
1107             }
1108             } else {
1109 0         0 $len = 0;
1110             }
1111             }
1112             #if ($iscow and $len and $PERL518) { # 5.18 COW logic
1113             # my $offset = $len % $Config{ptrsize};
1114             # $len += $Config{ptrsize} - $offset if $offset;
1115             #}
1116             warn sprintf("Saving pv as %s %s cur=%d, len=%d, static=%d cow=%d %s flags=0x%x\n",
1117             $savesym, cstring($pv), $cur, $len,
1118             $static, $iscow, $shared_hek ? "shared, $fullname" : $fullname, $flags)
1119 0 0       0 if $debug{pv};
    0          
1120 0         0 return ( $savesym, $cur, $len, $pv, $static, $flags );
1121             }
1122              
1123             # Shared global string in PL_strtab.
1124             # Mostly GvNAME and GvFILE, but also CV prototypes or bareword hash keys.
1125             # Note: currently not used in list context
1126             sub save_hek {
1127 0     0 0 0 my ($str, $fullname, $dynamic) = @_; # not cstring'ed
1128             # $dynamic: see lexsub CvNAME in CV::save
1129             # force empty string for CV prototypes
1130 0 0       0 return "NULL" unless defined $str;
1131 0 0 0     0 return "NULL" if $dynamic and !length $str and !@_
      0        
      0        
1132             and $fullname !~ /unopaux_item.* const/;
1133             # The first assigment is already refcount bumped, we have to manually
1134             # do it for all others
1135 0         0 my ($cstr, $cur, $utf8) = strlen_flags($str);
1136 0         0 my $hek_key = $str.":".$utf8;
1137 0 0 0     0 if ($dynamic and defined $hektable{$hek_key}) {
1138 0         0 return sprintf("share_hek_hek(%s)", $hektable{$hek_key});
1139             }
1140 0 0 0     0 if (!$dynamic and defined $statichektable{$hek_key}) {
1141 0         0 return $statichektable{$hek_key};
1142             }
1143 0 0       0 $cur = - $cur if $utf8;
1144 0 0       0 $cstr = '""' if $cstr eq "0";
1145 0         0 my $sym = sprintf( "hek%d", $hek_index++ );
1146 0 0       0 if (!$dynamic) {
1147 0         0 $statichektable{$hek_key} = $sym;
1148 0         0 my $key = $cstr;
1149 0         0 my $len = abs($cur);
1150             # strip CowREFCNT
1151 0 0       0 if ($key =~ /\\000\\001"$/) {
1152 0         0 $key =~ s/\\000\\001"$/"/;
1153 0         0 $len -= 2;
1154             }
1155             # add the flags. a static hek is unshared
1156 0 0       0 if (!$utf8) { # 0x88: HVhek_STATIC + HVhek_UNSHARED
1157 0         0 $key =~ s/"$/\\000\\210"/;
1158             } else { # 0x89: + HVhek_UTF8
1159 0         0 $key =~ s/"$/\\000\\211"/;
1160             }
1161             #warn sprintf("Saving static hek %s %s cur=%d\n", $sym, $cstr, $cur)
1162             # if $debug{pv};
1163             # not const because we need to set the HASH at init
1164 0         0 $decl->add(sprintf("Static struct hek_ptr %s = { %u, %d, %s};",
1165             $sym, 0, $len, $key));
1166 0         0 $init->add(sprintf("PERL_HASH(%s.hek_hash, %s.hek_key, %u);", $sym, $sym, $len));
1167             } else {
1168 0         0 $hektable{$hek_key} = $sym;
1169 0         0 $decl->add(sprintf("Static HEK *%s;", $sym));
1170             warn sprintf("Saving hek %s %s cur=%d\n", $sym, $cstr, $cur)
1171 0 0       0 if $debug{pv};
1172             # randomized global shared hash keys:
1173             # share_hek needs a non-zero hash parameter, unlike hv_store.
1174             # Vulnerable to oCERT-2011-003 style DOS attacks?
1175             # user-input (object fields) do not affect strtab, it is pretty safe.
1176             # But we need to randomize them to avoid run-time conflicts
1177             # e.g. "Prototype mismatch: sub bytes::length (_) vs (_)"
1178             #if (0 and $PERL510) { # no refcount
1179             # $init->add(sprintf("%s = my_share_hek_0(%s, %d);", $sym, $cstr, $cur));
1180             #} else { # vs. bump the refcount
1181 0         0 $init->add(sprintf("%s = share_hek(%s, %d);", $sym, $cstr, $cur));
1182             #}
1183             # protect against Unbalanced string table refcount warning with PERL_DESTRUCT_LEVEL=2
1184             # $free->add(" $sym = NULL;");
1185             }
1186 0         0 return $sym;
1187             }
1188              
1189             sub gv_fetchpvn {
1190 0     0 0 0 my ($name, $flags, $type) = @_;
1191 0 0       0 warn 'undefined flags' unless defined $flags;
1192 0 0       0 warn 'undefined type' unless defined $type;
1193 0         0 my ($cname, $cur, $utf8) = strlen_flags($name);
1194 0 0       0 if ($] >= 5.009002) {
1195 0 0       0 $flags .= length($flags) ? "|$utf8" : $utf8 if $utf8;
    0          
1196 0         0 return "gv_fetchpvn_flags($cname, $cur, $flags, $type)";
1197             } else {
1198 0         0 return "gv_fetchpv($cname, $flags, $type)";
1199             }
1200             }
1201              
1202             # get_cv() returns a CV*
1203             sub get_cv {
1204 0     0 0 0 my ($name, $flags) = @_;
1205 0 0       0 $name = "" if $name eq "__ANON__";
1206 0         0 my ($cname, $cur, $utf8) = strlen_flags($name);
1207 0 0       0 warn 'undefined flags' unless defined $flags;
1208 0 0       0 if ($] >= 5.009002) {
1209 0 0       0 $flags .= length($flags) ? "|$utf8" : $utf8 if $utf8;
    0          
1210 0         0 return qq[get_cvn_flags($cname, $cur, $flags)];
1211             } else {
1212 0         0 return qq[get_cv($cname, $flags)];
1213             }
1214             }
1215              
1216             sub ivx ($) {
1217 0     0 0 0 my $ivx = shift;
1218 0         0 my $ivdformat = $Config{ivdformat};
1219 0         0 $ivdformat =~ s/["\0]//g; #" poor editor
1220 0         0 $ivdformat =~ s/".$/"/; # cperl bug 5.22.2 #61 (never released)
1221 0 0       0 unless ($ivdformat) {
1222 0 0       0 $ivdformat = $Config{ivsize} == 4 ? 'd' : 'ld';
1223             }
1224 0         0 my $POW = ( $Config{ivsize} * 4 - 1 ); # poor editor
1225 0         0 my $intmax = (1 << $POW) - 1;
1226 0         0 my $L = 'L';
1227             # LL for 32bit -2147483648L or 64bit -9223372036854775808L
1228 0 0       0 $L = 'LL' if $Config{ivsize} == 2*$Config{ptrsize};
1229             # UL if > INT32_MAX = 2147483647
1230 0 0       0 my $sval = sprintf("%${ivdformat}%s", $ivx, $ivx > $intmax ? "U$L" : "");
1231 0 0       0 if ($ivx < -$intmax) {
1232 0         0 $sval = sprintf("%${ivdformat}%s", $ivx, 'LL'); # DateTime
1233             }
1234 0 0       0 if ($INC{'POSIX.pm'}) {
1235             # i262: LONG_MIN -9223372036854775808L integer constant is so large that it is unsigned
1236 0 0       0 if ($ivx == POSIX::LONG_MIN()) {
    0          
1237 0         0 $sval = "PERL_LONG_MIN";
1238             }
1239             elsif ($ivx == POSIX::LONG_MAX()) {
1240 0         0 $sval = "PERL_LONG_MAX";
1241             }
1242             #elsif ($ivx == POSIX::HUGE_VAL()) {
1243             # $sval = "HUGE_VAL";
1244             #}
1245             }
1246 0 0       0 $sval = '0' if $sval =~ /(NAN|inf)$/i;
1247 0         0 return $sval;
1248             #return $C99 ? ".xivu_uv = $sval" : $sval; # this is version dependent
1249             }
1250              
1251             # protect from warning: floating constant exceeds range of ‘double’ [-Woverflow]
1252             sub nvx ($) {
1253 0     0 0 0 my $nvx = shift;
1254              
1255             # Handle infinite and NaN values
1256 0 0       0 if ( defined $nvx ) {
1257 0 0 0     0 if ( $Config{d_isinf} or $] < 5.012 ) {
1258 0 0       0 return 'INFINITY' if $nvx =~ /^Inf/i;
1259 0 0       0 return '-INFINITY' if $nvx =~ /^-Inf/i;
1260             }
1261 0 0 0     0 return 'NAN' if $nvx =~ /^NaN/i and ($Config{d_isnan} or $] < 5.012);
      0        
1262             # TODO NANL for long double
1263             }
1264              
1265 0         0 my $nvgformat = $Config{nvgformat};
1266 0         0 $nvgformat =~ s/["\0]//g; #" poor editor
1267 0         0 $nvgformat =~ s/".$/"/; # cperl bug 5.22.2 #61
1268 0 0       0 unless ($nvgformat) {
1269 0         0 $nvgformat = 'g';
1270             }
1271 0         0 my $dblmax = "1.79769313486232e+308";
1272 0         0 my $ldblmax = "1.18973149535723176502e+4932";
1273 0 0       0 if ($nvgformat eq 'g') { # a very poor choice to keep precision
1274             # on intel 17-18, on ppc 31, on sparc64/s390 34
1275             # TODO: rather use the binary representation of our union
1276 0 0       0 $nvgformat = $Config{uselongdouble} ? '.18Lg' : '.17g';
1277             }
1278 0 0       0 my $sval = sprintf("%${nvgformat}%s", $nvx, $nvx > $dblmax ? "L" : "");
1279 0 0       0 $sval = sprintf("%${nvgformat}%s", $nvx, "L") if $nvx < -$dblmax;
1280 0 0       0 if ($INC{'POSIX.pm'}) {
1281 0 0       0 if ($nvx == POSIX::DBL_MIN()) {
    0          
1282 0         0 $sval = "DBL_MIN";
1283             }
1284             elsif ($nvx == POSIX::DBL_MAX()) { #1.797693134862316e+308
1285 0         0 $sval = "DBL_MAX";
1286             }
1287             }
1288             else {
1289 0 0       0 if ($nvx == $dblmax) {
1290 0         0 $sval = "DBL_MAX";
1291             }
1292             }
1293              
1294 0 0       0 if ($Config{d_longdbl}) {
1295 0         0 my $posix;
1296 0 0       0 if ($INC{'POSIX.pm'}) {
1297 0         0 eval { $posix = POSIX::LDBL_MIN(); };
  0         0  
1298             }
1299 0 0       0 if ($posix) { # linux does not have these, darwin does
    0          
1300 0 0       0 if ($nvx == $posix) {
    0          
1301 0         0 $sval = "NV_MIN";
1302             }
1303             elsif ($nvx == POSIX::LDBL_MAX()) {
1304 0         0 $sval = "NV_MAX";
1305             }
1306             } elsif ($nvx == $ldblmax) {
1307 0         0 $sval = "NV_MAX";
1308             }
1309             }
1310 0 0       0 $sval = '0' if $sval =~ /(NAN|inf)$/i;
1311 0 0       0 $sval .= '.00' if $sval =~ /^-?\d+$/;
1312 0         0 return $sval;
1313             }
1314              
1315             sub mg_RC_off {
1316 0     0 0 0 my ($mg, $sym, $type) = @_;
1317 0 0       0 warn "MG->FLAGS ",$mg->FLAGS," turn off MGf_REFCOUNTED\n" if $debug{mg};
1318 0 0       0 if (!ref $sym) {
1319 0         0 $init->add(sprintf("my_mg_RC_off(aTHX_ (SV*)$sym, %s);", cchar($type)));
1320             } else {
1321 0         0 $init->add(sprintf("my_mg_RC_off(aTHX_ (SV*)s\\_%x, %s);", $$sym, cchar($type)));
1322             }
1323             }
1324              
1325             # for bytes and utf8 only
1326             # TODO: Carp::Heavy, Exporter::Heavy
1327             # special case: warnings::register via -fno-warnings
1328             sub force_heavy {
1329 0     0 0 0 my $pkg = shift;
1330 0         0 my $pkg_heavy = $pkg."_heavy.pl";
1331 55     55   328 no strict 'refs';
  55         71  
  55         104086  
1332 0 0 0     0 if (!$include_package{$pkg_heavy} and !exists $savINC{$pkg_heavy}) {
1333             #eval qq[sub $pkg\::AUTOLOAD {
1334             # require '$pkg_heavy';
1335             # goto &\$AUTOLOAD if defined &\$AUTOLOAD;
1336             # warn("Undefined subroutine \$AUTOLOAD called");
1337             # }];
1338             #warn "Redefined $pkg\::AUTOLOAD to omit Carp\n" if $debug{gv};
1339 0 0       0 warn "Forcing early $pkg_heavy\n" if $debug{pkg};
1340 0         0 require $pkg_heavy;
1341 0         0 mark_package($pkg_heavy, 1);
1342             #walk_syms($pkg); #before we stub unloaded CVs
1343             }
1344 0         0 return svref_2object( \*{$pkg."::AUTOLOAD"} );
  0         0  
1345             }
1346              
1347             # See also init_op_ppaddr below; initializes the ppaddr to the
1348             # OpTYPE; init_op_ppaddr iterates over the ops and sets
1349             # op_ppaddr to PL_ppaddr[op_ppaddr]; this avoids an explicit assignment
1350             # in perl_init ( ~10 bytes/op with GCC/i386 )
1351             sub B::OP::fake_ppaddr {
1352 0     0   0 my $op = shift;
1353 0 0       0 return "NULL" unless $op->can('name');
1354 0 0       0 if ($op->type == $OP_CUSTOM) {
1355 0 0       0 return ( $verbose ? sprintf( "/*XOP %s*/NULL", $op->name) : "NULL" );
1356             }
1357 0 0       0 return $B::C::optimize_ppaddr
    0          
1358             ? sprintf( "INT2PTR(void*,OP_%s)", uc( $op->name ) )
1359             : ( $verbose ? sprintf( "/*OP_%s*/NULL", uc( $op->name ) ) : "NULL" );
1360             }
1361 0     0   0 sub B::FAKEOP::fake_ppaddr { "NULL" }
1362             # XXX HACK! duct-taping around compiler problems
1363 0     0   0 sub B::OP::isa { UNIVERSAL::isa(@_) } # walkoptree_slow misses that
1364 70218     70218   3959624 sub B::OP::can { UNIVERSAL::can(@_) }
1365 0     0   0 sub B::OBJECT::name { "" } # B misses that
1366             $isa_cache{'B::OBJECT::can'} = 'UNIVERSAL';
1367              
1368             # This pair is needed because B::FAKEOP::save doesn't scalar dereference
1369             # $op->next and $op->sibling
1370             my $opsect_common =
1371             "next, sibling, ppaddr, " . ( $MAD ? "madprop, " : "" ) . "targ, type, ";
1372             #$opsect_common =~ s/, sibling/, _OP_SIBPARENT_FIELDNAME/ if $] > 5.021007;
1373             $opsect_common =~ s/, sibling/, sibparent/ if $have_sibparent;
1374             {
1375              
1376             # For 5.8:
1377             # Current workaround/fix for op_free() trying to free statically
1378             # defined OPs is to set op_seq = -1 and check for that in op_free().
1379             # Instead of hardwiring -1 in place of $op->seq, we use $op_seq
1380             # so that it can be changed back easily if necessary. In fact, to
1381             # stop compilers from moaning about a U16 being initialised with an
1382             # uncast -1 (the printf format is %d so we can't tweak it), we have
1383             # to "know" that op_seq is a U16 and use 65535. Ugh.
1384              
1385             # For 5.9 the hard coded text is the values for op_opt and op_static in each
1386             # op. The value of op_opt is irrelevant, and the value of op_static needs to
1387             # be 1 to tell op_free that this is a statically defined op and that is
1388             # shouldn't be freed.
1389              
1390             # For 5.10 op_seq = -1 is gone, the temp. op_static also, but we
1391             # have something better, we can set op_latefree to 1, which frees the children
1392             # (e.g. savepvn), but not the static op.
1393              
1394             # 5.8: U16 op_seq;
1395             # 5.9.4: unsigned op_opt:1; unsigned op_static:1; unsigned op_spare:5;
1396             # 5.10: unsigned op_opt:1; unsigned op_latefree:1; unsigned op_latefreed:1; unsigned op_attached:1; unsigned op_spare:3;
1397             # 5.18: unsigned op_opt:1; unsigned op_slabbed:1; unsigned op_savefree:1; unsigned op_static:1; unsigned op_spare:3;
1398             # 5.19: unsigned op_opt:1; unsigned op_slabbed:1; unsigned op_savefree:1; unsigned op_static:1; unsigned op_folded:1; unsigned op_spare:2;
1399             # 5.21.2: unsigned op_opt:1; unsigned op_slabbed:1; unsigned op_savefree:1; unsigned op_static:1; unsigned op_folded:1; unsigned op_lastesib:1; unsigned op_spare:1;
1400             # 5.21.11: unsigned op_opt:1; unsigned op_slabbed:1; unsigned op_savefree:1; unsigned op_static:1; unsigned op_folded:1; unsigned op_moresib:1; unsigned op_spare:1;
1401             my $static;
1402             if ( $] < 5.009004 ) {
1403             $static = sprintf "%u", 65535;
1404             $opsect_common .= "seq";
1405             }
1406             elsif ( $] < 5.010 ) {
1407             $static = '0, 1, 0';
1408             $opsect_common .= "opt, static, spare";
1409             }
1410             elsif ($] < 5.017002) {
1411             $static = '0, 1, 0, 0, 0';
1412             $opsect_common .= "opt, latefree, latefreed, attached, spare";
1413             }
1414             elsif ($] < 5.017004) {
1415             $static = '0, 1, 0, 0, 0, 0, 0';
1416             $opsect_common .= "opt, latefree, latefreed, attached, slabbed, savefree, spare";
1417             }
1418             elsif ($] < 5.017006) {
1419             $static = '0, 1, 0, 0, 0, 0, 0';
1420             $opsect_common .= "opt, latefree, latefreed, attached, slabbed, savefree, spare";
1421             }
1422             elsif ($] < 5.019002) { # 90840c5d1d 5.17.6
1423             $static = '0, 0, 0, 1, 0';
1424             $opsect_common .= "opt, slabbed, savefree, static, spare";
1425             }
1426             elsif ($] < 5.021002) {
1427             $static = '0, 0, 0, 1, 0, 0';
1428             $opsect_common .= "opt, slabbed, savefree, static, folded, spare";
1429             }
1430             elsif ($] < 5.0210011) {
1431             $static = '0, 0, 0, 1, 0, %d, 0';
1432             $opsect_common .= "opt, slabbed, savefree, static, folded, lastsib, spare";
1433             }
1434             else {
1435             $static = '0, 0, 0, 1, 0, %d, 0';
1436             $opsect_common .= "opt, slabbed, savefree, static, folded, moresib, spare";
1437             }
1438              
1439             sub B::OP::_save_common_middle {
1440 0     0   0 my $op = shift;
1441 0 0       0 my $madprop = $MAD ? "0," : "";
1442 0         0 my $ret;
1443 0 0       0 if ($static =~ / %d,/) {
1444 0         0 my $has_sib;
1445 0 0       0 if (ref($op) eq 'B::FAKEOP') {
    0          
1446 0         0 $has_sib = 0;
1447             } elsif ($] < 5.0210011) {
1448 0         0 $has_sib = $op->lastsib;
1449             } else {
1450 0         0 $has_sib = $op->moresib;
1451             }
1452 0         0 $ret = sprintf( "%s, %s %u, %u, $static, 0x%x, 0x%x",
1453             $op->fake_ppaddr, $madprop, $op->targ, $op->type,
1454             $has_sib,
1455             $op->flags, $op->private );
1456             } else {
1457 0         0 $ret = sprintf( "%s, %s %u, %u, $static, 0x%x, 0x%x",
1458             $op->fake_ppaddr, $madprop, $op->targ, $op->type,
1459             $op->flags, $op->private );
1460             }
1461             # XXX maybe add a ix=opindex string for debugging if $debug{flags}
1462 0 0       0 if ($B::C::Config::have_op_rettype) {
1463 0         0 $ret .= sprintf(", 0x%x", $op->rettype);
1464             }
1465 0         0 $ret;
1466             }
1467             $opsect_common .= ", flags, private";
1468             if ($B::C::Config::have_op_rettype) {
1469             $opsect_common .= ", rettype";
1470             }
1471             }
1472              
1473             sub B::OP::_save_common {
1474 0     0   0 my $op = shift;
1475             # compile-time method_named packages are always const PV sM/BARE, they should be optimized.
1476             # run-time packages are in gvsv/padsv. This is difficult to optimize.
1477             # my Foo $obj = shift; $obj->bar(); # TODO typed $obj
1478             # entersub -> pushmark -> package -> args...
1479             # See perl -MO=Terse -e '$foo->bar("var")'
1480             # See also http://www.perl.com/pub/2000/06/dougpatch.html
1481             # XXX TODO 5.8 ex-gvsv
1482             # XXX TODO Check for method_named as last argument
1483 0 0 0     0 if ($op->type > 0 and
      0        
      0        
      0        
      0        
      0        
1484             $op->name eq 'entersub' and $op->first and $op->first->can('name') and
1485             $op->first->name eq 'pushmark' and
1486             # Foo->bar() compile-time lookup, 34 = BARE in all versions
1487             (($op->first->next->name eq 'const' and $op->first->next->flags == 34)
1488             or $op->first->next->name eq 'padsv' # or $foo->bar() run-time lookup
1489             or ($] < 5.010 and $op->first->next->name eq 'gvsv' and !$op->first->next->type # 5.8 ex-gvsv
1490             and $op->first->next->next->name eq 'const' and $op->first->next->next->flags == 34))
1491             ) {
1492 0         0 my $pkgop = $op->first->next;
1493 0 0 0     0 if ($] < 5.010 and !$op->first->next->type) { # 5.8 ex-gvsv
1494 0         0 $pkgop = $op->first->next->next;
1495             }
1496 0 0       0 warn "check package_pv ".$pkgop->name." for method_name\n" if $debug{cv};
1497 0         0 my $pv = svop_or_padop_pv($pkgop); # 5.13: need to store away the pkg pv
1498 0 0 0     0 if ($pv and $pv !~ /[! \(]/) {
1499 0         0 $package_pv = $pv;
1500 0         0 push_package($package_pv);
1501             } else {
1502             # mostly optimized-away padsv NULL pads with 5.8
1503 0 0       0 warn "package_pv for method_name not found\n" if $debug{cv};
1504             }
1505             }
1506 0 0       0 if ($op->type == $OP_CUSTOM) {
1507 0 0       0 warn sprintf("CUSTOM OP %s $op\n", $op->name) if $verbose;
1508             }
1509 0         0 $prev_op = $op;
1510 0         0 my $sibling;
1511 0 0 0     0 if ($have_sibparent and !$op->moresib) { # HAS_SIBLING
1512 0         0 $sibling = $op->parent;
1513 0 0 0     0 warn "sibparent ",$op->name," $sibling\n" if $verbose and $debug{op};
1514             } else {
1515 0         0 $sibling = $op->sibling;
1516             }
1517             return sprintf( "s\\_%x, s\\_%x, %s",
1518 0         0 ${ $op->next },
  0         0  
1519             $$sibling,
1520             $op->_save_common_middle
1521             );
1522             }
1523              
1524             sub B::OP::save {
1525 0     0   0 my ( $op, $level ) = @_;
1526 0         0 my $sym = objsym($op);
1527 0 0       0 return $sym if defined $sym;
1528 0 0       0 $level = 0 unless $level;
1529 0         0 my $type = $op->type;
1530 0 0       0 $nullop_count++ unless $type;
1531 0 0       0 if ( $type == $OP_THREADSV ) {
1532             # saves looking up ppaddr but it's a bit naughty to hard code this
1533 0         0 $init->add(sprintf( "(void)find_threadsv(%s);", cstring( $threadsv_names[ $op->targ ])));
1534             }
1535 0 0       0 if ( $type == $OP_UCFIRST ) {
1536 0         0 $B::C::fold = 1;
1537 0 0       0 if ($] >= 5.013009) {
1538 0 0       0 warn "enabling -ffold with ucfirst\n" if $verbose;
1539 0 0       0 require "utf8.pm" unless $savINC{"utf8.pm"};
1540 0         0 mark_package("utf8");
1541 0         0 load_utf8_heavy();
1542             }
1543             }
1544 0 0       0 if (ref($op) eq 'B::OP') { # check wrong BASEOPs
1545             # [perl #80622] Introducing the entrytry hack, needed since 5.12, fixed with 5.13.8 a425677
1546             # ck_eval upgrades the UNOP entertry to a LOGOP, but B gets us just a B::OP (BASEOP).
1547             # op->other points to the leavetry op, which is needed for the eval scope.
1548 0 0       0 if ($op->name eq 'entertry') {
1549 0 0       0 warn "[perl #80622] Upgrading entertry from BASEOP to LOGOP...\n" if $verbose;
1550 0         0 bless $op, 'B::LOGOP';
1551 0         0 return $op->save($level);
1552             }
1553             }
1554              
1555             # since 5.10 nullified cops free their additional fields
1556 0 0 0     0 if ( $PERL510 and !$type and $OP_COP{ $op->targ } ) {
      0        
1557 0 0       0 warn sprintf( "Null COP: %d\n", $op->targ ) if $debug{cops};
1558 0         0 if (0 and $optimize_cop) {
1559             # XXX when is the NULL COP save to skip?
1560             # unsafe after entersub, entereval, anoncode, sort block (pushmark pushmark)
1561             # Rather skip this with CC not with C because we need the context.
1562             # XXX we dont have the prevop, it can be any op type.
1563             if ($verbose or $debug{cops}) {
1564             my $prevop = getsym(sprintf("&op_list[%d]", $opsect->index));
1565             warn sprintf( "Skip Null COP: %d, prev=\\s%x\n",
1566             $op->targ, $prevop);
1567             }
1568             return savesym( $op, $op->next->save );
1569             }
1570 0 0 0     0 if ($ITHREADS and $] >= 5.017) {
    0 0        
    0 0        
    0          
    0          
1571 0         0 $copsect->comment(
1572             "$opsect_common, line, stashoff, file, hints, seq, warnings, hints_hash");
1573 0         0 $copsect->add(sprintf("%s, 0, 0, (char *)NULL, 0, 0, NULL, NULL",
1574             $op->_save_common));
1575             }
1576             elsif ($ITHREADS and $] >= 5.016) {
1577 0         0 $copsect->comment(
1578             "$opsect_common, line, stashpv, file, stashlen, hints, seq, warnings, hints_hash");
1579 0         0 $copsect->add(sprintf("%s, 0, (char *)NULL, NULL, 0, 0, 0, NULL, NULL",
1580             $op->_save_common));
1581             }
1582             elsif ($ITHREADS and $] >= 5.015004) {
1583 0         0 $copsect->comment(
1584             "$opsect_common, line, stash, file, hints, seq, warnings, hints_hash");
1585 0         0 $copsect->add(sprintf("%s, 0, (char *)NULL, NULL, 0, 0, NULL, NULL",
1586             $op->_save_common));
1587             }
1588             elsif ($PERL512) {
1589 0         0 $copsect->comment(
1590             "$opsect_common, line, stash, file, hints, seq, warnings, hints_hash");
1591 0 0       0 $copsect->add(sprintf("%s, 0, %s, NULL, 0, 0, NULL, NULL",
1592             $op->_save_common, $ITHREADS ? "(char *)NULL" : "Nullhv"));
1593             }
1594             elsif ($PERL510) {
1595 0         0 $copsect->comment("$opsect_common, line, label, seq, warn_int, hints_hash");
1596 0         0 $copsect->add(sprintf("%s, %u, NULL, " . "NULL, NULL, 0, " . "%u, %d, NULL",
1597             $op->_save_common, 0, 0, 0));
1598             }
1599             else {
1600 0         0 $copsect->comment(
1601             "$opsect_common, label, seq, arybase, line, warnings, hints_hash");
1602 0         0 $copsect->add(
1603             sprintf( "%s, NULL, NULL, NULL, 0, 0, 0, NULL", $op->_save_common ) );
1604             }
1605 0         0 my $ix = $copsect->index;
1606 0 0       0 $init->add( sprintf( "cop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1607             unless $B::C::optimize_ppaddr;
1608 0         0 savesym( $op, "(OP*)&cop_list[$ix]" );
1609             }
1610             else {
1611 0         0 $opsect->comment($opsect_common);
1612 0         0 $opsect->add( $op->_save_common );
1613              
1614 0 0       0 $opsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1615 0         0 my $ix = $opsect->index;
1616 0 0       0 $init->add( sprintf( "op_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1617             unless $B::C::optimize_ppaddr;
1618             warn( sprintf( " OP=%s targ=%d flags=0x%x private=0x%x\n",
1619 0 0       0 peekop($op), $op->targ, $op->flags, $op->private ) ) if $debug{op};
1620 0         0 savesym( $op, "&op_list[$ix]" );
1621             }
1622             }
1623              
1624             # needed for special GV logic: save only stashes for stashes
1625             package B::STASHGV;
1626             our @ISA = ('B::GV');
1627              
1628             package B::FAKEOP;
1629              
1630             our @ISA = qw(B::OP);
1631              
1632             sub new {
1633 0     0   0 my ( $class, %objdata ) = @_;
1634 0         0 bless \%objdata, $class;
1635             }
1636              
1637             sub save {
1638 0     0   0 my ( $op, $level ) = @_;
1639 0         0 $opsect->add(
1640             sprintf( "%s, %s, %s", $op->next, $op->sibling, $op->_save_common_middle )
1641             );
1642 0         0 my $ix = $opsect->index;
1643 0 0       0 $init->add( sprintf( "op_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1644             unless $B::C::optimize_ppaddr;
1645 0         0 return "&op_list[$ix]";
1646             }
1647              
1648             *_save_common_middle = \&B::OP::_save_common_middle;
1649 0 0   0   0 sub next { $_[0]->{"next"} || 0 }
1650 0 0   0   0 sub type { $_[0]->{type} || 0 }
1651 0 0   0   0 sub sibling { $_[0]->{sibling} || 0 }
1652 0 0   0   0 sub moresib { $_[0]->{moresib} || 0 }
1653 0 0   0   0 sub parent { $_[0]->{parent} || 0 }
1654 0 0   0   0 sub ppaddr { $_[0]->{ppaddr} || 0 }
1655 0 0   0   0 sub targ { $_[0]->{targ} || 0 }
1656 0 0   0   0 sub flags { $_[0]->{flags} || 0 }
1657 0 0   0   0 sub private { $_[0]->{private} || 0 }
1658 0 0   0   0 sub rettype { $_[0]->{rettype} || 0 }
1659              
1660             package B::C;
1661              
1662             # dummy for B::C, only needed for B::CC
1663       0 0   sub label {}
1664              
1665             # save alternate ops if defined, and also add labels (needed for B::CC)
1666             sub do_labels ($$@) {
1667 0     0 0 0 my $op = shift;
1668 0         0 my $level = shift;
1669 0         0 for my $m (@_) {
1670 55     55   295 no strict 'refs';
  55         92  
  55         146331  
1671 0 0       0 my $mo = $op->$m if $m;
1672 0 0 0     0 if ( $mo and $$mo ) {
1673 0         0 label($mo);
1674 0 0 0     0 $mo->save($level) if $m ne 'first'
      0        
      0        
1675             or ($op->flags & 4
1676             and !($op->name eq 'const' and $op->flags & 64)); #OPpCONST_BARE has no first
1677             }
1678             }
1679             }
1680              
1681             sub B::UNOP::save {
1682 0     0   0 my ( $op, $level ) = @_;
1683 0         0 my $sym = objsym($op);
1684 0 0       0 return $sym if defined $sym;
1685 0 0       0 $level = 0 unless $level;
1686 0         0 $unopsect->comment("$opsect_common, first");
1687 0         0 $unopsect->add( sprintf( "%s, s\\_%x", $op->_save_common, ${ $op->first } ) );
  0         0  
1688 0 0       0 $unopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1689 0         0 my $ix = $unopsect->index;
1690 0 0       0 $init->add( sprintf( "unop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1691             unless $B::C::optimize_ppaddr;
1692 0         0 $sym = savesym( $op, "(OP*)&unop_list[$ix]" );
1693 0 0 0     0 if ($op->name eq 'method' and $op->first and $op->first->name eq 'const') {
      0        
1694 0         0 my $method = svop_name($op->first);
1695 0 0 0     0 if (!$method and $ITHREADS) {
1696 0         0 $method = padop_name($op->first, curcv); # XXX (curpad[targ])
1697             }
1698 0 0 0     0 warn "method -> const $method\n" if $debug{pkg} and $ITHREADS;
1699             #324,#326 need to detect ->(maybe::next|maybe|next)::(method|can)
1700 0 0       0 if ($method =~ /^(maybe::next|maybe|next)::(method|can)$/) {
    0          
1701 0 0       0 warn "mark \"$1\" for method $method\n" if $debug{pkg};
1702 0         0 mark_package($1, 1);
1703 0         0 mark_package("mro", 1);
1704             } # and also the old 5.8 NEXT|EVERY with non-fixed method names und subpackages
1705             elsif ($method =~ /^(NEXT|EVERY)::/) {
1706 0 0       0 warn "mark \"$1\" for method $method\n" if $debug{pkg};
1707 0         0 mark_package($1, 1);
1708 0 0       0 mark_package("NEXT", 1) if $1 ne "NEXT";
1709             }
1710             }
1711 0         0 do_labels ($op, $level+1, 'first');
1712 0         0 $sym;
1713             }
1714              
1715             sub is_constant {
1716 0     0 0 0 my $s = shift;
1717 0 0       0 return 1 if $s =~ /^(&sv_list|\-?\d+|Nullsv)/; # not gv_list, hek
1718 0         0 return 0;
1719             }
1720              
1721             sub B::UNOP_AUX::save {
1722 0     0   0 my ( $op, $level ) = @_;
1723 0         0 my $sym = objsym($op);
1724 0 0       0 return $sym if defined $sym;
1725 0 0       0 $level = 0 unless $level;
1726 0 0       0 my @aux_list = $op->name eq 'multideref'
1727             ? $op->aux_list_thr # our own version. GH#283, GH#341
1728             : $op->aux_list;
1729 0         0 my $auxlen = scalar @aux_list;
1730 0         0 $unopauxsect->comment("$opsect_common, first, aux");
1731 0         0 my $ix = $unopauxsect->index + 1;
1732             $unopauxsect->add(
1733             sprintf("%s, s\\_%x, %s+1",
1734 0         0 $op->_save_common, ${ $op->first }, "unopaux_item${ix}"));
  0         0  
1735 0 0       0 $unopauxsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1736             # This cannot be a section, as the number of elements is variable
1737 0         0 my $i = 1;
1738 0 0       0 my $s = "Static UNOP_AUX_item unopaux_item".$ix."[] = { /* ".$op->name." */\n\t"
1739             .($C99?"{.uv=$auxlen}":$auxlen). " \t/* length prefix */\n";
1740 0         0 my $action = 0;
1741 0         0 for my $item (@aux_list) {
1742 0 0       0 unless (ref $item) {
1743             # symbolize MDEREF and SIGNATURE actions and flags, just for the comments
1744 0         0 my $cmt = 'action';
1745 0 0       0 if ($verbose) {
1746 0 0       0 if ($op->name eq 'multideref') {
    0          
1747 0         0 my $act = $item & 0xf; # MDEREF_ACTION_MASK
1748 0 0       0 $cmt = 'AV_pop_rv2av_aelem' if $act == 1;
1749 0 0       0 $cmt = 'AV_gvsv_vivify_rv2av_aelem' if $act == 2;
1750 0 0       0 $cmt = 'AV_padsv_vivify_rv2av_aelem' if $act == 3;
1751 0 0       0 $cmt = 'AV_vivify_rv2av_aelem' if $act == 4;
1752 0 0       0 $cmt = 'AV_padav_aelem' if $act == 5;
1753 0 0       0 $cmt = 'AV_gvav_aelem' if $act == 6;
1754 0 0       0 $cmt = 'HV_pop_rv2hv_helem' if $act == 8;
1755 0 0       0 $cmt = 'HV_gvsv_vivify_rv2hv_helem' if $act == 9;
1756 0 0       0 $cmt = 'HV_padsv_vivify_rv2hv_helem' if $act == 10;
1757 0 0       0 $cmt = 'HV_vivify_rv2hv_helem' if $act == 11;
1758 0 0       0 $cmt = 'HV_padhv_helem' if $act == 12;
1759 0 0       0 $cmt = 'HV_gvhv_helem' if $act == 13;
1760 0         0 my $idx = $item & 0x30; # MDEREF_INDEX_MASK
1761 0 0       0 $cmt .= '' if $idx == 0x0;
1762 0 0       0 $cmt .= ' INDEX_const' if $idx == 0x10;
1763 0 0       0 $cmt .= ' INDEX_padsv' if $idx == 0x20;
1764 0 0       0 $cmt .= ' INDEX_gvsv' if $idx == 0x30;
1765             }
1766             elsif ($op->name eq 'signature') {
1767 0         0 my $act = $item & 0xf; # SIGNATURE_ACTION_MASK
1768 0 0       0 $cmt = 'reload' if $act == 0;
1769 0 0       0 $cmt = 'end' if $act == 1;
1770 0 0       0 $cmt = 'padintro' if $act == 2;
1771 0 0       0 $cmt = 'arg' if $act == 3;
1772 0 0       0 $cmt = 'arg_default_none' if $act == 4;
1773 0 0       0 $cmt = 'arg_default_undef' if $act == 5;
1774 0 0       0 $cmt = 'arg_default_0' if $act == 6;
1775 0 0       0 $cmt = 'arg_default_1' if $act == 7;
1776 0 0       0 $cmt = 'arg_default_iv' if $act == 8;
1777 0 0       0 $cmt = 'arg_default_const' if $act == 9;
1778 0 0       0 $cmt = 'arg_default_padsv' if $act == 10;
1779 0 0       0 $cmt = 'arg_default_gvsv' if $act == 11;
1780 0 0       0 $cmt = 'arg_default_op' if $act == 12;
1781 0 0       0 $cmt = 'array' if $act == 13;
1782 0 0       0 $cmt = 'hash' if $act == 14;
1783 0         0 my $idx = $item & 0x3F; # SIGNATURE_MASK
1784 0 0       0 $cmt .= '' if $idx == 0x0;
1785 0 0       0 $cmt .= ' flag skip' if $idx == 0x10;
1786 0 0       0 $cmt .= ' flag ref' if $idx == 0x20;
1787             } else {
1788 0         0 die "Unknown UNOP_AUX op {$op->name}";
1789             }
1790             }
1791 0         0 $action = $item;
1792 0 0       0 warn "{$op->name} action $action $cmt\n" if $debug{hv};
1793 0 0       0 $s .= ($C99 ? sprintf("\t,{.uv=0x%x} \t/* %s: %u */\n", $item, $cmt, $item)
1794             : sprintf("\t,0x%x \t/* %s: %u */\n", $item, $cmt, $item));
1795             } else {
1796             # const and sv already at compile-time, gv deferred to init-time.
1797             # testcase: $a[-1] -1 as B::IV not as -1
1798             # hmm, if const ensure that candidate CONSTs have been HEKified. (pp_multideref assertion)
1799             # || SvTYPE(keysv) >= SVt_PVMG
1800             # || !SvOK(keysv)
1801             # || SvROK(keysv)
1802             # || SvIsCOW_shared_hash(keysv));
1803 0 0       0 my $constkey = ($action & 0x30) == 0x10 ? 1 : 0;
1804 0 0       0 my $itemsym = $item->save("unopaux_item".$ix."[".$i."]" . ($constkey ? " const" : ""));
1805 0 0       0 if (is_constant($itemsym)) {
1806 0 0       0 if (ref $item eq 'B::IV') {
    0          
1807 0         0 my $iv = $item->IVX;
1808 0 0       0 $s .= ($C99 ? "\t,{.iv=$iv}\n"
1809             : "\t,PTR2IV($iv)\n");
1810             } elsif (ref $item eq 'B::UV') { # also for PAD_OFFSET
1811 0         0 my $uv = $item->UVX;
1812 0 0       0 $s .= ($C99 ? "\t,{.uv=$uv}\n"
1813             : "\t,PTR2IV($uv)\n");
1814             } else { # SV
1815 0 0       0 $s .= ($C99 ? "\t,{.sv=$itemsym}\n"
1816             : "\t,PTR2UV($itemsym)\n");
1817             }
1818             } else {
1819             # gv or other late inits
1820 0 0       0 $s .= ($C99 ? "\t,{.sv=Nullsv} \t/* $itemsym */\n"
1821             : "\t,0 \t/* $itemsym */\n");
1822 0         0 $init->add("unopaux_item".$ix."[".$i."].sv = (SV*)$itemsym;");
1823             }
1824             }
1825 0         0 $i++;
1826             }
1827 0         0 $decl->add($s."};");
1828 0 0       0 $init->add( sprintf( "unopaux_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1829             unless $B::C::optimize_ppaddr;
1830 0         0 $sym = savesym( $op, "(OP*)&unopaux_list[$ix]" );
1831 0         0 push @B::C::static_free, $sym;
1832             # $free->add(" ($sym)->op_type = OP_NULL;");
1833 0         0 do_labels ($op, $level+1, 'first');
1834 0         0 $sym;
1835             }
1836              
1837             # cannot save it statically in a sect. need the class (ref) and the ppaddr
1838             #sub B::XOP::save {
1839             # my ( $op, $level ) = @_;
1840             # my $sym = objsym($op);
1841             # return $sym if defined $sym;
1842             # # which class
1843             # $binopsect->comment("$opsect_common, first, last");
1844             # $binopsect->add(
1845             # sprintf( "%s, s\\_%x, s\\_%x",
1846             # $op->_save_common,
1847             # ${ $op->first },
1848             # ${ $op->last } ));
1849             # $binopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1850             # my $ix = $binopsect->index;
1851             # $init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1852             # unless $B::C::optimize_ppaddr;
1853             # $sym = savesym( $op, "(OP*)&binop_list[$ix]" );
1854             # do_labels ($op, $level+1, 'first', 'last');
1855             # $sym;
1856             #}
1857              
1858             sub B::BINOP::save {
1859 0     0   0 my ( $op, $level ) = @_;
1860 0         0 my $sym = objsym($op);
1861 0 0       0 return $sym if defined $sym;
1862             #return B::XOP::save(@_) if $op->type == $OP_CUSTOM;
1863              
1864 0 0       0 $level = 0 unless $level;
1865 0         0 $binopsect->comment("$opsect_common, first, last");
1866             $binopsect->add(
1867             sprintf( "%s, s\\_%x, s\\_%x",
1868             $op->_save_common,
1869 0         0 ${ $op->first },
1870 0         0 ${ $op->last } ));
  0         0  
1871 0 0       0 $binopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1872 0         0 my $ix = $binopsect->index;
1873 0         0 my $ppaddr = $op->ppaddr;
1874 0 0       0 if ($op->type == $OP_CUSTOM) {
1875 0         0 my $ptr = $$op;
1876 0 0 0     0 if ($] >= 5.019003 and ($op->name eq 'Devel_Peek_Dump' or $op->name eq 'Dump')){
      0        
1877 0 0       0 warn "custom op Devel_Peek_Dump\n" if $verbose;
1878 0 0       0 $decl->add('
1879             static void
1880             S_do_dump(pTHX_ SV *const sv, I32 lim)
1881             {
1882             dVAR;
1883             SV *pv_lim_sv = get_svs("Devel::Peek::pv_limit", 0);
1884             const STRLEN pv_lim = pv_lim_sv ? SvIV(pv_lim_sv) : 0;
1885             SV *dumpop = get_svs("Devel::Peek::dump_ops", 0);
1886             const U16 save_dumpindent = PL_dumpindent;
1887             PL_dumpindent = 2;
1888             do_sv_dump(0, Perl_debug_log, sv, 0, lim,
1889             (bool)(dumpop && SvTRUE(dumpop)), pv_lim);
1890             PL_dumpindent = save_dumpindent;
1891             }
1892             static OP *
1893             S_pp_dump(pTHX)
1894             {
1895             dSP;
1896             const I32 lim = PL_op->op_private == 2 ? (I32)POPi : 4;
1897             dPOPss;
1898             S_do_dump(aTHX_ sv, lim);
1899             RETPUSHUNDEF;
1900             }') unless $B::C::Devel_Peek_Dump_added;
1901 0         0 $ppaddr = 'S_pp_dump';
1902 0         0 $B::C::Devel_Peek_Dump_added++;
1903 0         0 $init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $ppaddr ));
1904             } else {
1905 0 0       0 warn "Warning: Unknown custom op ".$op->name."\n" if $verbose;
1906 0         0 $ppaddr = sprintf('Perl_custom_op_xop(aTHX_ INT2PTR(OP*, 0x%x))', $$op);
1907 0         0 $init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $ppaddr ));
1908             }
1909             } else {
1910 0 0       0 $init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $ppaddr ) )
1911             unless $B::C::optimize_ppaddr;
1912             }
1913 0         0 $sym = savesym( $op, "(OP*)&binop_list[$ix]" );
1914 0         0 do_labels ($op, $level+1, 'first', 'last');
1915 0         0 $sym;
1916             }
1917              
1918             sub B::LISTOP::save {
1919 0     0   0 my ( $op, $level ) = @_;
1920 0         0 my $sym = objsym($op);
1921 0 0       0 return $sym if defined $sym;
1922 0 0       0 $level = 0 unless $level;
1923 0         0 $listopsect->comment("$opsect_common, first, last");
1924             $listopsect->add(
1925             sprintf( "%s, s\\_%x, s\\_%x",
1926             $op->_save_common,
1927 0         0 ${ $op->first },
1928 0         0 ${ $op->last } ));
  0         0  
1929 0 0       0 $listopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1930 0         0 my $ix = $listopsect->index;
1931 0 0       0 $init->add( sprintf( "listop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1932             unless $B::C::optimize_ppaddr;
1933 0         0 $sym = savesym( $op, "(OP*)&listop_list[$ix]" );
1934 0 0 0     0 if ($op->type == $OP_DBMOPEN) {
    0          
1935             # resolves it at compile-time, not at run-time
1936 0         0 mark_package('AnyDBM_File'); # to save $INC{AnyDBM_File}
1937 0 0       0 require AnyDBM_File unless $savINC{'AnyDBM_File.pm'};
1938 0         0 $curINC{'AnyDBM_File.pm'} = $INC{'AnyDBM_File.pm'};
1939 0         0 AnyDBM_File->import; # strip the @ISA
1940 0         0 my $dbm = $AnyDBM_File::ISA[0]; # take the winner (only)
1941 0         0 svref_2object( \&{"$dbm\::bootstrap"} )->save;
  0         0  
1942 0         0 svref_2object( \&{"$dbm\::TIEHASH"} )->save; # called by pp_dbmopen
  0         0  
1943 0         0 $curINC{$dbm.".pm"} = $INC{$dbm.".pm"};
1944             } elsif ($op->type == $OP_FORMLINE and $B::C::const_strings) { # -O3 ~
1945             # non-static only for all const strings containing ~ #277
1946 0         0 my $sv;
1947 0         0 my $fop = $op;
1948 0         0 my $svop = $op->first;
1949 0   0     0 while ($svop != $op and ref($svop) ne 'B::NULL') {
1950 0 0 0     0 if ($svop->name eq 'const' and $svop->can('sv')) {
1951 0         0 $sv = $svop->sv;
1952             }
1953 0 0 0     0 if ($sv and $sv->can("PV") and $sv->PV and $sv->PV =~ /~/m) {
      0        
      0        
1954 0         0 local $B::C::const_strings;
1955 0 0       0 warn "force non-static formline arg ",cstring($sv->PV),"\n" if $debug{pv};
1956 0         0 $svop->save($level, "svop const");
1957             }
1958 0         0 $svop = $svop->next;
1959             }
1960             }
1961 0         0 do_labels ($op, $level+1, 'first', 'last');
1962 0         0 $sym;
1963             }
1964              
1965             sub B::LOGOP::save {
1966 0     0   0 my ( $op, $level ) = @_;
1967 0         0 my $sym = objsym($op);
1968 0 0       0 return $sym if defined $sym;
1969 0 0       0 $level = 0 unless $level;
1970 0         0 $logopsect->comment("$opsect_common, first, other");
1971             $logopsect->add(
1972             sprintf( "%s, s\\_%x, s\\_%x",
1973             $op->_save_common,
1974 0         0 ${ $op->first },
1975 0         0 ${ $op->other } ));
  0         0  
1976 0 0       0 $logopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1977 0         0 my $ix = $logopsect->index;
1978 0 0       0 $init->add( sprintf( "logop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1979             unless $B::C::optimize_ppaddr;
1980 0         0 $sym = savesym( $op, "(OP*)&logop_list[$ix]" );
1981 0         0 do_labels ($op, $level+1, 'first', 'other');
1982 0         0 $sym;
1983             }
1984              
1985             sub B::LOOP::save {
1986 0     0   0 my ( $op, $level ) = @_;
1987 0         0 my $sym = objsym($op);
1988 0 0       0 return $sym if defined $sym;
1989              
1990 0 0       0 $level = 0 unless $level;
1991             #warn sprintf("LOOP: redoop %s, nextop %s, lastop %s\n",
1992             # peekop($op->redoop), peekop($op->nextop),
1993             # peekop($op->lastop)) if $debug{op};
1994 0         0 $loopsect->comment("$opsect_common, first, last, redoop, nextop, lastop");
1995             $loopsect->add(
1996             sprintf(
1997             "%s, s\\_%x, s\\_%x, s\\_%x, s\\_%x, s\\_%x",
1998             $op->_save_common,
1999 0         0 ${ $op->first },
2000 0         0 ${ $op->last },
2001 0         0 ${ $op->redoop },
2002 0         0 ${ $op->nextop },
2003 0         0 ${ $op->lastop }
  0         0  
2004             )
2005             );
2006 0 0       0 $loopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2007 0         0 my $ix = $loopsect->index;
2008 0 0       0 $init->add( sprintf( "loop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2009             unless $B::C::optimize_ppaddr;
2010 0         0 $sym = savesym( $op, "(OP*)&loop_list[$ix]" );
2011 0         0 do_labels($op, $level+1, qw(first last redoop nextop lastop));
2012 0         0 $sym;
2013             }
2014              
2015             sub B::METHOP::save {
2016 0     0   0 my ( $op, $level ) = @_;
2017 0         0 my $sym = objsym($op);
2018 0 0       0 return $sym if defined $sym;
2019 0 0       0 $level = 0 unless $level;
2020 0         0 $methopsect->comment("$opsect_common, first, rclass");
2021 0 0       0 my $union = $op->name eq 'method' ? "{.op_first=(OP*)%s}" : "{.op_meth_sv=(SV*)%s}";
2022 0 0       0 $union = "%s" unless $C99;
2023 0 0       0 my $s = "%s, $union, ". ($ITHREADS ? "(PADOFFSET)%s" : "(SV*)%s"); # rclass
2024 0         0 my $ix = $methopsect->index + 1;
2025 0 0       0 my $rclass = $ITHREADS ? $op->rclass : $op->rclass->save("op_rclass_sv");
2026 0 0       0 if ($rclass =~ /^&sv_list/) {
2027 0         0 $init->add( sprintf( "SvREFCNT_inc_simple_NN(%s); /* methop_list[%d].op_rclass_sv */",
2028             $rclass, $ix ));
2029             # Put this simple PV into the PL_stashcache, it has no STASH,
2030             # and initialize the method cache.
2031             # TODO: backref magic for next, init the next::method cache
2032 0         0 $init->add( sprintf( "Perl_mro_method_changed_in(aTHX_ gv_stashsv(%s, GV_ADD));",
2033             $rclass ));
2034             }
2035 0 0       0 my $first = $op->name eq 'method' ? $op->first->save : $op->meth_sv->save;
2036 0 0       0 if ($first =~ /^&sv_list/) {
2037 0         0 $init->add( sprintf( "SvREFCNT_inc_simple_NN(%s); /* methop_list[%d].op_meth_sv */",
2038             $first, $ix ));
2039             }
2040 0 0 0     0 $first = 'NULL' if !$C99 and $first eq 'Nullsv';
2041 0         0 $methopsect->add(sprintf($s, $op->_save_common, $first, $rclass));
2042 0 0       0 $methopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2043 0 0       0 $init->add( sprintf( "methop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2044             unless $B::C::optimize_ppaddr;
2045 0         0 $sym = savesym( $op, "(OP*)&methop_list[$ix]" );
2046 0 0       0 if ($op->name eq 'method') {
2047 0         0 do_labels($op, $level+1, 'first', 'rclass');
2048             } else {
2049 0         0 do_labels($op, $level+1, 'meth_sv', 'rclass');
2050             }
2051 0         0 $sym;
2052             }
2053              
2054             sub B::PVOP::save {
2055 0     0   0 my ( $op, $level ) = @_;
2056 0         0 my $sym = objsym($op);
2057 0 0       0 return $sym if defined $sym;
2058 0 0       0 $level = 0 unless $level;
2059             # op_pv must be dynamic
2060 0         0 $pvopsect->comment("$opsect_common, pv");
2061 0         0 $pvopsect->add( sprintf( "%s, NULL", $op->_save_common ) );
2062 0 0       0 $pvopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2063 0         0 my $ix = $pvopsect->index;
2064 0 0       0 $init->add( sprintf( "pvop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2065             unless $B::C::optimize_ppaddr;
2066 0         0 my ($cstring,$cur,$utf8) = strlen_flags($op->pv); # utf8 in op_private as OPpPV_IS_UTF8 (0x80)
2067             # do not use savepvn here #362
2068 0         0 $init->add( sprintf( "pvop_list[%d].op_pv = savesharedpvn(%s, %u);", $ix, $cstring, $cur ));
2069 0         0 savesym( $op, "(OP*)&pvop_list[$ix]" );
2070             }
2071              
2072             # XXX Until we know exactly the package name for a method_call
2073             # we improve the method search heuristics by maintaining this mru list.
2074             sub push_package ($) {
2075 0 0   0 0 0 my $p = shift or return;
2076 0         0 warn "save package_pv \"$package_pv\" for method_name from @{[(caller(1))[3]]}\n"
2077 0 0 0     0 if $debug{cv} or $debug{pkg} and !grep { $p eq $_ } @package_pv;
  0   0     0  
2078 0 0       0 @package_pv = grep { $p ne $_ } @package_pv if @package_pv; # remove duplicates at the end
  0         0  
2079 0         0 unshift @package_pv, $p; # prepend at the front
2080 0         0 mark_package($p);
2081             }
2082              
2083             # method_named is in 5.6.1
2084             sub method_named {
2085 0     0 0 0 my $name = shift;
2086 0 0       0 return unless $name;
2087 0         0 my $cop = shift;
2088 0 0       0 my $loc = $cop ? " at ".$cop->file." line ".$cop->line : "";
2089             # Note: the pkg PV is unacessible(?) at PL_stack_base+TOPMARK+1.
2090             # But it is also at the const or padsv after the pushmark, before all args.
2091             # See L
2092             # We check it in op->_save_common
2093 0 0       0 if (ref($name) eq 'B::CV') {
2094 0         0 warn $name;
2095 0         0 return $name;
2096             }
2097 0         0 my $method;
2098 0         0 for ($package_pv, @package_pv, 'main') {
2099 55     55   302 no strict 'refs';
  55         75  
  55         657008  
2100 0 0       0 next unless defined $_;
2101 0         0 $method = $_ . '::' . $name;
2102 0 0       0 if (defined(&$method)) {
2103 0 0       0 warn sprintf( "Found &%s::%s\n", $_, $name ) if $debug{cv};
2104 0         0 $include_package{$_} = 1; # issue59
2105 0         0 mark_package($_, 1);
2106 0         0 last;
2107             } else {
2108 0 0       0 if (my $parent = try_isa($_,$name)) {
2109 0 0       0 warn sprintf( "Found &%s::%s\n", $parent, $name ) if $debug{cv};
2110 0         0 $method = $parent . '::' . $name;
2111 0         0 $include_package{$parent} = 1;
2112 0         0 last;
2113             }
2114 0 0       0 warn "no definition for method_name \"$method\"\n" if $debug{cv};
2115             }
2116             }
2117             #my $b = $Config{archname}."/B\.pm";
2118             #if ($name !~ /^tid|can|isa|pmreplroot$/ and $loc !~ m/$b line / and $package_pv !~ /^B::/) {
2119             # return undef if $ITHREADS;
2120             #}
2121 0 0       0 $method = $name unless $method;
2122 0 0       0 if (exists &$method) { # Do not try to save non-existing methods
2123 0 0       0 warn "save method_name \"$method\"$loc\n" if $debug{cv};
2124 0         0 return svref_2object( \&{$method} );
  0         0  
2125             } else {
2126 0         0 return 0;
2127             }
2128             }
2129              
2130              
2131             # scalar: pv. list: (stash,pv,sv)
2132             # pads are not named, but may be typed
2133             sub padop_name {
2134 0     0 0 0 my $op = shift;
2135 0         0 my $cv = shift;
2136 0 0 0     0 if ($op->can('name')
      0        
2137             and ($op->name eq 'padsv' or $op->name eq 'method_named'
2138             or ref($op) eq 'B::SVOP')) #threaded
2139             {
2140 0 0 0     0 return () if $cv and ref($cv->PADLIST) eq 'B::SPECIAL';
2141 0 0 0     0 my @c = ($cv and ref($cv) eq 'B::CV' and ref($cv->PADLIST) ne 'B::NULL')
2142             ? $cv->PADLIST->ARRAY : comppadlist->ARRAY;
2143 0         0 my @types = $c[0]->ARRAY;
2144 0         0 my @pad = $c[1]->ARRAY;
2145 0 0       0 my $ix = $op->can('padix') ? $op->padix : $op->targ;
2146 0         0 my $sv = $pad[$ix];
2147 0         0 my $t = $types[$ix];
2148 0 0 0     0 if (defined($t) and ref($t) ne 'B::SPECIAL') {
    0          
2149 0 0       0 my $pv = $sv->can("PV") ? $sv->PV : ($t->can('PVX') ? $t->PVX : '');
    0          
2150             # need to fix B for SVpad_TYPEDI without formal STASH
2151 0 0 0     0 my $stash = (ref($t) eq 'B::PVMG' and ref($t->SvSTASH) ne 'B::SPECIAL') ? $t->SvSTASH->NAME : '';
2152 0 0       0 return wantarray ? ($stash,$pv,$sv) : $pv;
2153             } elsif ($sv) {
2154 0 0       0 my $pv = $sv->PV if $sv->can("PV");
2155 0 0       0 my $stash = $sv->STASH->NAME if $sv->can("STASH");
2156 0 0       0 return wantarray ? ($stash,$pv,$sv) : $pv;
2157             }
2158             }
2159             }
2160              
2161             sub svop_name {
2162 0     0 0 0 my $op = shift;
2163 0         0 my $cv = shift;
2164 0         0 my $sv;
2165 0 0 0     0 if ($op->can('name') and $op->name eq 'padsv') {
2166 0         0 my @r = padop_name($op, $cv);
2167 0 0       0 return wantarray ? @r : ($r[1] ? $r[1] : $r[0]);
    0          
2168             } else {
2169 0 0       0 if (!$op->can("sv")) {
2170 0 0 0     0 if (ref($op) eq 'B::PMOP' and $op->pmreplroot->can("sv")) {
2171 0         0 $sv = $op->pmreplroot->sv;
2172             } else {
2173 0 0 0     0 $sv = $op->first->sv unless $op->flags & 4
      0        
      0        
2174             or ($op->name eq 'const' and $op->flags & 34) or $op->first->can("sv");
2175             }
2176             } else {
2177 0         0 $sv = $op->sv;
2178             }
2179 0 0 0     0 if ($sv and $$sv) {
2180 0 0       0 if ($sv->FLAGS & SVf_ROK) {
2181 0 0       0 return '' if $sv->isa("B::NULL");
2182 0         0 my $rv = $sv->RV;
2183 0 0       0 if ($rv->isa("B::PVGV")) {
2184 0         0 my $o = $rv->IO;
2185 0 0       0 return $o->STASH->NAME if $$o;
2186             }
2187 0 0       0 return '' if $rv->isa("B::PVMG");
2188 0         0 return $rv->STASH->NAME;
2189             } else {
2190 0 0       0 if ($op->name eq 'gvsv') {
    0          
2191 0 0       0 return wantarray ? ($sv->STASH->NAME, $sv->NAME) : $sv->STASH->NAME.'::'.$sv->NAME;
2192             } elsif ($op->name eq 'gv') {
2193 0 0       0 return wantarray ? ($sv->STASH->NAME, $sv->NAME) : $sv->STASH->NAME.'::'.$sv->NAME;
2194             } else {
2195 0 0       0 return $sv->can('STASH') ? $sv->STASH->NAME
    0          
2196             : $sv->can('NAME') ? $sv->NAME : $sv->PV;
2197             }
2198             }
2199             }
2200             }
2201             }
2202              
2203             # return the next COP for file and line info
2204             sub nextcop {
2205 0     0 0 0 my $op = shift;
2206 0   0     0 while ($op and ref($op) ne 'B::COP' and ref($op) ne 'B::NULL') { $op = $op->next; }
  0   0     0  
2207 0 0 0     0 return ($op and ref($op) eq 'B::COP') ? $op : undef;
2208             }
2209              
2210             sub svimmortal {
2211 0     0 0 0 my $sym = shift;
2212 0 0       0 if ($sym =~ /\(SV\*\)?\&PL_sv_(yes|no|undef|placeholder)/) {
2213 0         0 return 1;
2214             }
2215 0         0 return undef;
2216             }
2217              
2218             sub B::SVOP::save {
2219 0     0   0 my ( $op, $level, $fullname ) = @_;
2220 0         0 my $sym = objsym($op);
2221 0 0       0 return $sym if defined $sym;
2222 0 0       0 $level = 0 unless $level;
2223 0         0 my $svsym = 'Nullsv';
2224             # XXX moose1 crash with 5.8.5-nt, Cwd::_perl_abs_path also
2225 0 0 0     0 if ($op->name eq 'aelemfast' and $op->flags & 128) { #OPf_SPECIAL
    0 0        
      0        
      0        
      0        
2226 0         0 $svsym = '&PL_sv_undef'; # pad does not need to be saved
2227 0 0       0 warn sprintf("SVOP->sv aelemfast pad %d\n", $op->flags) if $debug{sv};
2228             } elsif ($op->name eq 'gv' and $op->next and $op->next->name eq 'rv2cv'
2229             and $op->next->next and $op->next->next->name eq 'defined' ) {
2230             # 96 do not save a gvsv->cv if just checked for defined'ness
2231 0         0 my $gv = $op->sv;
2232 0         0 my $gvsv = svop_name($op);
2233 0 0       0 if ($gvsv !~ /^DynaLoader::/) {
2234 0 0       0 warn "skip saving defined(&$gvsv)\n" if $debug{gv}; # defer to run-time
2235 0         0 $svsym = '(SV*)' . $gv->save( 8 ); # ~Save_CV in B::GV::save
2236             } else {
2237 0         0 $svsym = '(SV*)' . $gv->save();
2238             }
2239             } else {
2240 0         0 my $sv = $op->sv;
2241 0         0 $svsym = $sv->save("svop ".$op->name);
2242 0 0       0 if ($svsym =~ /^(gv_|PL_.*gv)/) {
    0          
2243 0         0 $svsym = '(SV*)' . $svsym;
2244             } elsif ($svsym =~ /^\([SAHC]V\*\)\&sv_list/) {
2245 0         0 $svsym =~ s/^\([SAHC]V\*\)//;
2246             } else {
2247 0         0 $svsym =~ s/^\([GAPH]V\*\)/(SV*)/;
2248             }
2249 0 0       0 warn "Error: SVOP: ".$op->name." $sv $svsym" if $svsym =~ /^\(SV\*\)lexwarn/; #322
2250             }
2251 0 0       0 if ($op->name eq 'method_named') {
2252 0         0 my $cv = method_named(svop_or_padop_pv($op), nextcop($op));
2253 0 0       0 $cv->save if $cv;
2254             }
2255 0         0 my $is_const_addr = $svsym =~ m/Null|\&/;
2256 0 0 0     0 if ($MULTI and svimmortal($svsym)) { # t/testm.sh Test::Pod
2257 0         0 $is_const_addr = 0;
2258             }
2259 0         0 $svopsect->comment("$opsect_common, sv");
2260 0 0       0 $svopsect->add(sprintf( "%s, %s",
2261             $op->_save_common, ( $is_const_addr ? $svsym : "Nullsv /* $svsym */" ) )
2262             );
2263 0 0       0 $svopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2264 0         0 my $ix = $svopsect->index;
2265 0 0       0 $init->add( sprintf( "svop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2266             unless $B::C::optimize_ppaddr;
2267 0 0       0 $init->add("svop_list[$ix].op_sv = $svsym;")
2268             unless $is_const_addr;
2269 0         0 savesym( $op, "(OP*)&svop_list[$ix]" );
2270             }
2271              
2272             sub B::PADOP::save {
2273 0     0   0 my ( $op, $level ) = @_;
2274 0         0 my $sym = objsym($op);
2275 0 0       0 return $sym if defined $sym;
2276 0 0       0 $level = 0 unless $level;
2277 0         0 my $skip_defined;
2278 0 0 0     0 if ($op->name eq 'method_named') {
    0 0        
      0        
      0        
2279 0         0 my $cv = method_named(svop_or_padop_pv($op), nextcop($op));
2280 0 0       0 $cv->save if $cv;
2281             } elsif ($op->name eq 'gv' and $op->next and $op->next->name eq 'rv2cv'
2282             and $op->next->next and $op->next->next->name eq 'defined' ) {
2283             # 96 do not save a gvsv->cv if just checked for defined'ness
2284 0         0 $skip_defined++;
2285             }
2286             # This is saved by curpad syms at the end. But with __DATA__ handles it is better to save earlier
2287 0 0 0     0 if ($op->name eq 'padsv' or $op->name eq 'gvsv' or $op->name eq 'gv') {
      0        
2288 0         0 my @c = comppadlist->ARRAY;
2289 0         0 my @pad = $c[1]->ARRAY;
2290 0 0       0 my $ix = $op->can('padix') ? $op->padix : $op->targ;
2291 0         0 my $sv = $pad[$ix];
2292 0 0 0     0 if ($sv and $$sv) {
2293 0         0 my $name = padop_name($op, curcv);
2294 0 0 0     0 if ($skip_defined and $name !~ /^DynaLoader::/) {
2295 0 0       0 warn "skip saving defined(&$name)\n" if $debug{gv}; # defer to run-time
2296             } else {
2297 0 0       0 $sv->save("padop ". ($name ? $name : ''));
2298             }
2299             }
2300             }
2301 0         0 $padopsect->comment("$opsect_common, padix");
2302 0         0 $padopsect->add( sprintf( "%s, %d", $op->_save_common, $op->padix ) );
2303 0 0       0 $padopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2304 0         0 my $ix = $padopsect->index;
2305 0 0       0 $init->add( sprintf( "padop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2306             unless $B::C::optimize_ppaddr;
2307 0         0 savesym( $op, "(OP*)&padop_list[$ix]" );
2308             }
2309              
2310             sub B::COP::save {
2311 0     0   0 my ( $op, $level ) = @_;
2312 0         0 my $sym = objsym($op);
2313 0 0       0 return $sym if defined $sym;
2314              
2315 0 0       0 $level = 0 unless $level;
2316             # we need to keep CvSTART cops, so check $level == 0
2317             # what a COP needs to do is to reset the stack, and restore locals
2318 0 0 0     0 if ($optimize_cop and $level and !$op->label
      0        
      0        
2319             and ref($prev_op) ne 'B::LISTOP') { # XXX very unsafe!
2320 0         0 my $sym = savesym( $op, $op->next->save );
2321             warn sprintf( "Skip COP (0x%x) => %s (0x%x), line %d file %s\n",
2322 0 0       0 $$op, $sym, $op->next, $op->line, $op->file ) if $debug{cops};
2323 0         0 return $sym;
2324             }
2325              
2326             # TODO: if it is a nullified COP we must save it with all cop fields!
2327             warn sprintf( "COP: line %d file %s\n", $op->line, $op->file )
2328 0 0       0 if $debug{cops};
2329              
2330             # shameless cut'n'paste from B::Deparse
2331 0         0 my ($warn_sv, $isint);
2332 0         0 my $warnings = $op->warnings;
2333 0         0 my $is_special = ref($warnings) eq 'B::SPECIAL';
2334 0 0       0 my $warnsvcast = $PERL510 ? "(STRLEN*)" : "(SV*)";
2335 0 0 0     0 if ( $is_special && $$warnings == 4 ) { # use warnings 'all';
    0 0        
    0          
2336 0         0 $warn_sv = 'pWARN_ALL';
2337             }
2338             elsif ( $is_special && $$warnings == 5 ) { # no warnings 'all';
2339 0         0 $warn_sv = 'pWARN_NONE';
2340             }
2341             elsif ($is_special) { # use warnings;
2342 0         0 $warn_sv = 'pWARN_STD';
2343             }
2344             else {
2345             # LEXWARN_on: Original $warnings->save from 5.8.9 was wrong,
2346             # DUP_WARNINGS copied length PVX bytes.
2347 0         0 my $warn = bless $warnings, "B::LEXWARN";
2348             # TODO: isint here misses already seen lexwarn symbols
2349 0         0 ($warn_sv, $isint) = $warn->save;
2350 0         0 my $ix = $copsect->index + 1;
2351             # XXX No idea how a &sv_list[] came up here, a re-used object. Anyway.
2352 0 0       0 $warn_sv = substr($warn_sv,1) if substr($warn_sv,0,3) eq '&sv';
2353 0         0 $warn_sv = $warnsvcast.'&'.$warn_sv;
2354 0 0 0     0 $free->add( sprintf( " cop_list[%d].cop_warnings = NULL;", $ix ) )
2355             if !$B::C::optimize_warn_sv or !$PERL510;
2356             #push @B::C::static_free, sprintf("cop_list[%d]", $ix);
2357             }
2358              
2359 0 0 0     0 my $dynamic_copwarn = ($PERL510 and !$is_special) ? 1 : !$B::C::optimize_warn_sv;
2360             # branch feature/gh70-static-lexwarn with PERL_SUPPORT_STATIC_COP
2361 0 0 0     0 $dynamic_copwarn = 0 if $Config{usecperl} and $] >= 5.022002;
2362              
2363             # Trim the .pl extension, to print the executable name only.
2364 0         0 my $file = $op->file;
2365             # $file =~ s/\.pl$/.c/;
2366 0         0 my $add_label = 0;
2367 0 0       0 if ($PERL512) {
    0          
2368 0 0 0     0 if ($ITHREADS and $] >= 5.017) {
    0 0        
    0 0        
      0        
2369 0         0 $copsect->comment(
2370             "$opsect_common, line, stashoff, file, hints, seq, warnings, hints_hash");
2371 0 0       0 $copsect->add(
2372             sprintf( "%s, %u, " . "%d, %s, %u, " . "%s, %s, NULL",
2373             $op->_save_common, $op->line,
2374             $op->stashoff, "NULL", #hints=0
2375             $op->hints,
2376             ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL'
2377             ));
2378             } elsif ($ITHREADS and $] >= 5.016) {
2379             # [perl #113034] [PATCH] 2d8d7b1 replace B::COP::stashflags by B::COP::stashlen (5.16.0 only)
2380 0         0 $copsect->comment(
2381             "$opsect_common, line, stashpv, file, stashlen, hints, seq, warnings, hints_hash");
2382 0 0       0 $copsect->add(
    0          
2383             sprintf( "%s, %u, " . "%s, %s, %d, %u, " . "%s, %s, NULL",
2384             $op->_save_common, $op->line,
2385             "NULL", "NULL",
2386             # XXX at broken 5.16.0 with B-1.34 we do non-utf8, non-null only (=> negative len),
2387             # 5.16.0 B-1.35 has stashlen, 5.16.1 we will see.
2388             $op->can('stashlen') ? $op->stashlen : length($op->stashpv),
2389             $op->hints,
2390             ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL'
2391             ));
2392             } elsif ($ITHREADS and $] >= 5.015004 and $] < 5.016) {
2393 0         0 $copsect->comment(
2394             "$opsect_common, line, stashpv, file, stashflags, hints, seq, warnings, hints_hash");
2395 0 0       0 $copsect->add(
2396             sprintf( "%s, %u, " . "%s, %s, %d, %u, " . "%s, %s, NULL",
2397             $op->_save_common, $op->line,
2398             "NULL", "NULL",
2399             $op->stashflags, $op->hints,
2400             ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL'
2401             ));
2402             } else {
2403             # cop_label now in hints_hash (Change #33656)
2404 0         0 $copsect->comment(
2405             "$opsect_common, line, stash, file, hints, seq, warn_sv, hints_hash");
2406 0 0       0 $copsect->add(
    0          
    0          
2407             sprintf( "%s, %u, " . "%s, %s, %u, " . "%s, %s, NULL",
2408             $op->_save_common, $op->line,
2409             $ITHREADS ? "NULL" : "Nullhv",# we cannot store this static (attribute exit)
2410             $ITHREADS ? "NULL" : "Nullgv",
2411             $op->hints, ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL'
2412             ));
2413             }
2414 0 0       0 if ( $op->label ) {
2415 0         0 $add_label = 1;
2416             }
2417             }
2418             elsif ($PERL510) {
2419 0         0 $copsect->comment("$opsect_common, line, label, stash, file, hints, seq, warnings, hints_hash");
2420 0 0       0 $copsect->add(sprintf("%s, %u, %s, " . "%s, %s, %u, " . "%u, %s, NULL",
2421             $op->_save_common, $op->line, 'NULL',
2422             "NULL", "NULL",
2423             $op->hints, $op->cop_seq, !$dynamic_copwarn ? $warn_sv : 'NULL'
2424             ));
2425 0 0       0 if ($op->label) {
2426 0         0 $init->add(sprintf( "CopLABEL_set(&cop_list[%d], CopLABEL_alloc(%s));",
2427             $copsect->index, cstring( $op->label ) ));
2428             }
2429             }
2430             else {
2431             # 5.8 misses cop_io
2432 0         0 $copsect->comment("$opsect_common, label, stash, file, seq, arybase, line, warn_sv, io");
2433 0 0       0 $copsect->add(
    0          
2434             sprintf( "%s, %s, %s, %s, %s, %d, %u, %s %s",
2435             $op->_save_common, cstring( $op->label ),
2436             "NULL", "NULL",
2437             ivx($op->cop_seq), $op->arybase,
2438             $op->line, !$dynamic_copwarn ? $warn_sv : 'NULL',
2439             ( $PERL56 ? "" : ", 0" )
2440             ));
2441             }
2442 0 0       0 $copsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2443 0         0 my $ix = $copsect->index;
2444 0 0       0 $init->add( sprintf( "cop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2445             unless $B::C::optimize_ppaddr;
2446              
2447 0         0 my $i = 0;
2448 0 0 0     0 if ($PERL510 and $op->hints_hash) {
2449 0         0 my $hints = $op->hints_hash;
2450 0 0       0 if ($$hints) {
2451 0 0       0 if (exists $cophhtable{$$hints}) {
2452 0         0 my $cophh = $cophhtable{$$hints};
2453 0         0 $init->add(sprintf("CopHINTHASH_set(&cop_list[%d], %s);", $ix, $cophh));
2454             } else {
2455 0 0       0 my $hint_hv = $hints->HASH if ref $hints eq 'B::RHE';
2456 0         0 my $cophh = sprintf( "cophh%d", scalar keys %cophhtable );
2457 0         0 $cophhtable{$$hints} = $cophh;
2458 0         0 $decl->add(sprintf("Static COPHH *%s;", $cophh));
2459 0         0 for my $k (keys %$hint_hv) {
2460 0         0 my ($ck, $kl, $utf8) = strlen_flags($k);
2461 0         0 my $v = $hint_hv->{$k};
2462 0 0       0 next if $k eq ':'; #skip label, see below
2463 0         0 my $val = B::svref_2object( \$v )->save("\$^H{$k}");
2464 0 0       0 if ($utf8) {
2465 0 0       0 $init->add(sprintf("%s = cophh_store_pvn(%s, %s, %d, 0, %s, COPHH_KEY_UTF8);",
2466             $cophh, $i ? $cophh : 'NULL', $ck, $kl, $val));
2467             } else {
2468 0 0       0 $init->add(sprintf("%s = cophh_store_pvs(%s, %s, %s, 0);",
2469             $cophh, $i ? $cophh : 'NULL', $ck, $val));
2470             }
2471             #$init->add(sprintf("%s->refcounted_he_refcnt--;", $cophh));
2472             #if (!$ITHREADS) {
2473             # $init->add(sprintf("HEK_FLAGS(%s->refcounted_he_hek) |= HVhek_STATIC;", $cophh));
2474             #}
2475             #if ($PERL522 and !$ITHREADS) { # breaks issue220
2476             # $init->add(sprintf("unshare_hek_hek(%s->refcounted_he_hek);", $cophh));
2477             #}
2478 0         0 $i++;
2479             }
2480 0         0 $init->add(sprintf("CopHINTHASH_set(&cop_list[%d], %s);", $ix, $cophh));
2481             }
2482             }
2483             }
2484 0 0       0 if ($add_label) {
2485             # test 29 and 15,16,21. 44,45
2486 0         0 my ($cstring, $cur, $utf8) = strlen_flags($op->label);
2487 0 0 0     0 if ($] >= 5.015001) { # officially added with 5.15.1 aebc0cbee
    0          
    0          
2488 0 0 0     0 warn "utf8 label $cstring" if $utf8 and $verbose;
2489 0         0 $init->add(sprintf("Perl_cop_store_label(aTHX_ &cop_list[%d], %s, %u, %s);",
2490             $copsect->index, $cstring, $cur, $utf8));
2491             } elsif ($] > 5.013004) {
2492 0         0 $init->add(sprintf("Perl_store_cop_label(aTHX_ &cop_list[%d], %s, %u, %s);",
2493             $copsect->index, $cstring, $cur, $utf8));
2494             } elsif (!($^O =~ /^(MSWin32|AIX)$/ or $ENV{PERL_DL_NONLAZY})) {
2495 0 0       0 warn "Warning: Overwrote hints_hash with label\n" if $i;
2496 0         0 my $ix = $copsect->index;
2497 0         0 $init->add(
2498             sprintf("cop_list[%d].cop_hints_hash = Perl_store_cop_label(aTHX_ cop_list[%d].cop_hints_hash, %s);",
2499             $ix, $ix, $cstring));
2500             }
2501             }
2502              
2503 0 0 0     0 if ($PERL510 and !$is_special and !$isint) {
      0        
2504 0         0 my $copw = $warn_sv;
2505 0         0 $copw =~ s/^\(STRLEN\*\)&//;
2506             # on cv_undef (scope exit, die, Attribute::Handlers, ...) CvROOT and kids are freed.
2507             # so lexical cop_warnings need to be dynamic.
2508 0 0       0 if ($copw) {
2509 0         0 my $dest = "cop_list[$ix].cop_warnings";
2510             # with DEBUGGING savepvn returns ptr + PERL_MEMORY_DEBUG_HEADER_SIZE
2511             # which is not the address which will be freed in S_cop_free.
2512             # Need to use old-style PerlMemShared_, see S_cop_free in op.c (#362)
2513             # lexwarn might be also be STRLEN* 0
2514 0         0 $init->no_split;
2515 0         0 $init->add("#ifdef PERL_SUPPORT_STATIC_COP /* so far cperl only */",
2516             "$dest = $warn_sv;",
2517             "#else",
2518             sprintf("%s = (STRLEN*)savesharedpvn((const char*)%s, sizeof(%s));",
2519             $dest, $copw, $copw),
2520             "#endif");
2521 0         0 $init->split;
2522             }
2523             } else {
2524 0 0       0 $init->add( sprintf( "cop_list[%d].cop_warnings = %s;", $ix, $warn_sv ) )
2525             unless $B::C::optimize_warn_sv;
2526             }
2527             #push @B::C::static_free, "cop_list[$ix]" if $ITHREADS;
2528 0 0       0 if (!$B::C::optimize_cop) {
2529 0         0 my $stash = savestashpv($op->stashpv);
2530 0         0 $init->add(sprintf( "CopSTASH_set(&cop_list[%d], %s);", $ix, $stash ));
2531 0 0       0 if (!$ITHREADS) {
2532 0 0       0 if ($B::C::const_strings) {
2533 0         0 my $constpv = constpv($file);
2534             # define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv))
2535             # cache gv_fetchfile
2536 0 0       0 if ( !$copgvtable{$constpv} ) {
2537 0         0 $copgvtable{$constpv} = $gv_index++;
2538 0         0 $init->add( sprintf( "gv_list[%d] = gv_fetchfile(%s);", $copgvtable{$constpv}, $constpv ) );
2539             }
2540             $init->add( sprintf( "CopFILEGV_set(&cop_list[%d], gv_list[%d]); /* %s */",
2541 0         0 $ix, $copgvtable{$constpv}, cstring($file) ) );
2542             #$init->add(sprintf( "CopFILE_set(&cop_list[%d], %s);", $ix, constpv($file) ));
2543             } else {
2544 0         0 $init->add(sprintf( "CopFILE_set(&cop_list[%d], %s);", $ix, cstring($file) ));
2545             }
2546             } else { # cv_undef e.g. in bproto.t and many more core tests with threads
2547 0         0 $init->add(sprintf( "CopFILE_set(&cop_list[%d], %s);", $ix, cstring($file) ));
2548             }
2549             }
2550              
2551             # our root: store all packages from this file
2552 0 0       0 if (!$mainfile) {
2553 0 0       0 $mainfile = $op->file if $op->stashpv eq 'main';
2554             } else {
2555 0 0 0     0 mark_package($op->stashpv) if $mainfile eq $op->file and $op->stashpv ne 'main';
2556             }
2557 0         0 savesym( $op, "(OP*)&cop_list[$ix]" );
2558             }
2559              
2560             # if REGCOMP can be called in init or deferred in init1
2561             sub re_does_swash {
2562 0     0 0 0 my ($qstr, $pmflags) = @_;
2563             # SWASHNEW, now needing a multideref GV. 0x5000000 is just a hack. can be more
2564 0 0 0     0 if (($] >= 5.021006 and ($pmflags & 0x5000000 == 0x5000000))
      0        
2565             # or any unicode property (#253). Note: \p{} breaks #242
2566             or ($qstr =~ /\\P\{/)
2567             )
2568             {
2569 0         0 return 1;
2570             } else {
2571 0         0 return 0;
2572             }
2573             }
2574              
2575             sub B::PMOP::save {
2576 0     0   0 my ( $op, $level, $fullname ) = @_;
2577 0         0 my ($replrootfield, $replstartfield, $gvsym) = ('NULL', 'NULL');
2578 0         0 my $sym = objsym($op);
2579 0 0       0 return $sym if defined $sym;
2580             # 5.8.5-thr crashes here (7) at pushre
2581 0 0 0     0 if ($] < 5.008008 and $ITHREADS and $$op < 256) { # B bug. split->first->pmreplroot = 0x1
      0        
2582 0         0 die "Internal B::walkoptree error: invalid PMOP for pushre\n";
2583 0         0 return;
2584             }
2585 0 0       0 $level = 0 unless $level;
2586 0         0 my $replroot = $op->pmreplroot;
2587 0         0 my $replstart = $op->pmreplstart;
2588 0         0 my $ppaddr = $op->ppaddr;
2589              
2590             # under ithreads, OP_PUSHRE.op_replroot is an integer. multi not.
2591 0 0       0 $replrootfield = sprintf( "s\\_%x", $$replroot ) if ref $replroot;
2592 0 0 0     0 if ( $ITHREADS && $op->name eq "pushre" ) {
    0          
2593 0 0       0 warn "PMOP::save saving a pp_pushre as int ${replroot}\n" if $debug{gv};
2594 0         0 $replrootfield = "INT2PTR(OP*,${replroot})";
2595             }
2596             elsif ($$replroot) {
2597             # OP_PUSHRE (a mutated version of OP_MATCH for the regexp
2598             # argument to a split) stores a GV in op_pmreplroot instead
2599             # of a substitution syntax tree. We don't want to walk that...
2600 0 0       0 if ( $op->name eq "pushre" ) {
2601 0 0       0 warn "PMOP::save saving a pp_pushre with GV $gvsym\n" if $debug{gv};
2602 0         0 $gvsym = $replroot->save;
2603 0         0 $replrootfield = "NULL";
2604 0 0       0 $replstartfield = $replstart->save if $replstart;
2605             }
2606             else {
2607 0 0       0 $replstart->save if $replstart;
2608 0         0 $replstartfield = saveoptree( "*ignore*", $replroot, $replstart );
2609 0         0 $replstartfield =~ s/^hv/(OP*)hv/;
2610             }
2611             }
2612              
2613             # pmnext handling is broken in perl itself, we think. Bad op_pmnext
2614             # fields aren't noticed in perl's runtime (unless you try reset) but we
2615             # segfault when trying to dereference it to find op->op_pmnext->op_type
2616 0 0       0 if ($PERL510) {
    0          
2617 0         0 $pmopsect->comment(
2618             "$opsect_common, first, last, pmoffset, pmflags, pmreplroot, pmreplstart"
2619             );
2620             $pmopsect->add(
2621             sprintf( "%s, s\\_%x, s\\_%x, %u, 0x%x, {%s}, {%s}",
2622 0         0 $op->_save_common, ${ $op->first },
2623 0 0       0 ${ $op->last }, ( $ITHREADS ? $op->pmoffset : 0 ),
  0         0  
2624             $op->pmflags, $replrootfield, $replstartfield
2625             ));
2626 0 0       0 if ($] >= 5.017) {
2627 0         0 my $code_list = $op->code_list;
2628 0 0 0     0 if ($code_list and $$code_list) {
2629             warn sprintf("saving pmop_list[%d] code_list $code_list (?{})\n", $pmopsect->index)
2630 0 0       0 if $debug{gv};
2631 0         0 my $code_op = $code_list->save;
2632 0 0       0 $init->add(sprintf("pmop_list[%d].op_code_list = %s;", # (?{}) code blocks
2633             $pmopsect->index, $code_op)) if $code_op;
2634             warn sprintf("done saving pmop_list[%d] code_list $code_list (?{})\n", $pmopsect->index)
2635 0 0       0 if $debug{gv};
2636             }
2637             }
2638             }
2639             elsif ($PERL56) {
2640             # pmdynflags does not exist as B method. It is only used for PMdf_UTF8 dynamically,
2641             # if static we set this already in pmflags.
2642 0         0 $pmopsect->comment(
2643             "$opsect_common, first, last, pmreplroot, pmreplstart, pmnext, pmregexp, pmflags, pmpermflags, pmdynflags"
2644             );
2645             $pmopsect->add(
2646             sprintf( "%s, s\\_%x, s\\_%x, %s, %s, 0, 0, 0x%x, 0x%x",
2647             $op->_save_common,
2648 0         0 ${ $op->first }, ${ $op->last },
  0         0  
  0         0  
2649             $replrootfield, $replstartfield,
2650             $op->pmflags, $op->pmpermflags, 0 # XXX original 5.6 B::C misses pmdynflags
2651             ));
2652             } else { # perl5.8.x
2653 0         0 $pmopsect->comment(
2654             "$opsect_common, first, last, pmreplroot, pmreplstart, pmoffset, pmflags, pmpermflags, pmdynflags, pmstash"
2655             );
2656             $pmopsect->add(
2657             sprintf( "%s, s\\_%x, s\\_%x, %s, %s, 0, %u, 0x%x, 0x%x, 0x%x, %s",
2658 0         0 $op->_save_common, ${ $op->first },
2659 0 0       0 ${ $op->last }, $replrootfield,
  0 0       0  
2660             $replstartfield, $ITHREADS ? $op->pmoffset : 0,
2661             $op->pmflags, $op->pmpermflags,
2662             $op->pmdynflags, $MULTI ? cstring($op->pmstashpv) : "0"
2663             ));
2664 0 0 0     0 if (!$MULTI and $op->pmstash) {
2665 0         0 my $stash = $op->pmstash->save;
2666 0         0 $init->add( sprintf( "pmop_list[%d].op_pmstash = %s;", $pmopsect->index, $stash ) );
2667             }
2668             }
2669 0 0       0 $pmopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2670 0         0 my $pm = sprintf( "pmop_list[%d]", $pmopsect->index );
2671 0 0       0 $init->add( sprintf( "%s.op_ppaddr = %s;", $pm, $ppaddr ) )
2672             unless $B::C::optimize_ppaddr;
2673 0         0 my $re = $op->precomp;
2674 0 0       0 if ( defined($re) ) {
2675 0         0 my $initpm = $init;
2676 0         0 $Regexp{$$op} = $op;
2677 0 0       0 if ($PERL510) {
    0          
2678             # TODO minor optim: fix savere( $re ) to avoid newSVpvn;
2679             # precomp did not set the utf8 flag (#333, #338), fixed with 1.52_01
2680 0         0 my ($qre, $relen, $utf8) = strlen_flags($re);
2681 0         0 my $pmflags = $op->pmflags;
2682             warn "pregcomp $pm $qre:$relen:$utf8".sprintf(" 0x%x\n",$pmflags)
2683 0 0 0     0 if $debug{pv} or $debug{gv};
2684             # Since 5.13.10 with PMf_FOLD (i) we need to swash_init("utf8::Cased").
2685 0 0 0     0 if ($] >= 5.013009 and $pmflags & 4) {
2686             # Note: in CORE utf8::SWASHNEW is demand-loaded from utf8 with Perl_load_module()
2687 0         0 load_utf8_heavy();
2688 0 0 0     0 if ($PERL518 and !$swash_init and $swash_ToCf) {
      0        
2689 0         0 $init->add("PL_utf8_tofold = $swash_ToCf;");
2690 0         0 $swash_init++;
2691             }
2692             }
2693             # some pm need early init (242), SWASHNEW needs some late GVs (GH#273)
2694             # esp with 5.22 multideref init. i.e. all \p{} \N{}, \U, /i, ...
2695             # But XSLoader and utf8::SWASHNEW itself needs to be early.
2696 0 0 0     0 if (($utf8 and $] >= 5.013009 and ($pmflags & 4 == 4)) # needs SWASHNEW (case fold)
      0        
      0        
2697             or re_does_swash($qre, $pmflags))
2698             {
2699 0         0 $initpm = $init1;
2700 0 0       0 warn sprintf("deferred PMOP %s %s 0x%x\n", $qre, $fullname, $pmflags) if $debug{sv};
2701             } else {
2702 0 0       0 warn sprintf("normal PMOP %s %s 0x%x\n", $qre, $fullname, $pmflags) if $debug{sv};
2703             }
2704 0 0 0     0 if ($PERL518 and $op->reflags & RXf_EVAL_SEEN) { # set HINT_RE_EVAL on
2705 0         0 $pmflags |= PMf_EVAL;
2706 0         0 $initpm->no_split;
2707 0         0 $initpm->add("{",
2708             " U32 hints_sav = PL_hints;",
2709             " PL_hints |= HINT_RE_EVAL;");
2710             }
2711 0 0       0 if ($] > 5.008008) { # can do utf8 qr
2712 0         0 $initpm->add( # XXX Modification of a read-only value attempted. use DateTime - threaded
2713             sprintf("PM_SETRE(&%s, CALLREGCOMP(newSVpvn_flags(%s, %s, SVs_TEMP|$utf8), 0x%x));",
2714             $pm, $qre, $relen, $pmflags),
2715             sprintf("RX_EXTFLAGS(PM_GETRE(&%s)) = 0x%x;", $pm, $op->reflags ));
2716             } else {
2717 0         0 $initpm->add
2718             ("PM_SETRE(&$pm,",
2719             " CALLREGCOMP(newSVpvn($qre, $relen), ".sprintf("0x%x));", $pmflags),
2720             sprintf("RX_EXTFLAGS(PM_GETRE(&%s)) = 0x%x;", $pm, $op->reflags ));
2721 0 0       0 $initpm->add("SvUTF8_on(PM_GETRE(&$pm));") if $utf8;
2722             }
2723 0 0 0     0 if ($] >= 5.018 and $op->reflags & RXf_EVAL_SEEN) { # set HINT_RE_EVAL off
2724 0         0 $initpm->add(" PL_hints = hints_sav;",
2725             "}");
2726 0         0 $initpm->split();
2727             }
2728             # See toke.c:8964
2729             # set in the stash the PERL_MAGIC_symtab PTR to the PMOP: ((PMOP**)mg->mg_ptr) [elements++] = pm;
2730 0 0 0     0 if ($PERL510 and $op->pmflags & PMf_ONCE()) {
2731 0 0       0 my $stash = $MULTI ? $op->pmstashpv
    0          
2732             : ref $op->pmstash eq 'B::HV' ? $op->pmstash->NAME : '__ANON__';
2733 0         0 $Regexp{$$op} = $op; #188: restore PMf_ONCE, set PERL_MAGIC_symtab in $stash
2734             }
2735             }
2736             elsif ($PERL56) {
2737 0         0 my ( $resym, $relen ) = savere( $re, 0 );
2738 0         0 $init->add(
2739             "$pm.op_pmregexp = pregcomp((char*)$resym, (char*)$resym + $relen, &$pm);"
2740             );
2741             }
2742             else { # 5.8
2743 0         0 my ( $resym, $relen ) = savere( $re, 0 );
2744 0         0 $init->add(
2745             "PM_SETRE(&$pm, CALLREGCOMP(aTHX_ (char*)$resym, (char*)$resym + $relen, &$pm));"
2746             );
2747             }
2748             }
2749 0 0       0 if ( $gvsym ) {
2750 0 0       0 if ($PERL510) {
2751             # XXX need that for subst
2752 0         0 $init->add("$pm.op_pmreplrootu.op_pmreplroot = (OP*)$gvsym;");
2753             } else {
2754 0         0 $init->add("$pm.op_pmreplroot = (OP*)$gvsym;");
2755             }
2756             }
2757 0         0 savesym( $op, "(OP*)&$pm" );
2758             }
2759              
2760             sub B::SPECIAL::save {
2761 0     0   0 my ($sv, $fullname) = @_;
2762             # special case: $$sv is not the address but an index into specialsv_list
2763             # warn "SPECIAL::save specialsv $$sv\n"; # debug
2764 0 0       0 @specialsv_name = qw(Nullsv &PL_sv_undef &PL_sv_yes &PL_sv_no pWARN_ALL pWARN_NONE)
2765             unless @specialsv_name; # 5.6.2 Exporter quirks. pWARN_STD was added to B with 5.8.9
2766 0         0 my $sym = $specialsv_name[$$sv];
2767 0 0       0 if ( !defined($sym) ) {
2768 0         0 warn "unknown specialsv index $$sv passed to B::SPECIAL::save";
2769             }
2770 0         0 return $sym;
2771             }
2772              
2773       0     sub B::OBJECT::save { }
2774              
2775             sub B::NULL::save {
2776 0     0   0 my ($sv, $fullname) = @_;
2777 0         0 my $sym = objsym($sv);
2778 0 0       0 return $sym if defined $sym;
2779              
2780             # debug
2781 0 0       0 if ( $$sv == 0 ) {
2782 0 0       0 warn "NULL::save for sv = 0 called from @{[(caller(1))[3]]}\n" if $verbose;
  0         0  
2783 0         0 return savesym( $sv, "(void*)Nullsv" );
2784             }
2785              
2786 0         0 my $i = $svsect->index + 1;
2787 0 0       0 warn "Saving SVt_NULL sv_list[$i]\n" if $debug{sv};
2788 0 0       0 $svsect->add( sprintf( "NULL, $u32fmt, 0x%x".($PERL510?", {0}":''),
2789             $sv->REFCNT, $sv->FLAGS ) );
2790             #$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; # XXX where is this possible?
2791 0 0 0     0 if ($debug{flags} and (!$ITHREADS or $PERL514) and $DEBUG_LEAKING_SCALARS) { # add index to sv_debug_file to easily find the Nullsv
      0        
      0        
2792             # $svsect->debug( "ix added to sv_debug_file" );
2793 0         0 $init->add(sprintf(qq(sv_list[%d].sv_debug_file = savesharedpv("NULL sv_list[%d] 0x%x");),
2794             $svsect->index, $svsect->index, $sv->FLAGS));
2795             }
2796 0         0 savesym( $sv, sprintf( "&sv_list[%d]", $svsect->index ) );
2797             }
2798              
2799             sub B::UV::save {
2800 0     0   0 my ($sv, $fullname) = @_;
2801 0         0 my $sym = objsym($sv);
2802 0 0       0 return $sym if defined $sym;
2803 0         0 my $uvuformat = $Config{uvuformat};
2804 0         0 $uvuformat =~ s/["\0]//g; #" poor editor
2805 0         0 $uvuformat =~ s/".$/"/; # cperl bug 5.22.2 #61
2806 0         0 my $uvx = $sv->UVX;
2807 0         0 my $suff = 'U';
2808 0 0       0 $suff .= 'L' if $uvx > 2147483647;
2809 0         0 my $i = $svsect->index + 1;
2810 0 0       0 if ($PERL524) {
    0          
    0          
2811             # since 5.24 we need to point the xpvuv to the head
2812             } elsif ($PERL514) {
2813             # issue 145 warn $sv->UVX, " ", sprintf($u32fmt, $sv->UVX);
2814 0         0 $xpvuvsect->comment( "stash, magic, cur, len, xuv_u" );
2815 0         0 $xpvuvsect->add( sprintf( "Nullhv, {0}, 0, 0, {%".$uvuformat."$suff}", $uvx ) );
2816             } elsif ($PERL510) {
2817 0         0 $xpvuvsect->comment( "stash, magic, cur, len, xuv_u" );
2818 0         0 $xpvuvsect->add( sprintf( "{0}, 0, 0, {%".$uvuformat."$suff}", $uvx ) );
2819             } else {
2820 0         0 $xpvuvsect->comment( "pv, cur, len, uv" );
2821 0         0 $xpvuvsect->add( sprintf( "0, 0, 0, %".$uvuformat.$suff, $uvx ) );
2822             }
2823 0 0       0 if ($PERL524) {
2824 0 0       0 $svsect->add(sprintf( "NULL, $u32fmt, 0x%x".
    0          
2825             ($PERL510?', {'.($C99?".svu_uv=":"").$uvx."$suff}":''),
2826             $sv->REFCNT, $sv->FLAGS));
2827             #32bit - sizeof(void*), 64bit: - 2*ptrsize
2828 0 0 0     0 if ($Config{ptrsize} == 4 and !IS_MSVC) {
2829 0         0 $init->add(sprintf( "sv_list[%d].sv_any = (void*)&sv_list[%d] - sizeof(void*);", $i, $i));
2830             } else {
2831             $init->add(sprintf( "sv_list[%d].sv_any = (char*)&sv_list[%d] - %d;", $i, $i,
2832 0         0 2*$Config{ptrsize}));
2833             }
2834             } else {
2835 0 0       0 $svsect->add(sprintf( "&xpvuv_list[%d], $u32fmt, 0x%x".
    0          
2836             ($PERL510?', {'.($C99?".svu_uv=":"").$uvx."$suff}":''),
2837             $xpvuvsect->index, $sv->REFCNT, $sv->FLAGS));
2838             }
2839 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
2840             warn sprintf( "Saving IV(UV) 0x%x to xpvuv_list[%d], sv_list[%d], called from %s:%s\n",
2841 0         0 $sv->UVX, $xpvuvsect->index, $i, @{[(caller(1))[3]]}, @{[(caller(0))[2]]} )
  0         0  
2842 0 0       0 if $debug{sv};
2843 0         0 savesym( $sv, sprintf( "&sv_list[%d]", $i ) );
2844             }
2845              
2846             sub B::IV::save {
2847 0     0   0 my ($sv, $fullname) = @_;
2848 0         0 my $sym = objsym($sv);
2849 0 0       0 return $sym if defined $sym;
2850             # Since 5.11 the RV is no special SV object anymore, just a IV (test 16)
2851 0         0 my $svflags = $sv->FLAGS;
2852 0 0 0     0 if ($PERL512 and $svflags & SVf_ROK) {
2853 0         0 return $sv->B::RV::save($fullname);
2854             }
2855 0 0       0 if ($svflags & SVf_IVisUV) {
2856 0         0 return $sv->B::UV::save;
2857             }
2858 0         0 my $ivx = ivx($sv->IVX);
2859 0         0 my $i = $svsect->index + 1;
2860 0 0 0     0 if ($svflags & 0xff and !($svflags & (SVf_IOK|SVp_IOK))) { # Not nullified
2861 0 0 0     0 unless (($PERL510 and $svflags & 0x00010000) # PADSTALE - out of scope lexical is !IOK
      0        
      0        
      0        
      0        
2862             or (!$PERL510 and $svflags & 0x00000100) # PADBUSY
2863             or ($] > 5.015002 and $svflags & 0x60002)) { # 5.15.3 changed PAD bits
2864 0         0 warn sprintf("Internal warning: IV !IOK $fullname sv_list[$i] 0x%x\n",$svflags);
2865             }
2866             }
2867 0 0       0 if ($PERL524) {
    0          
    0          
2868             # since 5.24 we need to point the xpviv to the head
2869             } elsif ($PERL514) {
2870 0         0 $xpvivsect->comment( "stash, magic, cur, len, xiv_u" );
2871 0         0 $xpvivsect->add( sprintf( "Nullhv, {0}, 0, 0, {%s}", $ivx ) );
2872             } elsif ($PERL510) {
2873 0         0 $xpvivsect->comment( "stash, magic, cur, len, xiv_u" );
2874 0         0 $xpvivsect->add( sprintf( "{0}, 0, 0, {%s}", $ivx ) );
2875             } else {
2876 0         0 $xpvivsect->comment( "pv, cur, len, iv" );
2877 0         0 $xpvivsect->add( sprintf( "0, 0, 0, %s", $ivx ) );
2878             }
2879 0 0       0 if ($PERL524) {
2880 0 0       0 $svsect->add(sprintf( "NULL, $u32fmt, 0x%x, {".($C99?".svu_iv=":"").$ivx.'}',
2881             $sv->REFCNT, $svflags ));
2882             #32bit - sizeof(void*), 64bit: - 2*ptrsize
2883 0 0 0     0 if ($Config{ptrsize} == 4 and !IS_MSVC) {
2884 0         0 $init->add(sprintf( "sv_list[%d].sv_any = (void*)&sv_list[%d] - sizeof(void*);", $i, $i));
2885             } else {
2886             $init->add(sprintf( "sv_list[%d].sv_any = (char*)&sv_list[%d] - %d;", $i, $i,
2887 0         0 2*$Config{ptrsize}));
2888             }
2889             } else {
2890 0 0       0 $svsect->add(sprintf( "&xpviv_list[%d], $u32fmt, 0x%x".($PERL510?', {'.($C99?".svu_iv=":"").$ivx.'}':''),
    0          
2891             $xpvivsect->index, $sv->REFCNT, $svflags ));
2892             }
2893 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
2894             warn sprintf( "Saving IV 0x%x to xpviv_list[%d], sv_list[%d], called from %s:%s\n",
2895 0         0 $sv->IVX, $xpvivsect->index, $i, @{[(caller(1))[3]]}, @{[(caller(0))[2]]} )
  0         0  
2896 0 0       0 if $debug{sv};
2897 0         0 savesym( $sv, sprintf( "&sv_list[%d]", $i ) );
2898             }
2899              
2900             sub B::NV::save {
2901 0     0   0 my ($sv, $fullname) = @_;
2902 0         0 my $sym = objsym($sv);
2903 0 0       0 return $sym if defined $sym;
2904 0         0 my $nv = nvx($sv->NV);
2905 0 0       0 $nv .= '.00' if $nv =~ /^-?\d+$/;
2906             # IVX is invalid in B.xs and unused
2907 0 0       0 my $iv = $sv->FLAGS & SVf_IOK ? $sv->IVX : 0;
2908 0 0 0     0 $nv = '0.00' if IS_MSVC and !$nv;
2909 0 0       0 if ($PERL514) {
    0          
2910 0         0 $xpvnvsect->comment('STASH, MAGIC, cur, len, IVX, NVX');
2911 0         0 $xpvnvsect->add( sprintf( "Nullhv, {0}, 0, 0, {%ld}, {%s}", $iv, $nv ) );
2912             } elsif ($PERL510) { # not fixed by NV isa IV >= 5.8
2913 0         0 $xpvnvsect->comment('NVX, cur, len, IVX');
2914 0         0 $xpvnvsect->add( sprintf( "{%s}, 0, 0, {%ld}", $nv, $iv ) );
2915             }
2916             else {
2917 0         0 $xpvnvsect->comment('PVX, cur, len, IVX, NVX');
2918 0         0 $xpvnvsect->add( sprintf( "0, 0, 0, %ld, %s", $iv, $nv ) );
2919             }
2920 0 0       0 $svsect->add(
2921             sprintf( "&xpvnv_list[%d], $u32fmt, 0x%x %s",
2922             $xpvnvsect->index, $sv->REFCNT, $sv->FLAGS, $PERL510 ? ', {0}' : '' ));
2923 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
2924             warn sprintf( "Saving NV %s to xpvnv_list[%d], sv_list[%d]\n",
2925             $nv, $xpvnvsect->index, $svsect->index )
2926 0 0       0 if $debug{sv};
2927 0         0 savesym( $sv, sprintf( "&sv_list[%d]", $svsect->index ) );
2928             }
2929              
2930             sub savepvn {
2931 0     0 0 0 my ( $dest, $pv, $sv, $cur ) = @_;
2932 0         0 my @init;
2933              
2934             # work with byte offsets/lengths
2935 0 0       0 $pv = pack "a*", $pv if defined $pv;
2936 0 0 0     0 if ( defined $max_string_len && length($pv) > $max_string_len ) {
2937 0         0 push @init, sprintf( "Newx(%s, %u, char);", $dest, length($pv) + 2 );
2938 0         0 my $offset = 0;
2939 0         0 while ( length $pv ) {
2940 0         0 my $str = substr $pv, 0, $max_string_len, '';
2941 0         0 push @init,
2942             sprintf( "Copy(%s, %s+%d, %u, char);",
2943             cstring($str), $dest, $offset, length($str) );
2944 0         0 $offset += length $str;
2945             }
2946 0         0 push @init, sprintf( "%s[%u] = '\\0';", $dest, $offset );
2947             warn sprintf( "Copying overlong PV %s to %s\n", cstring($pv), $dest )
2948 0 0 0     0 if $debug{sv} or $debug{pv};
2949             }
2950             else {
2951             # If READONLY and FAKE use newSVpvn_share instead. (test 75)
2952             # XXX IsCOW forgotten here. rather use a helper is_shared_hek()
2953 0 0 0     0 if ($PERL510 and $sv and (($sv->FLAGS & 0x09000000) == 0x09000000)) {
      0        
2954 0 0       0 warn sprintf( "Saving shared HEK %s to %s\n", cstring($pv), $dest ) if $debug{sv};
2955 0         0 my $hek = save_hek($pv,'',1);
2956 0 0       0 push @init, sprintf( "%s = HEK_KEY(%s);", $dest, $hek ) unless $hek eq 'NULL';
2957 0 0       0 if ($DEBUGGING) { # we have to bypass a wrong HE->HEK assert in hv.c
2958 0         0 push @B::C::static_free, $dest;
2959             }
2960             } else {
2961 0         0 my $cstr = cstring($pv);
2962 0 0 0     0 if (!$cstr and $cstr == 0) {
2963 0         0 $cstr = '""';
2964             }
2965 0 0 0     0 if ($sv and IsCOW($sv)) { # and ($B::C::cow or IsCOW_hek($sv)))
2966             # This cannot be savepvn allocated. TODO: READONLY COW => static hek?
2967 0 0       0 if ($cstr !~ /\\000\\00\d"$/) {
2968 0         0 $cstr = substr($cstr,0,-1) . '\0\001"';
2969 0         0 $cur += 2;
2970             }
2971 0 0       0 warn sprintf( "Saving COW PV %s to %s\n", $cstr, $dest ) if $debug{sv};
2972 0         0 return (sprintf( "Newx(%s, sizeof(%s)-1, char);", $dest, $cstr ),
2973             sprintf( "Copy(%s, %s, sizeof(%s)-1, char);", $cstr, $dest, $cstr ));
2974             }
2975 0 0       0 warn sprintf( "Saving PV %s to %s\n", $cstr, $dest ) if $debug{sv};
2976 0         0 push @init, sprintf( "%s = Perl_savepvn(aTHX_ STR_WITH_LEN(%s));", $dest, $cstr );
2977             }
2978             }
2979 0         0 return @init;
2980             }
2981              
2982             sub B::PVLV::save {
2983 0     0   0 my ($sv, $fullname) = @_;
2984 0         0 my $sym = objsym($sv);
2985 0 0       0 if (defined $sym) {
2986 0 0       0 if ($in_endav) {
2987 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
2988 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
2989             }
2990 0         0 return $sym;
2991             }
2992 0         0 my ($pvsym, $cur, $len, $pv, $static, $flags) = save_pv_or_rv ($sv, $fullname);
2993 0         0 my ( $lvtarg, $lvtarg_sym ); # XXX missing
2994 0         0 my $tmp_pvsym = $pvsym;
2995 0 0       0 if ($PERL514) {
    0          
2996 0         0 $xpvlvsect->comment('STASH, MAGIC, CUR, LEN, GvNAME, xnv_u, TARGOFF, TARGLEN, TARG, TYPE');
2997 0         0 $xpvlvsect->add(
2998             sprintf("Nullhv, {0}, %u, %d, 0/*GvNAME later*/, %s, %u, %u, Nullsv, %s",
2999             $cur, $len, nvx($sv->NVX),
3000             $sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) ));
3001 0 0 0     0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3002 0         0 $svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x, {(char*)%s}",
3003             $xpvlvsect->index, $sv->REFCNT, $sv->FLAGS, $tmp_pvsym));
3004             } elsif ($PERL510) {
3005 0         0 $xpvlvsect->comment('xnv_u, CUR, LEN, GvNAME, MAGIC, STASH, TARGOFF, TARGLEN, TARG, TYPE');
3006 0         0 $xpvlvsect->add(
3007             sprintf("%s, %u, %d, 0/*GvNAME later*/, 0, Nullhv, %u, %u, Nullsv, %s",
3008             nvx($sv->NVX), $cur, $len,
3009             $sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) ));
3010 0 0       0 $svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x, {%s}",
3011             $xpvlvsect->index, $sv->REFCNT, $flags,
3012             ($C99?".svu_pv = (char*)":"(char*)").$tmp_pvsym));
3013             } else {
3014 0         0 $xpvlvsect->comment('PVX, CUR, LEN, IVX, NVX, TARGOFF, TARGLEN, TARG, TYPE');
3015 0         0 $xpvlvsect->add(
3016             sprintf("(char*)%s, %u, %u, %s, %s, 0, 0, %u, %u, Nullsv, %s",
3017             $pvsym, $cur, $len, ivx($sv->IVX), nvx($sv->NVX),
3018             $sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) ));
3019 0         0 $svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x",
3020             $xpvlvsect->index, $sv->REFCNT, $flags));
3021             }
3022 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3023 0         0 my $s = "sv_list[".$svsect->index."]";
3024 0 0 0     0 if ( !$static ) {
    0          
3025 0 0       0 if ($PERL510) {
3026 0         0 $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3027             }
3028             else {
3029 0         0 $init->add( savepvn( sprintf( "xpvlv_list[%d].xpv_pv", $xpvlvsect->index ), $pv, $cur ) );
3030             }
3031             } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3032 0         0 $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3033             }
3034 0         0 $sv->save_magic($fullname);
3035 0         0 savesym( $sv, "&".$s );
3036             }
3037              
3038             sub B::PVIV::save {
3039 0     0   0 my ($sv, $fullname) = @_;
3040 0         0 my $sym = objsym($sv);
3041 0 0       0 if (defined $sym) {
3042 0 0       0 if ($in_endav) {
3043 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
3044 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
3045             }
3046 0         0 return $sym;
3047             }
3048 0         0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3049 0         0 my $tmp_pvsym = $pvsym;
3050 0 0       0 if ($PERL514) {
    0          
3051 0         0 $xpvivsect->comment('STASH, MAGIC, cur, len, IVX');
3052 0         0 $xpvivsect->add( sprintf( "Nullhv, {0}, %u, %u, {%s}", $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long
3053 0 0 0     0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3054             } elsif ($PERL510) {
3055 0         0 $xpvivsect->comment('xnv_u, cur, len, IVX');
3056 0         0 $xpvivsect->add( sprintf( "{0}, %u, %u, {%s}", $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long
3057             } else {
3058             #$iv = 0 if $sv->FLAGS & (SVf_IOK|SVp_IOK);
3059 0         0 $xpvivsect->comment('PVX, cur, len, IVX');
3060 0         0 $xpvivsect->add( sprintf( "(char*)%s, %u, %u, %s",
3061             $pvsym, $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long
3062             }
3063 0 0       0 $svsect->add(
    0          
3064             sprintf("&xpviv_list[%d], $u32fmt, 0x%x %s",
3065             $xpvivsect->index, $sv->REFCNT, $flags,
3066             $PERL510 ? ", {".($C99?".svu_pv=":"")."(char*)$tmp_pvsym}" : '' ) );
3067 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3068 0         0 my $s = "sv_list[".$svsect->index."]";
3069 0 0       0 if ( defined($pv) ) {
3070 0 0 0     0 if ( !$static ) {
    0          
3071 0 0       0 if ($PERL510) {
3072 0         0 $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3073             } else {
3074 0         0 $init->add( savepvn( sprintf( "xpviv_list[%d].xpv_pv", $xpvivsect->index ), $pv, $cur ) );
3075             }
3076             } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3077 0         0 $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3078             }
3079             }
3080 0         0 savesym( $sv, "&".$s );
3081             }
3082              
3083             sub B::PVNV::save {
3084 0     0   0 my ($sv, $fullname) = @_;
3085 0         0 my $sym = objsym($sv);
3086 0 0       0 if (defined $sym) {
3087 0 0       0 if ($in_endav) {
3088 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
3089 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
3090             }
3091 0         0 return $sym;
3092             }
3093 0         0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3094 0         0 my $tmp_pvsym = $pvsym;
3095 0         0 my $nvx = '0.0';
3096 0         0 my $ivx = ivx($sv->IVX); # here must be IVX!
3097 0 0       0 if ($flags & (SVf_NOK|SVp_NOK)) {
3098             # it could be a double, or it could be 2 ints - union xpad_cop_seq
3099 0         0 $nvx = nvx($sv->NV);
3100             } else {
3101 0 0 0     0 if ($PERL510 and $C99 and !$PERL522) {
    0 0        
3102 0         0 $nvx = sprintf(".xpad_cop_seq.xlow = %s, .xpad_cop_seq.xhigh = %s",
3103             ivx($sv->COP_SEQ_RANGE_LOW), ivx($sv->COP_SEQ_RANGE_HIGH),
3104             );
3105             } elsif (!$PERL522) {
3106 0         0 $nvx = nvx($sv->NVX);
3107             }
3108             }
3109 0 0       0 if ($PERL510) {
3110             # For some time the stringification works of NVX double to two ints worked ok.
3111 0 0       0 if ($PERL514) {
3112 0 0 0     0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3113 0         0 $xpvnvsect->comment('STASH, MAGIC, cur, len, IVX, NVX');
3114 0         0 $xpvnvsect->add(sprintf( "Nullhv, {0}, %u, %u, {%s}, {%s}", $cur, $len, $ivx, $nvx) );
3115             } else {
3116 0         0 $xpvnvsect->comment('NVX, cur, len, IVX');
3117 0         0 $xpvnvsect->add(sprintf( "{%s}, %u, %u, {%s}", $nvx, $cur, $len, $ivx ) );
3118             }
3119 0 0 0     0 if (!($sv->FLAGS & (SVf_NOK|SVp_NOK)) and !$PERL522) {
3120 0 0       0 warn "NV => run-time union xpad_cop_seq init\n" if $debug{sv};
3121 0         0 $init->add(sprintf("xpvnv_list[%d].xnv_u.xpad_cop_seq.xlow = %s;",
3122             $xpvnvsect->index, ivx($sv->COP_SEQ_RANGE_LOW)),
3123             # pad.c: PAD_MAX = I32_MAX (4294967295)
3124             # U suffix <= "warning: this decimal constant is unsigned only in ISO C90"
3125             sprintf("xpvnv_list[%d].xnv_u.xpad_cop_seq.xhigh = %s;",
3126             $xpvnvsect->index, ivx($sv->COP_SEQ_RANGE_HIGH)));
3127             }
3128             }
3129             else {
3130 0         0 $xpvnvsect->comment('PVX, cur, len, IVX, NVX');
3131 0         0 $xpvnvsect->add(sprintf( "(char*)%s, %u, %u, %s, %s", $pvsym, $cur, $len, $ivx, $nvx ) );
3132             }
3133 0 0       0 $svsect->add(
    0          
3134             sprintf("&xpvnv_list[%d], $u32fmt, 0x%x %s",
3135             $xpvnvsect->index, $sv->REFCNT, $flags,
3136             $PERL510 ? ", {".($C99?".svu_pv=":"")."(char*)$tmp_pvsym}" : '' ) );
3137 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3138 0         0 my $s = "sv_list[".$svsect->index."]";
3139 0 0       0 if ( defined($pv) ) {
3140 0 0 0     0 if ( !$static ) {
    0          
3141 0 0       0 if ($PERL510) {
3142 0         0 $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3143             }
3144             else {
3145 0         0 $init->add( savepvn( sprintf( "xpvnv_list[%d].xpv_pv", $xpvnvsect->index ), $pv, $cur ) );
3146             }
3147             } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3148 0         0 $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3149             }
3150             }
3151 0 0 0     0 push @B::C::static_free, "&".$s if $PERL518 and $sv->FLAGS & SVs_OBJECT;
3152 0         0 savesym( $sv, "&".$s );
3153             }
3154              
3155             sub B::BM::save {
3156 0     0   0 my ($sv, $fullname) = @_;
3157 0         0 my $sym = objsym($sv);
3158 0 0 0     0 return $sym if !$PERL510 and defined $sym;
3159 0 0       0 $sv = bless $sv, "B::BM" if $PERL510;
3160 0         0 my $pv = pack "a*", ( $sv->PV . "\0" . $sv->TABLE );
3161 0         0 my $cur = $sv->CUR;
3162 0         0 my $len = $cur + length($sv->TABLE) + 1;
3163 0         0 my $s;
3164 0 0       0 if ($PERL510) {
3165 0 0       0 warn "Saving FBM for GV $sym\n" if $debug{gv};
3166 0         0 $init->add( sprintf( "%s = (GV*)newSV_type(SVt_PVGV);", $sym ),
3167             sprintf( "SvFLAGS(%s) = 0x%x;", $sym, $sv->FLAGS),
3168             sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $sv->REFCNT + 1 ),
3169             sprintf( "SvPVX(%s) = %s;", $sym, cstring($pv) ),
3170             sprintf( "SvCUR_set(%s, %d);", $sym, $cur ),
3171             sprintf( "SvLEN_set(%s, %d);", $sym, $len ),
3172             sprintf( "BmRARE(%s) = %d;", $sym, $sv->RARE ),
3173             sprintf( "BmPREVIOUS(%s) = %d;", $sym, $sv->PREVIOUS ),
3174             sprintf( "BmUSEFUL(%s) = %d;", $sym, $sv->USEFUL )
3175             );
3176             } else {
3177 0         0 my $static;
3178 0         0 $xpvbmsect->comment('pvx,cur,len(+258),IVX,NVX,MAGIC,STASH,USEFUL,PREVIOUS,RARE');
3179 0 0 0     0 $xpvbmsect->add(
3180             sprintf("%s, %u, %u, %s, %s, 0, 0, %d, %u, 0x%x",
3181             defined($pv) && $static ? cstring($pv) : "NULL",
3182             $cur, $len, ivx($sv->IVX), nvx($sv->NVX),
3183             $sv->USEFUL, $sv->PREVIOUS, $sv->RARE
3184             ));
3185 0         0 $svsect->add(sprintf("&xpvbm_list[%d], $u32fmt, 0x%x",
3186             $xpvbmsect->index, $sv->REFCNT, $sv->FLAGS));
3187 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3188 0         0 $s = "sv_list[".$svsect->index."]";
3189 0 0       0 if (!$static) {
3190 0         0 $init->add(savepvn( sprintf( "xpvbm_list[%d].xpv_pv", $xpvbmsect->index ), $pv, 0, $len ) );
3191             } else {
3192 0 0 0     0 push @B::C::static_free, $s if defined($pv) and !$in_endav;
3193             }
3194             }
3195             # Restore possible additional magic. fbm_compile adds just 'B'.
3196 0         0 $sv->save_magic($fullname);
3197              
3198 0 0       0 if ($PERL510) {
3199 0         0 return $sym;
3200             } else {
3201 0 0       0 if ($] == 5.008009) { # XXX 5.8.9 needs more. TODO test 5.8.0 - 5.8.7
3202 0         0 $init->add( sprintf( "fbm_compile(&sv_list[%d], 0);", $svsect->index ) );
3203             }
3204             # cur+len was broken on all B::C versions
3205             #$init->add(sprintf( "xpvbm_list[%d].xpv_cur = %u;", $xpvbmsect->index, $len ) );
3206 0         0 return savesym( $sv, "&".$s );
3207             }
3208             }
3209              
3210             sub B::PV::save {
3211 0     0   0 my ($sv, $fullname) = @_;
3212 0         0 my $sym = objsym($sv);
3213 0 0       0 if (defined $sym) {
3214 0 0       0 if ($in_endav) {
3215 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
3216 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
3217             }
3218 0         0 return $sym;
3219             }
3220             #my $flags = $sv->FLAGS;
3221 0         0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3222 0 0       0 my $shared_hek = $PERL510 ? (($flags & 0x09000000) == 0x09000000) : undef;
3223 0 0 0     0 if (!$shared_hek and (IsCOW_hek($sv) or ($len==0 and $flags & SVf_IsCOW))) {
      0        
3224 0         0 $shared_hek = 1;
3225             }
3226 0         0 my $tmp_pvsym = $pvsym;
3227             # $static = 0 if !($flags & SVf_ROK) and $sv->PV and $sv->PV =~ /::bootstrap$/;
3228 0         0 my $refcnt = $sv->REFCNT;
3229 0         0 my $svix;
3230             # sv_free2 problem with !SvIMMORTAL and del_SV
3231             # repro with -O0 .. -O2 for all testcases
3232 0 0 0     0 if ($PERL518 and $fullname && $fullname eq 'svop const') {
      0        
3233 0 0       0 $refcnt = $DEBUGGING ? 1000 : 0x7fffffff;
3234             }
3235             #if (!$shared_hek and !$B::C::cow and IsCOW($sv)) {
3236             # $flags &= ~SVf_IsCOW;
3237             # warn sprintf("turn off SVf_IsCOW %s %s %s\n", $sym, cstring($pv), $fullname)
3238             # if $debug{pv};
3239             #}
3240 0 0       0 if ($PERL510) {
3241             # static pv, do not destruct. test 13 with pv0 "3".
3242 0 0 0     0 if ($B::C::const_strings and !$shared_hek and $flags & SVf_READONLY and !$len) {
      0        
      0        
3243 0         0 $flags &= ~0x01000000;
3244             warn sprintf("constpv turn off SVf_FAKE %s %s %s\n", $sym, cstring($pv), $fullname)
3245 0 0       0 if $debug{pv};
3246             }
3247 0 0 0     0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3248 0 0       0 $xpvsect->comment( $PERL514 ? "stash, magic, cur, len" : "xnv_u, cur, len");
3249 0 0       0 $xpvsect->add( sprintf( "%s{0}, %u, %u", $PERL514 ? "Nullhv, " : "", $cur, $len ) );
3250 0         0 $svsect->comment( "any, refcnt, flags, sv_u" );
3251 0 0       0 $svsect->add( sprintf( "&xpv_list[%d], $u32fmt, 0x%x, {%s}",
    0          
3252             $xpvsect->index, $refcnt, $flags,
3253             $tmp_pvsym eq 'NULL' ? '0' :
3254             ($C99?".svu_pv=(char*)":"(char*)").$pvsym ));
3255 0         0 $svix = $svsect->index;
3256 0 0 0     0 if ( defined($pv) and !$static ) {
    0 0        
      0        
3257 0 0       0 if ($shared_hek) {
3258 0         0 my $hek = save_hek($pv, $fullname, 1);
3259 0 0       0 $init->add( sprintf( "sv_list[%d].sv_u.svu_pv = HEK_KEY(%s);", $svix, $hek ))
3260             unless $hek eq 'NULL';
3261             } else {
3262 0         0 $init->add( savepvn( sprintf( "sv_list[%d].sv_u.svu_pv", $svix ), $pv, $sv, $cur ) );
3263             }
3264             } elsif ($shared_hek and $static and $pvsym =~ /^hek/) {
3265 0         0 $init->add( sprintf( "sv_list[%d].sv_u.svu_pv = %s.hek_key;", $svix, $pvsym ));
3266             }
3267 0 0 0     0 if ($debug{flags} and (!$ITHREADS or $PERL514) and $DEBUG_LEAKING_SCALARS) { # add sv_debug_file
      0        
      0        
3268 0 0       0 $init->add(sprintf(qq(sv_list[%d].sv_debug_file = %s" sv_list[%d] 0x%x";),
3269             $svix, cstring($pv) eq '0' ? '"NULL"' : cstring($pv),
3270             $svix, $flags));
3271             }
3272             }
3273             else {
3274 0         0 $xpvsect->comment( "pv, cur, len");
3275 0         0 $xpvsect->add(sprintf( "(char*)%s, %u, %u", $pvsym, $cur, $len ) );
3276 0         0 $svsect->comment( "any, refcnt, flags" );
3277 0         0 $svsect->add(sprintf( "&xpv_list[%d], $u32fmt, 0x%x",
3278             $xpvsect->index, $refcnt, $flags));
3279 0         0 $svix = $svsect->index;
3280 0 0 0     0 if ( defined($pv) and !$static ) {
3281 0         0 $init->add( savepvn( sprintf( "xpv_list[%d].xpv_pv", $xpvsect->index ), $pv, 0, $cur ) );
3282             }
3283             }
3284 0         0 my $s = "sv_list[$svix]";
3285 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3286 0 0 0     0 push @B::C::static_free, "&".$s if $PERL518 and $flags & SVs_OBJECT;
3287 0         0 savesym( $sv, "&".$s );
3288             }
3289              
3290             # 5.18-5.20 => PV::save, since 5.22 native using this method
3291             sub B::PADNAME::save {
3292 0     0   0 my ($pn, $fullname) = @_;
3293 0         0 my $sym = objsym($pn);
3294 0 0       0 if (defined $sym) {
3295 0 0       0 if ($in_endav) {
3296 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
3297 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
3298             }
3299 0         0 return $sym;
3300             }
3301 0         0 my $flags = $pn->FLAGS; # U8 + FAKE if OUTER. OUTER,STATE,LVALUE,TYPED,OUR
3302 0         0 $flags = $flags & 0xff;
3303 0         0 my $gen = $pn->GEN;
3304 0         0 my $stash = $pn->OURSTASH;
3305 0         0 my $type = $pn->TYPE;
3306 0         0 my $sn = $stash->save($fullname);
3307 0         0 my $tn = $type->save($fullname);
3308 0         0 my $refcnt = $pn->REFCNT;
3309 0 0       0 $refcnt++ if $refcnt < 1000; # XXX protect from free, but allow SvREFCOUNT_IMMORTAL
3310 0         0 my $str = $pn->PVX;
3311 0         0 my $cstr = cstring($str); # a 5.22 padname is always utf8
3312 0         0 my $len = $pn->LEN;
3313 0         0 my $alignedlen = 8*(int($len / 8)+1); # 5 -> 8, 9 -> 16
3314 0         0 my $struct_name = "my_padname_with_str_".$alignedlen;
3315 0         0 my $pnsect = $padnamesect{$alignedlen};
3316 0 0       0 if (!$pnsect) {
3317 0         0 my $name = "padname_$alignedlen";
3318 0 0       0 warn "dynamically created oversized $name section\n" if $verbose;
3319 0         0 $padnamesect{$alignedlen} = new B::C::Section $name, \%symtable, 0;
3320             }
3321 0         0 my $ix = $pnsect->index + 1;
3322 0         0 my $name = $pnsect->name;
3323 0         0 my $s = "&".$name."_list[$ix]";
3324             # 5.22 needs the buffer to be at the end, and the pv pointing to it.
3325             # We allocate a static buffer of different sizes.
3326 0         0 $pnsect->comment( "pv, ourstash, type, low, high, refcnt, gen, len, flags, str");
3327 0         0 my $pnstr = "((char*)$s)+STRUCT_OFFSET(struct $struct_name, xpadn_str[0])";
3328 0 0       0 if (IS_MSVC) {
3329 0         0 $pnstr = sprintf("((char*)$s)+%d", $Config{ptrsize} * 3 + 5);
3330             }
3331 0 0 0     0 $pnsect->add( sprintf
    0          
    0          
    0          
3332             ( "%s, %s, {%s}, %u, %u, %s, %i, %u, 0x%x, %s",
3333             ($ix or $len) ? $pnstr : 'NULL',
3334             is_constant($sn) ? "(HV*)$sn" : 'Nullhv',
3335             is_constant($tn) ? "(HV*)$tn" : 'Nullhv',
3336             $pn->COP_SEQ_RANGE_LOW,
3337             $pn->COP_SEQ_RANGE_HIGH,
3338             $refcnt >= 1000 ? sprintf("0x%x", $refcnt) : "$refcnt /* +1 */",
3339             $gen, $len, $flags, $cstr));
3340             #if ( $len > 64 ) {
3341             # Houston we have a problem, need to allocate this padname dynamically. Not done yet
3342             # either dynamic or seperate structs per size MyPADNAME(5)
3343             # die "Internal Error: Overlong name of lexical variable $cstr for $fullname [#229]";
3344             #}
3345 0 0       0 $pnsect->debug( $fullname." ".$str, $pn->flagspv ) if $debug{flags};
3346 0 0       0 $init->add("SvOURSTASH_set($s, $sn);") unless is_constant($sn);
3347 0 0       0 $init->add("PadnameTYPE($s) = (HV*)$tn;") unless is_constant($tn);
3348 0         0 push @B::C::static_free, $s;
3349 0         0 savesym( $pn, $s );
3350             }
3351              
3352             sub lexwarnsym {
3353 0     0 0 0 my $pv = shift;
3354 0 0       0 if ($lexwarnsym{$pv}) {
3355 0         0 return @{$lexwarnsym{$pv}};
  0         0  
3356             } else {
3357 0         0 my $sym = sprintf( "lexwarn%d", $pv_index++ );
3358 0         0 my ($cstring, $cur, $utf8) = strlen_flags($pv);
3359 0         0 my $isint = 0;
3360 0 0       0 if ($] < 5.009) { # need a SV->PV
3361 0         0 $decl->add( sprintf( "Static SV* %s;", $sym ));
3362 0         0 $init->add( sprintf( "%s = newSVpvn(%s, %u);", $sym, $cstring, $cur));
3363             } else {
3364             # if 8 use UVSIZE, if 4 use LONGSIZE
3365 0 0       0 my $t = ($Config{longsize} == 8) ? "J" : "L";
3366 0         0 my ($iv) = unpack($t, $pv); # unsigned longsize
3367 0 0 0     0 if ($iv >= 0 and $iv <= 2) { # specialWARN: single STRLEN
3368 0         0 $decl->add( sprintf( "Static const STRLEN* %s = %d;", $sym, $iv ));
3369 0         0 $isint = 1;
3370             } else { # sizeof(STRLEN) + (WARNsize)
3371 0         0 my $packedpv = pack("$t a*",length($pv), $pv);
3372 0         0 $decl->add( sprintf( "Static const char %s[] = %s;", $sym, cstring($packedpv) ));
3373             }
3374             }
3375 0         0 $lexwarnsym{$pv} = [$sym,$isint];
3376 0         0 return ($sym, $isint);
3377             }
3378             }
3379              
3380             # pre vs. post 5.8.9/5.9.4 logic for lexical warnings
3381             @B::LEXWARN::ISA = qw(B::PV B::IV);
3382             sub B::LEXWARN::save {
3383 0     0   0 my ($sv, $fullname) = @_;
3384 0 0       0 my $pv = $] >= 5.008009 ? $sv->PV : $sv->IV;
3385 0         0 return lexwarnsym($pv); # look for shared const int's
3386             }
3387              
3388             # post 5.11: When called from save_rv not from PMOP::save precomp
3389             sub B::REGEXP::save {
3390 0     0   0 my ($sv, $fullname) = @_;
3391 0         0 my $sym = objsym($sv);
3392 0 0       0 return $sym if defined $sym;
3393 0         0 my $pv = $sv->PV;
3394 0         0 my $cur = $sv->CUR;
3395             # construct original PV
3396 0         0 $pv =~ s/^(\(\?\^[adluimsx-]*\:)(.*)\)$/$2/;
3397 0         0 $cur -= length($sv->PV) - length($pv);
3398 0         0 my $cstr = cstring($pv);
3399             # Unfortunately this XPV is needed temp. Later replaced by struct regexp.
3400 0 0       0 $xpvsect->add( sprintf( "%s{0}, %u, %u", $PERL514 ? "Nullhv, " : "", $cur, 0 ) );
3401 0 0       0 $svsect->add(sprintf("&xpv_list[%d], $u32fmt, 0x%x, {%s}",
3402             $xpvsect->index, $sv->REFCNT, $sv->FLAGS, $] > 5.017006 ? "NULL" : $cstr));
3403 0         0 my $ix = $svsect->index;
3404 0 0 0     0 warn "Saving RX $cstr to sv_list[$ix]\n" if $debug{rx} or $debug{sv};
3405 0 0       0 if ($] > 5.011) {
3406 0 0       0 my $pmflags = $PERL522 ? $sv->compflags : $sv->EXTFLAGS;
3407 0 0       0 my $initpm = re_does_swash($cstr, $pmflags) ? $init1 : $init;
3408 0 0 0     0 if ($PERL518 and $sv->EXTFLAGS & RXf_EVAL_SEEN) {
3409 0         0 $initpm->add("PL_hints |= HINT_RE_EVAL;");
3410             }
3411             $initpm->add(# replace sv_any->XPV with struct regexp. need pv and extflags
3412 0         0 sprintf("SvANY(&sv_list[%d]) = SvANY(CALLREGCOMP(newSVpvn(%s, %d), 0x%x));",
3413             $ix, $cstr, $cur, $pmflags));
3414 0 0 0     0 if ($PERL518 and $sv->EXTFLAGS & RXf_EVAL_SEEN) {
3415 0         0 $initpm->add("PL_hints &= ~HINT_RE_EVAL;");
3416             }
3417             }
3418 0 0       0 if ($] < 5.017006) {
3419             # since 5.17.6 the SvLEN stores RX_WRAPPED(rx)
3420 0         0 $init->add(sprintf("SvCUR(&sv_list[%d]) = %d;", $ix, $cur),
3421             "SvLEN(&sv_list[$ix]) = 0;");
3422             } else {
3423 0         0 $init->add("sv_list[$ix].sv_u.svu_rx = (struct regexp*)sv_list[$ix].sv_any;");
3424             }
3425 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3426 0         0 $sym = savesym( $sv, sprintf( "&sv_list[%d]", $ix ) );
3427 0         0 $sv->save_magic($fullname);
3428 0         0 return $sym;
3429             }
3430              
3431             sub save_remap {
3432 0     0 0 0 my ($key, $pkg, $name, $ivx, $mandatory) = @_;
3433 0         0 my $id = $xpvmgsect->index + 1;
3434             #my $svid = $svsect->index + 1;
3435 0 0       0 warn "init remap for $key\: $name $ivx in xpvmg_list[$id]\n" if $verbose;
3436 0         0 my $props = { NAME => $name, ID => $id, MANDATORY => $mandatory };
3437 0 0       0 $init2_remap{$key}{MG} = [] unless $init2_remap{$key}{'MG'};
3438 0         0 push @{$init2_remap{$key}{MG}}, $props;
  0         0  
3439             }
3440              
3441             sub patch_dlsym {
3442 0     0 0 0 my ($sv, $fullname, $ivx) = @_;
3443 0         0 my $pkg = '';
3444 0 0       0 if (ref($sv) eq 'B::PVMG') {
3445 0         0 my $stash = $sv->SvSTASH;
3446 0 0       0 $pkg = $stash->can('NAME') ? $stash->NAME : '';
3447             }
3448 0 0       0 my $name = $sv->FLAGS & SVp_POK ? $sv->PVX : "";
3449 0         0 my $ivx_s = $ivx;
3450 0         0 $ivx_s =~ s/U?L?$//g;
3451 0         0 my $ivxhex = sprintf("0x%x", $ivx_s);
3452             # Encode RT #94221
3453 0 0 0     0 if ($name =~ /encoding$/ and $name =~ /^(ascii|ascii_ctrl|iso8859_1|null)/ and $Encode::VERSION eq '2.58') {
    0 0        
    0 0        
    0 0        
    0          
3454 0         0 $name =~ s/-/_/g;
3455 0 0       0 $pkg = 'Encode' if $pkg eq 'Encode::XS'; # TODO foreign classes
3456 0 0 0     0 mark_package($pkg) if $fullname eq '(unknown)' and $ITHREADS;
3457 0 0       0 warn "$pkg $Encode::VERSION with remap support for $name\n" if $verbose;
3458             }
3459             elsif ($pkg eq 'Encode::XS') {
3460 0         0 $pkg = 'Encode';
3461 0 0       0 if ($fullname eq 'Encode::Encoding{iso-8859-1}') {
    0          
    0          
    0          
3462 0         0 $name = "iso8859_1_encoding";
3463             }
3464             elsif ($fullname eq 'Encode::Encoding{null}') {
3465 0         0 $name = "null_encoding";
3466             }
3467             elsif ($fullname eq 'Encode::Encoding{ascii-ctrl}') {
3468 0         0 $name = "ascii_ctrl_encoding";
3469             }
3470             elsif ($fullname eq 'Encode::Encoding{ascii}') {
3471 0         0 $name = "ascii_encoding";
3472             }
3473              
3474 0 0 0     0 if ($name and $name =~ /^(ascii|ascii_ctrl|iso8859_1|null)/ and $Encode::VERSION gt '2.58') {
      0        
3475 0         0 my $enc = Encode::find_encoding($name);
3476 0 0       0 $name .= "_encoding" unless $name =~ /_encoding$/;
3477 0         0 $name =~ s/-/_/g;
3478 0 0       0 warn "$pkg $Encode::VERSION with remap support for $name (find 1)\n" if $verbose;
3479 0         0 mark_package($pkg);
3480 0 0       0 if ($pkg ne 'Encode') {
3481 0         0 svref_2object( \&{"$pkg\::bootstrap"} )->save;
  0         0  
3482 0         0 mark_package('Encode');
3483             }
3484             }
3485             else {
3486 0         0 for my $n (Encode::encodings()) { # >=5.16 constsub without name
3487 0         0 my $enc = Encode::find_encoding($n);
3488 0 0 0     0 if ($enc and ref($enc) ne 'Encode::XS') { # resolve alias such as Encode::JP::JIS7=HASH(0x292a9d0)
3489 0         0 $pkg = ref($enc);
3490 0         0 $pkg =~ s/^(Encode::\w+)(::.*)/$1/; # collapse to the @dl_module name
3491 0         0 $enc = Encode->find_alias($n);
3492             }
3493 0 0 0     0 if ($enc and ref($enc) eq 'Encode::XS' and $sv->IVX == $$enc) {
      0        
3494 0         0 $name = $n;
3495 0         0 $name =~ s/-/_/g;
3496 0 0       0 $name .= "_encoding" if $name !~ /_encoding$/;
3497 0         0 mark_package($pkg) ;
3498 0 0       0 if ($pkg ne 'Encode') {
3499 0         0 svref_2object( \&{"$pkg\::bootstrap"} )->save;
  0         0  
3500 0         0 mark_package('Encode');
3501             }
3502 0         0 last;
3503             }
3504             }
3505 0 0       0 if ($name) {
3506 0 0       0 warn "$pkg $Encode::VERSION remap found for constant $name\n" if $verbose;
3507             } else {
3508 0         0 warn "Warning: Possible missing remap for compile-time XS symbol in $pkg $fullname $ivxhex [#305]\n";
3509             }
3510             }
3511             }
3512             # Encode-2.59 uses a different name without _encoding
3513             elsif ($Encode::VERSION ge '2.58' and Encode::find_encoding($name)) {
3514 0         0 my $enc = Encode::find_encoding($name);
3515 0 0       0 $pkg = ref($enc) if ref($enc) ne 'Encode::XS';
3516 0         0 $name .= "_encoding";
3517 0         0 $name =~ s/-/_/g;
3518 0 0       0 $pkg = 'Encode' unless $pkg;
3519 0 0       0 warn "$pkg $Encode::VERSION with remap support for $name (find 2)\n" if $verbose;
3520             }
3521             # now that is a weak heuristic, which misses #305
3522             elsif (defined ($Net::DNS::VERSION)
3523             and $Net::DNS::VERSION =~ /^0\.(6[789]|7[1234])/) {
3524 0 0       0 if ($fullname eq 'svop const') {
3525 0         0 $name = "ascii_encoding";
3526 0 0       0 $pkg = 'Encode' unless $pkg;
3527 0         0 warn "Warning: Patch Net::DNS external XS symbol $pkg\::$name $ivxhex [RT #94069]\n";
3528             }
3529             }
3530             elsif ($pkg eq 'Net::LibIDN') {
3531 0         0 $name = "idn_to_ascii"; # ??
3532             }
3533              
3534             # new API (only Encode so far)
3535 0 0 0     0 if ($pkg and $name and $name =~ /^[a-zA-Z_0-9-]+$/) { # valid symbol name
      0        
3536 0 0       0 warn "Remap IOK|POK $pkg with $name\n" if $verbose;
3537 0         0 save_remap($pkg, $pkg, $name, $ivxhex, 0);
3538 0         0 $ivx = "0UL /* $ivxhex => $name */";
3539 0 0       0 mark_package($pkg, 1) if $fullname =~ /^(svop const|padop)/;
3540             }
3541             else {
3542 0         0 warn "Warning: Possible missing remap for compile-time XS symbol in $pkg $fullname $ivxhex [#305]\n";
3543             }
3544 0         0 return $ivx;
3545             }
3546              
3547             sub B::PVMG::save {
3548 0     0   0 my ($sv, $fullname) = @_;
3549 0         0 my $sym = objsym($sv);
3550 0 0       0 if (defined $sym) {
3551 0 0       0 if ($in_endav) {
3552 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
3553 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
3554             }
3555 0         0 return $sym;
3556             }
3557 0         0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3558             #warn sprintf( "PVMG %s (0x%x) $pvsym, $len, $cur, $pv\n", $sym, $$sv ) if $debug{mg};
3559              
3560 0         0 my ($ivx,$nvx);
3561             # since 5.11 REGEXP isa PVMG, but has no IVX and NVX methods
3562 0 0 0     0 if ($] >= 5.011 and ref($sv) eq 'B::REGEXP') {
3563 0         0 return B::REGEXP::save($sv, $fullname);
3564             }
3565             else {
3566 0         0 $ivx = ivx($sv->IVX); # XXX How to detect HEK* namehek?
3567 0         0 $nvx = nvx($sv->NVX); # it cannot be xnv_u.xgv_stash ptr (BTW set by GvSTASH later)
3568              
3569             # See #305 Encode::XS: XS objects are often stored as SvIV(SvRV(obj)). The real
3570             # address needs to be patched after the XS object is initialized.
3571             # But how detect them properly?
3572             # Detect ptr to extern symbol in shared library and remap it in init2
3573             # Safe and mandatory currently only Net-DNS-0.67 - 0.74.
3574             # svop const or pad OBJECT,IOK
3575 0 0 0     0 if (((!$ITHREADS
      0        
      0        
3576             and $fullname
3577             and $fullname =~ /^svop const|^padop|^Encode::Encoding| :pad\[1\]/)
3578             or $ITHREADS)
3579             and $sv->IVX > LOWEST_IMAGEBASE # some crazy heuristic for a sharedlibrary ptr in .data (> image_base)
3580             and ref($sv->SvSTASH) ne 'B::SPECIAL')
3581             {
3582 0         0 $ivx = patch_dlsym($sv, $fullname, $ivx);
3583             }
3584             }
3585              
3586 0         0 my $tmp_pvsym = $pvsym;
3587 0 0       0 if ($PERL510) {
3588 0 0       0 if ($sv->FLAGS & SVf_ROK) { # sv => sv->RV cannot be initialized static.
3589 0 0       0 $init->add(sprintf("SvRV_set(&sv_list[%d], (SV*)%s);", $svsect->index+1, $pvsym))
3590             if $pvsym ne '';
3591 0         0 $pvsym = 'NULL';
3592 0         0 $static = 1;
3593             }
3594 0 0       0 if ($PERL514) {
3595 0 0 0     0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3596 0         0 $xpvmgsect->comment("STASH, MAGIC, cur, len, xiv_u, xnv_u");
3597 0         0 $xpvmgsect->add(sprintf("Nullhv, {0}, %u, %u, {%s}, {%s}",
3598             $cur, $len, $ivx, $nvx));
3599             } else {
3600 0         0 $xpvmgsect->comment("xnv_u, cur, len, xiv_u, xmg_u, xmg_stash");
3601 0         0 $xpvmgsect->add(sprintf("{%s}, %u, %u, {%s}, {0}, Nullhv",
3602             $nvx, $cur, $len, $ivx));
3603             }
3604 0 0       0 $svsect->add(sprintf("&xpvmg_list[%d], $u32fmt, 0x%x, {%s}",
    0          
3605             $xpvmgsect->index, $sv->REFCNT, $flags,
3606             $tmp_pvsym eq 'NULL' ? '0' :
3607             ($C99?".svu_pv=(char*)":"(char*)").$tmp_pvsym));
3608             }
3609             else {
3610 0 0 0     0 if ($pvsym =~ /PL_sv_undef/ and $ITHREADS) {
3611 0         0 $pvsym = 'NULL'; # Moose 5.8.9d
3612             }
3613 0         0 $xpvmgsect->add(sprintf("(char*)%s, %u, %u, %s, %s, 0, 0",
3614             $pvsym, $cur, $len, $ivx, $nvx));
3615 0         0 $svsect->add(sprintf("&xpvmg_list[%d], $u32fmt, 0x%x",
3616             $xpvmgsect->index, $sv->REFCNT, $flags));
3617             }
3618 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3619 0         0 my $s = "sv_list[".$svsect->index."]";
3620 0 0 0     0 if ( !$static ) { # do not overwrite RV slot (#273)
    0          
3621             # XXX comppadnames need &PL_sv_undef instead of 0 (?? which testcase?)
3622 0 0       0 if ($PERL510) {
3623 0         0 $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3624             } else {
3625 0         0 $init->add( savepvn( sprintf( "xpvmg_list[%d].xpv_pv", $xpvmgsect->index ),
3626             $pv, $sv, $cur ) );
3627             }
3628             } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3629 0         0 $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3630             }
3631 0         0 $sym = savesym( $sv, "&".$s );
3632 0         0 $sv->save_magic($fullname);
3633 0         0 return $sym;
3634             }
3635              
3636             # mark threads::shared to be xs-loaded
3637             sub mark_threads {
3638 0 0   0 0 0 if ( $INC{'threads.pm'} ) {
3639 0         0 my $stash = 'threads';
3640 0         0 mark_package($stash);
3641 0         0 $use_xsloader = 1;
3642 0         0 $xsub{$stash} = 'Dynamic-' . $INC{'threads.pm'};
3643 0 0       0 warn "mark threads for 'P' magic\n" if $debug{mg};
3644             } else {
3645 0 0       0 warn "ignore to mark threads for 'P' magic\n" if $debug{mg};
3646             }
3647 0 0       0 if ( $INC{'threads/shared.pm'} ) {
3648 0         0 my $stash = 'threads::shared';
3649 0         0 mark_package($stash);
3650             # XXX why is this needed? threads::shared should be initialized automatically
3651 0         0 $use_xsloader = 1; # ensure threads::shared is initialized
3652 0         0 $xsub{$stash} = 'Dynamic-' . $INC{'threads/shared.pm'};
3653 0 0       0 warn "mark threads::shared for 'P' magic\n" if $debug{mg};
3654             } else {
3655 0 0       0 warn "ignore to mark threads::shared for 'P' magic\n" if $debug{mg};
3656             }
3657             }
3658              
3659             sub B::PVMG::save_magic {
3660 0     0   0 my ($sv, $fullname) = @_;
3661 0         0 my $sv_flags = $sv->FLAGS;
3662 0         0 my $pkg;
3663 0 0 0     0 return if $fullname and $fullname eq '%B::C::';
3664 0 0       0 if ($debug{mg}) {
3665 0         0 my $flagspv = "";
3666 0 0       0 $fullname = '' unless $fullname;
3667 0 0 0     0 $flagspv = $sv->flagspv if $debug{flags} and $PERL510 and !$sv->MAGICAL;
      0        
3668             warn sprintf( "saving magic for %s %s (0x%x) flags=0x%x%s - called from %s:%s\n",
3669             B::class($sv), $fullname, $$sv, $sv_flags, $debug{flags} ? "(".$flagspv.")" : "",
3670 0 0       0 @{[(caller(1))[3]]}, @{[(caller(1))[2]]});
  0         0  
  0         0  
3671             }
3672              
3673             # crashes on STASH=0x18 with HV PERL_MAGIC_overload_table stash %version:: flags=0x3280000c
3674             # issue267 GetOpt::Long SVf_AMAGIC|SVs_RMG|SVf_OOK
3675             # crashes with %Class::MOP::Instance:: flags=0x2280000c also
3676 0 0 0     0 if (ref($sv) eq 'B::HV' and $] > 5.018 and $sv->MAGICAL and $fullname =~ /::$/) {
    0 0        
      0        
      0        
      0        
3677 0 0       0 warn sprintf("skip SvSTASH for overloaded HV %s flags=0x%x\n", $fullname, $sv_flags)
3678             if $verbose;
3679             # [cperl #60] not only overloaded, version also
3680             } elsif (ref($sv) eq 'B::HV' and $] > 5.018 and $fullname =~ /(version|File)::$/) {
3681 0 0       0 warn sprintf("skip SvSTASH for %s flags=0x%x\n", $fullname, $sv_flags)
3682             if $verbose;
3683             } else {
3684 0         0 my $pkgsym;
3685 0         0 $pkg = $sv->SvSTASH;
3686 0 0 0     0 if ($pkg and $$pkg) {
3687 0 0       0 my $pkgname = $pkg->can('NAME') ? $pkg->NAME : $pkg->NAME_HEK."::DESTROY";
3688             warn sprintf("stash isa class \"%s\" (%s)\n", $pkgname, ref $pkg)
3689 0 0 0     0 if $debug{mg} or $debug{gv};
3690             # 361 do not force dynaloading IO via IO::Handle upon us
3691             # core already initialized this stash for us
3692 0 0 0     0 unless ($fullname eq 'main::STDOUT' and $] >= 5.018) {
3693 0 0       0 if (ref $pkg eq 'B::HV') {
3694 0 0 0     0 if ($fullname !~ /::$/ or $B::C::stash) {
3695 0         0 $pkgsym = $pkg->save($fullname);
3696             } else {
3697 0         0 $pkgsym = savestashpv($pkgname);
3698             }
3699             } else {
3700 0         0 $pkgsym = 'NULL';
3701             }
3702              
3703             warn sprintf( "xmg_stash = \"%s\" as %s\n", $pkgname, $pkgsym )
3704 0 0 0     0 if $debug{mg} or $debug{gv};
3705             # Q: Who is initializing our stash from XS? ->save is missing that.
3706             # A: We only need to init it when we need a CV
3707             # defer for XS loaded stashes with AMT magic
3708 0 0       0 if (ref $pkg eq 'B::HV') {
3709 0         0 $init->add( sprintf( "SvSTASH_set(s\\_%x, (HV*)s\\_%x);", $$sv, $$pkg ) );
3710 0         0 $init->add( sprintf( "SvREFCNT((SV*)s\\_%x) += 1;", $$pkg ) );
3711 0 0       0 $init->add("++PL_sv_objcount;") unless ref($sv) eq "B::IO";
3712             # XXX
3713             #push_package($pkg->NAME); # correct code, but adds lots of new stashes
3714             }
3715             }
3716             }
3717             }
3718 0 0 0     0 $init->add(sprintf("SvREADONLY_off((SV*)s\\_%x);", $$sv))
3719             if $sv_flags & SVf_READONLY and ref($sv) ne 'B::HV';
3720              
3721             # Protect our SVs against non-magic or SvPAD_OUR. Fixes tests 16 and 14 + 23
3722 0 0 0     0 if ($PERL510 and !($sv->MAGICAL or $sv_flags & SVf_AMAGIC)) {
      0        
3723             warn sprintf("Skipping non-magical PVMG type=%d, flags=0x%x%s\n",
3724             $sv_flags && 0xff, $sv_flags, $debug{flags} ? "(".$sv->flagspv.")" : "")
3725 0 0 0     0 if $debug{mg};
    0          
3726 0         0 return '';
3727             }
3728              
3729             # disabled. testcase: t/testm.sh Path::Class
3730 0         0 if (0 and $PERL518 and $sv_flags & SVf_AMAGIC) {
3731             my $name = $fullname;
3732             $name =~ s/^%(.*)::$/$1/;
3733             $name = $pkg->NAME if $pkg and $$pkg;
3734             warn sprintf("initialize overload cache for %s\n", $fullname )
3735             if $debug{mg} or $debug{gv};
3736             # This is destructive, it removes the magic instead of adding it.
3737             #$init1->add(sprintf("Gv_AMG(%s); /* init overload cache for %s */", savestashpv($name),
3738             # $fullname));
3739             }
3740              
3741 0         0 my @mgchain = $sv->MAGIC;
3742 0         0 my ( $mg, $type, $obj, $ptr, $len, $ptrsv );
3743 0         0 my $magic = '';
3744 0         0 foreach $mg (@mgchain) {
3745 0         0 $type = $mg->TYPE;
3746 0         0 $ptr = $mg->PTR;
3747 0         0 $len = $mg->LENGTH;
3748 0         0 $magic .= $type;
3749 0 0       0 if ( $debug{mg} ) {
3750 0         0 warn sprintf( "%s %s magic 0x%x\n", $fullname, cchar($type), $mg->FLAGS );
3751             #eval {
3752             # warn sprintf( "magic %s (0x%x), obj %s (0x%x), type %s, ptr %s\n",
3753             # B::class($sv), $$sv, B::class($obj), $$obj, cchar($type),
3754             # cstring($ptr) );
3755             #};
3756             }
3757              
3758 0 0       0 unless ( $type =~ /^[rDn]$/ ) { # r - test 23 / D - Getopt::Long
3759             # 5.10: Can't call method "save" on unblessed reference
3760             #warn "Save MG ". $obj . "\n" if $PERL510;
3761             # 5.11 'P' fix in B::IV::save, IV => RV
3762 0         0 $obj = $mg->OBJ;
3763 0 0 0     0 $obj->save($fullname)
3764             unless $PERL510 and ref $obj eq 'SCALAR';
3765 0 0       0 mark_threads if $type eq 'P';
3766             }
3767              
3768 0 0       0 if ( $len == HEf_SVKEY ) {
    0          
    0          
    0          
    0          
    0          
3769             # The pointer is an SV* ('s' sigelem e.g.)
3770             # XXX On 5.6 ptr might be a SCALAR ref to the PV, which was fixed later
3771 0 0 0     0 if (ref($ptr) eq 'SCALAR') {
    0          
3772 0         0 $ptrsv = svref_2object($ptr)->save($fullname);
3773             } elsif ($ptr and ref $ptr) {
3774 0         0 $ptrsv = $ptr->save($fullname);
3775             } else {
3776 0         0 $ptrsv = 'NULL';
3777             }
3778 0 0       0 warn "MG->PTR is an SV*\n" if $debug{mg};
3779 0         0 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, (char *)%s, %d);",
3780             $$sv, $$obj, cchar($type), $ptrsv, $len));
3781 0 0       0 if (!($mg->FLAGS & 2)) {
3782 0         0 mg_RC_off($mg, $sv, $type);
3783             }
3784             }
3785             # coverage $Template::Stash::PRIVATE
3786             elsif ( $type eq 'r' ) { # qr magic, for 5.6 done in C.xs. test 20
3787 0 0       0 my $rx = $PERL56 ? ${$mg->OBJ} : $mg->REGEX;
  0         0  
3788             # stored by some PMOP *pm = cLOGOP->op_other (pp_ctl.c) in C.xs
3789 0         0 my $pmop = $Regexp{$rx};
3790 0 0       0 if (!$pmop) {
3791 0         0 warn "Warning: C.xs PMOP missing for QR\n";
3792             } else {
3793 0         0 my ($resym, $relen);
3794 0 0       0 if ($PERL56) {
3795 0         0 ($resym, $relen) = savere( $pmop->precomp ); # 5.6 has precomp only in PMOP
3796 0 0       0 ($resym, $relen) = savere( $mg->precomp ) unless $relen;
3797             } else {
3798 0         0 ($resym, $relen) = savere( $mg->precomp );
3799             }
3800 0         0 my $pmsym = $pmop->save(0, $fullname);
3801 0 0       0 if ($PERL510) {
3802 0         0 push @B::C::static_free, $resym;
3803 0         0 $init->add( split /\n/,
3804             sprintf <pmflags, $$sv, cchar($type), cstring($ptr), $len );
3805             {
3806             REGEXP* rx = CALLREGCOMP((SV* const)%s, %d);
3807             sv_magic((SV*)s\\_%x, (SV*)rx, %s, %s, %d);
3808             }
3809             CODE1
3810             }
3811             else {
3812 0         0 $pmsym =~ s/\(OP\*\)\&pmop_list/&pmop_list/;
3813 0         0 $init->add( split /\n/,
3814             sprintf <
3815             {
3816             REGEXP* rx = pregcomp((char*)$resym,(char*)($resym + $relen), (PMOP*)$pmsym);
3817             sv_magic((SV*)s\\_%x, (SV*)rx, %s, %s, %d);
3818             }
3819             CODE2
3820             }
3821             }
3822             }
3823             elsif ( $type eq 'D' ) { # XXX regdata AV - coverage? i95, 903
3824             # see Perl_mg_copy() in mg.c
3825 0 0       0 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
3826             $$sv, $fullname eq 'main::-' ? 0 : $$sv, "'D'", cstring($ptr), $len ));
3827             }
3828             elsif ( $type eq 'n' ) { # shared_scalar is from XS dist/threads-shared
3829             # XXX check if threads is loaded also? otherwise it is only stubbed
3830 0         0 mark_threads;
3831 0         0 $init->add(sprintf("sv_magic((SV*)s\\_%x, Nullsv, %s, %s, %d);",
3832             $$sv, "'n'", cstring($ptr), $len ));
3833             }
3834             elsif ( $type eq 'c' ) { # and !$PERL518
3835 0         0 $init->add(sprintf(
3836             "/* AMT overload table for the stash %s s\\_%x is generated dynamically */",
3837             $fullname, $$sv ));
3838             }
3839             elsif ( $type eq ':' ) { # symtab magic
3840             # search $ptr in list of pmops and replace it. e.g. (char*)&pmop_list[0]
3841 0         0 my $pmop_ptr = unpack("J", $mg->PTR);
3842 0         0 my $pmop;
3843 0 0       0 $pmop = $B::C::Regexp{$pmop_ptr} if defined $pmop_ptr;
3844 0 0       0 my $pmsym = $pmop ? $pmop->save(0, $fullname)
3845             : ''; #sprintf('&pmop_list[%u]', $pmopsect->index);
3846 0 0 0     0 warn sprintf("pmop 0x%x not found in our B::C Regexp hash\n", $pmop_ptr || 'undef')
      0        
3847             if !$pmop and $verbose;
3848 0 0       0 $init->add("{\tU32 elements;", # toke.c: PL_multi_open == '?'
    0          
3849             sprintf("\tMAGIC *mg = sv_magicext((SV*)s\\_%x, 0, ':', 0, 0, 0);", $$sv),
3850             "\telements = mg->mg_len / sizeof(PMOP**);",
3851             "\tRenewc(mg->mg_ptr, elements + 1, PMOP*, char);",
3852             ($pmop
3853             ? (sprintf("\t((OP**)mg->mg_ptr) [elements++] = (OP*)%s;", $pmsym))
3854             : ( defined $pmop_ptr
3855             ? sprintf( "\t((OP**)mg->mg_ptr) [elements++] = (OP*)s\\_%x;", $pmop_ptr ) : '' )),
3856             "\tmg->mg_len = elements * sizeof(PMOP**);", "}");
3857             }
3858             else {
3859 0         0 $init->add(sprintf(
3860             "sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
3861             $$sv, $$obj, cchar($type), cstring($ptr), $len));
3862 0 0       0 if (!($mg->FLAGS & 2)) {
3863 0         0 mg_RC_off($mg, $sv, $type);
3864             }
3865             }
3866             }
3867 0 0 0     0 $init->add(sprintf("SvREADONLY_on((SV*)s\\_%x);", $$sv))
3868             if $sv_flags & SVf_READONLY and ref($sv) ne 'B::HV';
3869 0         0 $magic;
3870             }
3871              
3872             # Since 5.11 also called by IV::save (SV -> IV)
3873             sub B::RV::save {
3874 0     0   0 my ($sv, $fullname) = @_;
3875 0         0 my $sym = objsym($sv);
3876 0 0       0 return $sym if defined $sym;
3877             warn sprintf( "Saving RV %s (0x%x) - called from %s:%s\n",
3878 0         0 B::class($sv), $$sv, @{[(caller(1))[3]]}, @{[(caller(1))[2]]})
  0         0  
3879 0 0       0 if $debug{sv};
3880              
3881 0         0 my $rv = save_rv($sv, $fullname);
3882 0 0       0 return '0' unless $rv;
3883 0 0       0 if ($PERL510) {
3884 0         0 $svsect->comment( "any, refcnt, flags, sv_u" );
3885             # 5.22 has a wrong RV->FLAGS (https://github.com/perl11/cperl/issues/63)
3886 0         0 my $flags = $sv->FLAGS;
3887 0 0 0     0 $flags = 0x801 if $flags & 9 and $PERL522; # not a GV but a ROK IV (21)
3888             # 5.10 has no struct xrv anymore, just sv_u.svu_rv. static or dynamic?
3889             # initializer element is computable at load time
3890 0 0 0     0 $svsect->add( sprintf( "ptr_undef, $u32fmt, 0x%x, {%s}", $sv->REFCNT, $flags,
3891             (($C99 && is_constant($rv)) ? ".svu_rv=$rv" : "0 /*-> $rv */")));
3892 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3893 0         0 my $s = "sv_list[".$svsect->index."]";
3894             # 354 defined needs SvANY
3895 0 0 0     0 $init->add( sprintf("$s.sv_any = (char*)&$s - %d;", $Config{ptrsize}))
3896             if $] > 5.019 or $ITHREADS;
3897 0 0 0     0 unless ($C99 && is_constant($rv)) {
3898 0 0       0 if ( $rv =~ /get_cv/ ) {
3899 0         0 $init2->add( "$s.sv_u.svu_rv = (SV*)$rv;" ) ;
3900             } else {
3901 0         0 $init->add( "$s.sv_u.svu_rv = (SV*)$rv;" ) ;
3902             }
3903             }
3904 0         0 return savesym( $sv, "&".$s );
3905             }
3906             else {
3907             # GVs need to be handled at runtime
3908 0 0 0     0 if ( ref( $sv->RV ) eq 'B::GV' or $rv =~ /^gv_list/) {
    0 0        
    0          
3909 0         0 $xrvsect->add("Nullsv /* $rv */");
3910 0         0 $init->add(
3911             sprintf( "xrv_list[%d].xrv_rv = (SV*)%s;", $xrvsect->index, $rv ) );
3912             }
3913             # and stashes, too
3914             elsif ( $sv->RV->isa('B::HV') && $sv->RV->NAME ) {
3915 0         0 $xrvsect->add("Nullsv /* $rv */");
3916 0         0 $init->add(
3917             sprintf( "xrv_list[%d].xrv_rv = (SV*)%s;", $xrvsect->index, $rv ) );
3918             }
3919             # one more: bootstrapped XS CVs (test Class::MOP, no simple testcase yet)
3920             # dynamic; so we need to inc it
3921             elsif ( $rv =~ /get_cv/ ) {
3922 0         0 $xrvsect->add("Nullsv /* $rv */");
3923 0         0 $init2->add(
3924             sprintf( "xrv_list[%d].xrv_rv = (SV*)SvREFCNT_inc(%s);", $xrvsect->index, $rv ) );
3925             }
3926             else {
3927             #$xrvsect->add($rv); # not static initializable (e.g. cv160 for ExtUtils::Install)
3928 0         0 $xrvsect->add("Nullsv /* $rv */");
3929 0         0 $init->add(
3930             sprintf( "xrv_list[%d].xrv_rv = (SV*)SvREFCNT_inc(%s);", $xrvsect->index, $rv ) );
3931             }
3932 0         0 $svsect->comment( "any, refcnt, flags" );
3933 0         0 $svsect->add(sprintf("&xrv_list[%d], $u32fmt, 0x%x",
3934             $xrvsect->index, $sv->REFCNT, $sv->FLAGS));
3935 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3936 0         0 my $s = "sv_list[".$svsect->index."]";
3937 0         0 return savesym( $sv, "&".$s );
3938             }
3939             }
3940              
3941             sub get_isa ($) {
3942 0     0 0 0 my $name = shift;
3943 0 0       0 if ($PERL510) {
3944 0 0       0 if (is_using_mro()) { # mro.xs loaded. c3 or dfs
3945 0         0 return @{mro::get_linear_isa($name)};
  0         0  
3946             } else { # dfs only, without loading mro
3947 0         0 return @{B::C::get_linear_isa($name)};
  0         0  
3948             }
3949             } else {
3950 55     55   446 no strict 'refs';
  55         87  
  55         7511  
3951 0         0 my $s = "$name\::";
3952 0 0       0 if (exists(${$s}{ISA})) {
  0         0  
3953 0 0       0 if (exists(${$s}{ISA}{ARRAY})) {
  0         0  
3954 0         0 return @{ "$s\::ISA" };
  0         0  
3955             }
3956             }
3957             }
3958             }
3959              
3960             # try_isa($pkg,$name) returns the found $pkg for the method $pkg::$name
3961             # If a method can be called (via UNIVERSAL::can) search the ISA's. No AUTOLOAD needed.
3962             # XXX issue 64, empty @ISA if a package has no subs. in Bytecode ok
3963             sub try_isa {
3964 0     0 0 0 my ( $cvstashname, $cvname ) = @_;
3965 0 0 0     0 return 0 unless defined $cvstashname && defined $cvname;
3966 0 0       0 if (my $found = $isa_cache{"$cvstashname\::$cvname"}) {
3967 0         0 return $found;
3968             }
3969 55     55   244 no strict 'refs';
  55         75  
  55         23868  
3970             # XXX theoretically a valid shortcut. In reality it fails when $cvstashname is not loaded.
3971             # return 0 unless $cvstashname->can($cvname);
3972 0         0 my @isa = get_isa($cvstashname);
3973             warn sprintf( "No definition for sub %s::%s. Try \@%s::ISA=(%s)\n",
3974             $cvstashname, $cvname, $cvstashname, join(",",@isa))
3975 0 0       0 if $debug{cv};
3976 0         0 for (@isa) { # global @ISA or in pad
3977 0 0       0 next if $_ eq $cvstashname;
3978 0 0       0 warn sprintf( "Try &%s::%s\n", $_, $cvname ) if $debug{cv};
3979 0 0       0 if (defined(&{$_ .'::'. $cvname})) {
  0         0  
3980 0 0       0 if (exists(${$cvstashname.'::'}{ISA})) {
  0         0  
3981 0         0 svref_2object( \@{$cvstashname . '::ISA'} )->save("$cvstashname\::ISA");
  0         0  
3982             }
3983 0         0 $isa_cache{"$cvstashname\::$cvname"} = $_;
3984 0         0 mark_package($_, 1); # force
3985 0         0 return $_;
3986             } else {
3987 0         0 $isa_cache{"$_\::$cvname"} = 0;
3988 0 0       0 if (get_isa($_)) {
3989 0         0 my $parent = try_isa($_, $cvname);
3990 0 0       0 if ($parent) {
3991 0         0 $isa_cache{"$_\::$cvname"} = $parent;
3992 0         0 $isa_cache{"$cvstashname\::$cvname"} = $parent;
3993 0 0       0 warn sprintf( "Found &%s::%s\n", $parent, $cvname ) if $debug{gv};
3994 0 0       0 if (exists(${$parent.'::'}{ISA})) {
  0         0  
3995 0 0       0 warn "save \@$parent\::ISA\n" if $debug{pkg};
3996 0         0 svref_2object( \@{$parent . '::ISA'} )->save("$parent\::ISA");
  0         0  
3997             }
3998 0 0       0 if (exists(${$_.'::'}{ISA})) {
  0         0  
3999 0 0       0 warn "save \@$_\::ISA\n" if $debug{pkg};
4000 0         0 svref_2object( \@{$_ . '::ISA'} )->save("$_\::ISA");
  0         0  
4001             }
4002 0         0 return $parent;
4003             }
4004             }
4005             }
4006             }
4007 0         0 return 0; # not found
4008             }
4009              
4010             sub load_utf8_heavy {
4011 0 0   0 0 0 return if $savINC{"utf8_heavy.pl"};
4012              
4013 0         0 require 'utf8_heavy.pl';
4014 0         0 mark_package('utf8_heavy.pl');
4015 0         0 $curINC{'utf8_heavy.pl'} = $INC{'utf8_heavy.pl'};
4016 0         0 $savINC{"utf8_heavy.pl"} = 1;
4017 0         0 add_hashINC("utf8");
4018              
4019             # FIXME: we want to use add_hashINC for utf8_heavy, inc_packname should return an array
4020             # add_hashINC("utf8_heavy.pl");
4021              
4022             # In CORE utf8::SWASHNEW is demand-loaded from utf8 with Perl_load_module()
4023             # It adds about 1.6MB exe size 32-bit.
4024 0         0 svref_2object( \&{"utf8\::SWASHNEW"} )->save;
  0         0  
4025              
4026 0         0 return 1;
4027             }
4028              
4029             # If the sub or method is not found:
4030             # 1. try @ISA, mark_package and return.
4031             # 2. try UNIVERSAL::method
4032             # 3. try compile-time expansion of AUTOLOAD to get the goto &sub addresses
4033             sub try_autoload {
4034 0     0 0 0 my ( $cvstashname, $cvname ) = @_;
4035 55     55   244 no strict 'refs';
  55         89  
  55         2342  
4036 0 0 0     0 return unless defined $cvstashname && defined $cvname;
4037 0 0       0 return 1 if try_isa($cvstashname, $cvname);
4038              
4039 55     55   193 no strict 'refs';
  55         78  
  55         57212  
4040 0 0       0 if (defined(*{'UNIVERSAL::'. $cvname}{CODE})) {
  0         0  
4041 0 0       0 warn "Found UNIVERSAL::$cvname\n" if $debug{cv};
4042 0         0 return svref_2object( \&{'UNIVERSAL::'.$cvname} );
  0         0  
4043             }
4044 0         0 my $fullname = $cvstashname . '::' . $cvname;
4045             warn sprintf( "No definition for sub %s. Try %s::AUTOLOAD\n",
4046 0 0       0 $fullname, $cvstashname ) if $debug{cv};
4047 0 0       0 if ($fullname eq 'utf8::SWASHNEW') {
4048             # utf8_heavy was loaded so far, so defer to a demand-loading stub
4049             # always require utf8_heavy, do not care if it s already in
4050 0     0   0 my $stub = sub { require 'utf8_heavy.pl'; goto &utf8::SWASHNEW };
  0         0  
  0         0  
4051 0         0 return svref_2object( $stub );
4052             }
4053              
4054             # Handle AutoLoader classes. Any more general AUTOLOAD
4055             # use should be handled by the class itself.
4056 0         0 my @isa = get_isa($cvstashname);
4057 0 0 0     0 if ( $cvstashname =~ /^POSIX|Storable|DynaLoader|Net::SSLeay|Class::MethodMaker$/
      0        
4058 0         0 or (exists ${$cvstashname.'::'}{AUTOLOAD} and grep( $_ eq "AutoLoader", @isa ) ) )
4059             {
4060             # Tweaked version of AutoLoader::AUTOLOAD
4061 0         0 my $dir = $cvstashname;
4062 0         0 $dir =~ s(::)(/)g;
4063 0 0       0 warn "require \"auto/$dir/$cvname.al\"\n" if $debug{cv};
4064 0 0       0 eval { local $SIG{__DIE__}; require "auto/$dir/$cvname.al" unless $INC{"auto/$dir/$cvname.al"} };
  0         0  
  0         0  
4065 0 0       0 unless ($@) {
4066 0 0       0 warn "Forced load of \"auto/$dir/$cvname.al\"\n" if $verbose;
4067 0 0       0 return svref_2object( \&$fullname )
4068             if defined &$fullname;
4069             }
4070             }
4071              
4072             # XXX Still not found, now it's getting dangerous (until 5.10 only)
4073             # Search and call ::AUTOLOAD (=> ROOT and XSUB) (test 27, 5.8)
4074             # Since 5.10 AUTOLOAD xsubs are already resolved
4075 0 0 0     0 if (exists ${$cvstashname.'::'}{AUTOLOAD} and !$PERL510) {
  0         0  
4076 0         0 my $auto = \&{$cvstashname.'::AUTOLOAD'};
  0         0  
4077             # Tweaked version of __PACKAGE__::AUTOLOAD
4078 0         0 $AutoLoader::AUTOLOAD = ${$cvstashname.'::AUTOLOAD'} = "$cvstashname\::$cvname";
  0         0  
4079              
4080             # Prevent eval from polluting STDOUT,STDERR and our c code.
4081             # With a debugging perl STDERR is written
4082 0         0 local *REALSTDOUT;
4083 0 0       0 local *REALSTDERR unless $DEBUGGING;
4084 0         0 open(REALSTDOUT,">&STDOUT");
4085 0 0       0 open(REALSTDERR,">&STDERR") unless $DEBUGGING;
4086 0         0 open(STDOUT,">","/dev/null");
4087 0 0       0 open(STDERR,">","/dev/null") unless $DEBUGGING;
4088 0 0       0 warn "eval \&$cvstashname\::AUTOLOAD\n" if $debug{cv};
4089 0         0 eval { &$auto };
  0         0  
4090 0         0 open(STDOUT,">&REALSTDOUT");
4091 0 0       0 open(STDERR,">&REALSTDERR") unless $DEBUGGING;
4092              
4093 0 0       0 unless ($@) {
4094             # we need just the empty auto GV, $cvname->ROOT and $cvname->XSUB,
4095             # but not the whole CV optree. XXX This still fails with 5.8
4096 0         0 my $cv = svref_2object( \&{$fullname} );
  0         0  
4097 0         0 return $cv;
4098             }
4099             }
4100              
4101             # XXX TODO Check Selfloader (test 31?)
4102 0         0 svref_2object( \*{$cvstashname.'::AUTOLOAD'} )->save
4103 0 0 0     0 if $cvstashname and exists ${$cvstashname.'::'}{AUTOLOAD};
  0         0  
4104 0         0 svref_2object( \*{$cvstashname.'::CLONE'} )->save
4105 0 0 0     0 if $cvstashname and exists ${$cvstashname.'::'}{CLONE};
  0         0  
4106             }
4107       0 0   sub Dummy_initxs { }
4108              
4109             sub B::CV::is_lexsub {
4110 0     0   0 my ($cv, $gv) = @_;
4111             # logical shortcut perl5 bug since ~ 5.19: testcc.sh 42
4112             # return ($PERL518 and (!$gv or ref($gv) eq 'B::SPECIAL') and $cv->can('NAME_HEK'));
4113 0 0 0     0 return ($PERL518 and (!$gv or ref($gv) eq 'B::SPECIAL') and $cv->can('NAME_HEK')) ? 1 : 0;
4114             }
4115              
4116             sub is_phase_name {
4117 0 0   0 0 0 $_[0] =~ /^(BEGIN|INIT|UNITCHECK|CHECK|END)$/ ? 1 : 0;
4118             }
4119              
4120             sub B::CV::save {
4121 0     0   0 my ($cv, $origname) = @_;
4122 0         0 my $sym = objsym($cv);
4123 0 0       0 if ( defined($sym) ) {
4124 0 0 0     0 warn sprintf( "CV 0x%x already saved as $sym\n", $$cv ) if $$cv and $debug{cv};
4125 0         0 return $sym;
4126             }
4127 0         0 my $gv = $cv->GV;
4128 0         0 my ( $cvname, $cvstashname, $fullname, $isutf8 );
4129 0         0 $fullname = '';
4130 0         0 my $CvFLAGS = $cv->CvFLAGS;
4131 0 0 0     0 if ($gv and $$gv) {
    0          
4132 0         0 $cvstashname = $gv->STASH->NAME;
4133 0         0 $cvname = $gv->NAME;
4134 0   0     0 $isutf8 = ($gv->FLAGS & SVf_UTF8) || ($gv->STASH->FLAGS & SVf_UTF8);
4135 0         0 $fullname = $cvstashname.'::'.$cvname;
4136             # XXX gv->EGV does not really help here
4137 0 0 0     0 if ($PERL522 and $cvname eq '__ANON__') {
4138 0 0       0 if ($origname) {
4139             warn sprintf( "CV with empty PVGV %s -> %s\n",
4140 0 0       0 $fullname, $origname) if $debug{cv};
4141 0         0 $cvname = $fullname = $origname;
4142 0 0       0 $cvname =~ s/^\Q$cvstashname\E::(.*)( :pad\[.*)?$/$1/ if $cvstashname;
4143 0         0 $cvname =~ s/^.*:://;
4144 0 0       0 if ($cvname =~ m/ :pad\[.*$/) {
4145 0         0 $cvname =~ s/ :pad\[.*$//;
4146 0 0       0 $cvname = '__ANON__' if is_phase_name($cvname);
4147 0         0 $fullname = $cvstashname.'::'.$cvname;
4148             }
4149 0 0       0 warn sprintf( "empty -> %s\n", $cvname) if $debug{cv};
4150             } else {
4151 0         0 $cvname = $gv->EGV->NAME;
4152             warn sprintf( "CV with empty PVGV %s -> %s::%s\n",
4153 0 0       0 $fullname, $cvstashname, $cvname) if $debug{cv};
4154 0         0 $fullname = $cvstashname.'::'.$cvname;
4155             }
4156             }
4157             warn sprintf( "CV 0x%x as PVGV 0x%x %s CvFLAGS=0x%x\n",
4158 0 0       0 $$cv, $$gv, $fullname, $CvFLAGS ) if $debug{cv};
4159             # XXX not needed, we already loaded utf8_heavy
4160             #return if $fullname eq 'utf8::AUTOLOAD';
4161 0 0 0     0 return '0' if $all_bc_subs{$fullname} or skip_pkg($cvstashname);
4162 0 0       0 $CvFLAGS &= ~0x400 if $PERL514; # no CVf_CVGV_RC otherwise we cannot set the GV
4163 0 0       0 mark_package($cvstashname, 1) unless $include_package{$cvstashname};
4164             }
4165             elsif ($cv->is_lexsub($gv)) {
4166 0         0 $fullname = $cv->NAME_HEK;
4167 0 0       0 $fullname = '' unless defined $fullname;
4168 0         0 $isutf8 = $cv->FLAGS & SVf_UTF8;
4169 0 0       0 warn sprintf( "CV lexsub NAME_HEK $fullname\n") if $debug{cv};
4170 0 0       0 if ($fullname =~ /^(.*)::(.*?)$/) {
4171 0         0 $cvstashname = $1;
4172 0         0 $cvname = $2;
4173             }
4174             }
4175 0 0       0 $cvstashname = '' unless defined $cvstashname;
4176              
4177             # XXX TODO need to save the gv stash::AUTOLOAD if exists
4178 0         0 my $root = $cv->ROOT;
4179 0         0 my $cvxsub = $cv->XSUB;
4180 0         0 my $isconst;
4181 55     55   294 { no strict 'subs';
  55         72  
  55         21231  
  0         0  
4182 0 0       0 $isconst = $PERL56 ? 0 : $CvFLAGS & CVf_CONST;
4183             }
4184              
4185 0 0 0     0 if ( !$isconst && $cvxsub && ( $cvname ne "INIT" ) ) {
      0        
4186 0         0 my $egv = $gv->EGV;
4187 0         0 my $stashname = $egv->STASH->NAME;
4188 0         0 $fullname = $stashname.'::'.$cvname;
4189 0 0 0     0 if ( $cvname eq "bootstrap" and !$xsub{$stashname} ) {
4190 0         0 my $file = $gv->FILE;
4191 0         0 $decl->add("/* bootstrap $file */");
4192 0 0       0 warn "Bootstrap $stashname $file\n" if $verbose;
4193 0         0 mark_package($stashname);
4194              
4195             # Without DynaLoader we must boot and link static
4196 0 0 0     0 if ( !$Config{usedl} ) {
    0 0        
4197 0         0 $xsub{$stashname} = 'Static';
4198             }
4199             # if it not isa('DynaLoader'), it should hopefully be XSLoaded
4200             # ( attributes being an exception, of course )
4201             elsif ( !UNIVERSAL::isa( $stashname, 'DynaLoader' )
4202             and ($stashname ne 'attributes' || $] >= 5.011))
4203             {
4204 0         0 my $stashfile = $stashname;
4205 0         0 $stashfile =~ s/::/\//g;
4206 0 0       0 if ($file =~ /XSLoader\.pm$/) { # almost always the case
4207 0         0 $file = $INC{$stashfile . ".pm"};
4208             }
4209 0 0       0 unless ($file) { # do the reverse as DynaLoader: soname => pm
4210 0         0 my ($laststash) = $stashname =~ /::([^:]+)$/;
4211 0 0       0 $laststash = $stashname unless $laststash;
4212 0         0 my $sofile = "auto/" . $stashfile . '/' . $laststash . '\.' . $Config{dlext};
4213 0         0 for (@DynaLoader::dl_shared_objects) {
4214 0 0       0 if (m{^(.+/)$sofile$}) {
4215 0         0 $file = $1. $stashfile.".pm"; last;
  0         0  
4216             }
4217             }
4218             }
4219 0         0 $xsub{$stashname} = 'Dynamic-'.$file;
4220 0         0 force_saving_xsloader();
4221             }
4222             else {
4223 0         0 $xsub{$stashname} = 'Dynamic';
4224             # DynaLoader was for sure loaded, before so we execute the branch which
4225             # does walk_syms and add_hashINC
4226 0         0 mark_package('DynaLoader', 1);
4227             }
4228              
4229             # INIT is removed from the symbol table, so this call must come
4230             # from PL_initav->save. Re-bootstrapping will push INIT back in,
4231             # so nullop should be sent.
4232 0 0       0 warn $fullname."\n" if $debug{sub};
4233 0         0 return qq/NULL/;
4234             }
4235             else {
4236             # XSUBs for IO::File, IO::Handle, IO::Socket, IO::Seekable and IO::Poll
4237             # are defined in IO.xs, so let's bootstrap it
4238 0         0 my @IO = qw(IO::File IO::Handle IO::Socket IO::Seekable IO::Poll);
4239 0 0       0 if (grep { $stashname eq $_ } @IO) {
  0         0  
4240             # mark_package('IO', 1);
4241             # $xsub{IO} = 'Dynamic-'. $INC{'IO.pm'}; # XSLoader (issue59)
4242 0         0 svref_2object( \&IO::bootstrap )->save;
4243 0         0 mark_package('IO::Handle', 1);
4244 0         0 mark_package('SelectSaver', 1);
4245             #for (@IO) { # mark all IO packages
4246             # mark_package($_, 1);
4247             #}
4248             }
4249             }
4250 0 0       0 warn $fullname."\n" if $debug{sub};
4251 0 0       0 unless ( in_static_core($stashname, $cvname) ) {
4252 55     55   259 no strict 'refs';
  55         74  
  55         5690  
4253             warn sprintf( "XSUB $fullname CV 0x%x\n", $$cv )
4254 0 0       0 if $debug{cv};
4255 0 0       0 svref_2object( \*{"$stashname\::bootstrap"} )->save
  0         0  
4256             if $stashname;# and defined ${"$stashname\::bootstrap"};
4257             # delsym($cv);
4258 0         0 return get_cv($fullname, 0);
4259             } else { # Those cvs are already booted. Reuse their GP.
4260             # Esp. on windows it is impossible to get at the XS function ptr
4261 0 0       0 warn sprintf( "core XSUB $fullname CV 0x%x\n", $$cv ) if $debug{cv};
4262 0         0 return get_cv($fullname, 0);
4263             }
4264             }
4265 0 0 0     0 if ( !$isconst && $cvxsub && $cvname eq "INIT" ) {
      0        
4266 55     55   214 no strict 'refs';
  55         75  
  55         48695  
4267 0 0       0 warn $fullname."\n" if $debug{sub};
4268 0         0 return svref_2object( \&Dummy_initxs )->save;
4269             }
4270              
4271             # XXX how is ANON with CONST handled? CONST uses XSUBANY [GH #246]
4272 0 0 0     0 if ($isconst and $cvxsub and !is_phase_name($cvname) and
      0        
      0        
      0        
4273             (
4274             (
4275             $PERL522
4276             and !( $CvFLAGS & SVs_PADSTALE )
4277             and !( $CvFLAGS & CVf_WEAKOUTSIDE )
4278             and !( $fullname && $fullname =~ qr{^File::Glob::GLOB}
4279             and ( $CvFLAGS & (CVf_ANONCONST|CVf_CONST) ) )
4280             )
4281             or (!$PERL522 and !($CvFLAGS & CVf_ANON)) )
4282             ) # skip const magic blocks (Attribute::Handlers)
4283             {
4284 0         0 my $stash = $gv->STASH;
4285             #warn sprintf("$cvstashname\::$cvname 0x%x -> XSUBANY", $CvFLAGS) if $debug{cv};
4286 0         0 my $sv = $cv->XSUBANY;
4287             warn sprintf( "CV CONST 0x%x %s::%s -> 0x%x as %s\n", $$gv, $cvstashname, $cvname,
4288 0 0       0 $sv, ref $sv) if $debug{cv};
4289             # warn sprintf( "%s::%s\n", $cvstashname, $cvname) if $debug{sub};
4290 0         0 my $stsym = $stash->save;
4291 0         0 my $name = cstring($cvname);
4292 0 0       0 if ($] >= 5.016) { # need to check 'Encode::XS' constant encodings
4293             # warn "$sv CONSTSUB $name";
4294 0 0 0     0 if ((ref($sv) eq 'B::IV' or ref($sv) eq 'B::PVMG') and $sv->FLAGS & SVf_ROK) {
      0        
4295 0         0 my $rv = $sv->RV;
4296 0 0 0     0 if ($rv->FLAGS & (SVp_POK|SVf_IOK) and $rv->IVX > LOWEST_IMAGEBASE) {
4297 0         0 patch_dlsym($rv, $fullname, $rv->IVX);
4298             }
4299             }
4300             }
4301             # scalarref: t/CORE/v5.22/t/op/const-optree.t at curpad_syms[6]
4302             # main::__ANON__ -> CxPOPSUB_DONE=SCALAR
4303             # TODO Attribute::Handlers #171, test 176
4304 0 0 0     0 if ($sv and ref($sv) and ref($sv) =~ /^(SCALAR|ARRAY|HASH|CODE|REF)$/) {
    0 0        
      0        
4305             # Save XSUBANY, maybe ARRAY or HASH also?
4306 0 0       0 warn "SCALAR const sub $cvstashname::$cvname -> $sv\n" if $debug{cv};
4307 0         0 my $vsym = svref_2object( \$sv )->save;
4308 0         0 my $cvi = "cv".$cv_index++;
4309 0         0 $decl->add("Static CV* $cvi;");
4310 0         0 $init->add("$cvi = newCONSTSUB( $stsym, $name, (SV*)$vsym );");
4311 0         0 return savesym( $cv, $cvi );
4312             }
4313             elsif ($sv and ref($sv) =~ /^B::[ANRPI]/) { # use constant => ()
4314 0         0 my $vsym = $sv->save;
4315 0         0 my $cvi = "cv".$cv_index++;
4316 0         0 $decl->add("Static CV* $cvi;");
4317 0         0 $init->add("$cvi = newCONSTSUB( $stsym, $name, (SV*)$vsym );");
4318 0         0 return savesym( $cv, $cvi );
4319             } else {
4320 0 0       0 warn "Warning: Undefined const sub $cvstashname::$cvname -> $sv\n" if $verbose;
4321             }
4322             }
4323              
4324             # This define is forwarded to the real sv below
4325             # The new method, which saves a SV only works since 5.10 (? Does not work in newer perls)
4326 0         0 my $sv_ix = $svsect->index + 1;
4327 0         0 my $xpvcv_ix;
4328 0         0 my $new_cv_fw = 0;#$PERL510; # XXX this does not work yet
4329 0 0       0 if ($new_cv_fw) {
4330 0         0 $sym = savesym( $cv, "CVIX$sv_ix" );
4331             } else {
4332 0         0 $svsect->add("CVIX$sv_ix");
4333 0 0       0 $svsect->debug( "&".$fullname, $cv->flagspv ) if $debug{flags};
4334 0         0 $xpvcv_ix = $xpvcvsect->index + 1;
4335 0         0 $xpvcvsect->add("XPVCVIX$xpvcv_ix");
4336             # Save symbol now so that GvCV() doesn't recurse back to us via CvGV()
4337 0         0 $sym = savesym( $cv, "&sv_list[$sv_ix]" );
4338             }
4339              
4340             warn sprintf( "saving %s CV 0x%x as %s\n", $fullname, $$cv, $sym )
4341 0 0       0 if $debug{cv};
4342 0 0 0     0 if (!$$root and $] < 5.010) {
4343 0         0 $package_pv = $cvstashname;
4344 0         0 push_package($package_pv);
4345             }
4346 0 0       0 if ($fullname eq 'utf8::SWASHNEW') { # bypass utf8::AUTOLOAD, a new 5.13.9 mess
4347 0         0 load_utf8_heavy();
4348             }
4349              
4350 0 0       0 if ($fullname eq 'IO::Socket::SSL::SSL_Context::new') {
4351 0 0 0     0 if ($IO::Socket::SSL::VERSION ge '1.956' and $IO::Socket::SSL::VERSION lt '1.995') {
4352             # See https://code.google.com/p/perl-compiler/issues/detail?id=317
4353             # https://rt.cpan.org/Ticket/Display.html?id=95452
4354 0         0 warn "Warning: Your IO::Socket::SSL version $IO::Socket::SSL::VERSION is unsupported to create\n".
4355             " a server. You need to upgrade IO::Socket::SSL to at least 1.995 [CPAN #95452]\n";
4356             }
4357             }
4358              
4359 0 0 0     0 if (!$$root && !$cvxsub) {
4360 0         0 my $reloaded;
4361 0 0       0 if ($cvstashname =~ /^(bytes|utf8)$/) { # no autoload, force compile-time
    0          
4362 0         0 force_heavy($cvstashname);
4363 0         0 $cv = svref_2object( \&{"$cvstashname\::$cvname"} );
  0         0  
4364 0         0 $reloaded = 1;
4365             } elsif ($fullname eq 'Coro::State::_jit') { # 293
4366             # need to force reload the jit src
4367 0         0 my ($pl) = grep { m|^Coro/jit-| } keys %INC;
  0         0  
4368 0 0       0 if ($pl) {
4369 0         0 delete $INC{$pl};
4370 0         0 require $pl;
4371 0         0 $cv = svref_2object( \&{$fullname} );
  0         0  
4372 0         0 $reloaded = 1;
4373             }
4374             }
4375 0 0       0 if ($reloaded) {
4376 0         0 $gv = $cv->GV;
4377             warn sprintf( "Redefined CV 0x%x as PVGV 0x%x %s CvFLAGS=0x%x\n",
4378 0 0       0 $$cv, $$gv, $fullname, $CvFLAGS ) if $debug{cv};
4379 0         0 $sym = savesym( $cv, $sym );
4380 0         0 $root = $cv->ROOT;
4381 0         0 $cvxsub = $cv->XSUB;
4382             }
4383             }
4384 0 0 0     0 if ( !$$root && !$cvxsub ) {
4385 0 0       0 if ( my $auto = try_autoload( $cvstashname, $cvname ) ) {
4386 0 0       0 if (ref $auto eq 'B::CV') { # explicit goto or UNIVERSAL
4387 0         0 $root = $auto->ROOT;
4388 0         0 $cvxsub = $auto->XSUB;
4389 0 0       0 if ($$auto) {
4390             # XXX This has now created a wrong GV name!
4391 0         0 my $oldcv = $cv;
4392 0         0 $cv = $auto ; # This is new. i.e. via AUTOLOAD or UNIVERSAL, in another stash
4393 0         0 my $gvnew = $cv->GV;
4394 0 0       0 if ($$gvnew) {
4395 0 0 0     0 if ($cvstashname ne $gvnew->STASH->NAME or $cvname ne $gvnew->NAME) { # UNIVERSAL or AUTOLOAD
4396 0         0 my $newname = $gvnew->STASH->NAME."::".$gvnew->NAME;
4397 0 0       0 warn " New $newname autoloaded. remove old cv\n" if $debug{sub}; # and wrong GV?
4398 0 0       0 unless ($new_cv_fw) {
4399 0         0 $svsect->remove;
4400 0         0 $xpvcvsect->remove;
4401             }
4402 0         0 delsym($oldcv);
4403 0 0       0 return $cv->save($newname) if !$PERL510;
4404              
4405 55     55   272 no strict 'refs';
  55         71  
  55         266326  
4406 0         0 my $newsym = svref_2object( \*{$newname} )->save;
  0         0  
4407 0 0       0 my $cvsym = defined objsym($cv) ? objsym($cv) : $cv->save($newname);
4408 0 0       0 if (my $oldsym = objsym($gv)) {
4409 0 0       0 warn "Alias polluted $oldsym to $newsym\n" if $debug{gv};
4410 0         0 $init->add("$oldsym = $newsym;");
4411 0         0 delsym($gv);
4412             }# else {
4413             #$init->add("GvCV_set(gv_fetchpv(\"$fullname\", GV_ADD, SVt_PV), (CV*)NULL);");
4414             #}
4415 0         0 return $cvsym;
4416             }
4417             }
4418 0         0 $sym = savesym( $cv, "&sv_list[$sv_ix]" ); # GOTO
4419 0 0       0 warn "$fullname GOTO\n" if $verbose;
4420             }
4421             } else {
4422             # Recalculated root and xsub
4423 0         0 $root = $cv->ROOT;
4424 0         0 $cvxsub = $cv->XSUB;
4425 0         0 my $gv = $cv->GV;
4426 0 0       0 if ($$gv) {
4427 0 0 0     0 if ($cvstashname ne $gv->STASH->NAME or $cvname ne $gv->NAME) { # UNIVERSAL or AUTOLOAD
4428 0         0 my $newname = $gv->STASH->NAME."::".$gv->NAME;
4429 0 0       0 warn "Recalculated root and xsub $newname. remove old cv\n" if $verbose;
4430 0         0 $svsect->remove;
4431 0         0 $xpvcvsect->remove;
4432 0         0 delsym($cv);
4433 0         0 return $cv->save($newname);
4434             }
4435             }
4436             }
4437 0 0 0     0 if ( $$root || $cvxsub ) {
4438 0 0 0     0 warn "Successful forced autoload\n" if $verbose and $debug{cv};
4439             }
4440             }
4441             }
4442 0 0       0 if (!$$root) {
4443 0 0 0     0 if ($fullname ne 'threads::tid'
      0        
      0        
4444             and $fullname ne 'main::main::'
4445 0         0 and ($PERL510 and !defined(&{"$cvstashname\::AUTOLOAD"})))
4446             {
4447             # XXX What was here?
4448             }
4449 0 0       0 if (exists &$fullname) {
    0          
4450 0 0       0 warn "Warning: Empty &".$fullname."\n" if $debug{sub};
4451 0 0 0     0 $init->add( "/* empty CV $fullname */" ) if $verbose or $debug{sub};
4452             } elsif ($cv->is_lexsub($gv)) {
4453             # need to find the attached lexical sub (#130 + #341) at run-time
4454             # in the PadNAMES array. So keep the empty PVCV
4455 0 0       0 warn "lexsub &".$fullname." saved as empty $sym\n" if $debug{sub};
4456             } else {
4457 0 0       0 warn "Warning: &".$fullname." not found\n" if $debug{sub};
4458 0 0 0     0 $init->add( "/* CV $fullname not found */" ) if $verbose or $debug{sub};
4459             # This block broke test 15, disabled
4460 0 0 0     0 if ($sv_ix == $svsect->index and !$new_cv_fw) { # can delete, is the last SV
4461             warn "No definition for sub $fullname (unable to autoload), skip CV[$sv_ix]\n"
4462 0 0       0 if $debug{cv};
4463 0         0 $svsect->remove;
4464 0         0 $xpvcvsect->remove;
4465 0         0 delsym( $cv );
4466             # Empty CV (methods) must be skipped not to disturb method resolution
4467             # (e.g. t/testm.sh POSIX)
4468 0         0 return '0';
4469             } else {
4470             # interim &AUTOLOAD saved, cannot delete. e.g. Fcntl, POSIX
4471             warn "No definition for sub $fullname (unable to autoload), stub CV[$sv_ix]\n"
4472 0 0 0     0 if $debug{cv} or $verbose;
4473             # continue, must save the 2 symbols from above
4474             }
4475             }
4476             }
4477              
4478 0         0 my $startfield = 0;
4479 0         0 my $padlist = $cv->PADLIST;
4480 0         0 set_curcv $cv;
4481 0         0 my $padlistsym = 'NULL';
4482 0         0 my $pv = $cv->PV;
4483 0         0 my $xsub = 0;
4484 0         0 my $xsubany = "{0}";
4485 0 0       0 if ($$root) {
    0          
    0          
4486             warn sprintf( "saving op tree for CV 0x%x, root=0x%x\n",
4487             $$cv, $$root )
4488 0 0 0     0 if $debug{cv} and $debug{gv};
4489 0         0 my $ppname = "";
4490 0 0 0     0 if ($cv->is_lexsub($gv)) {
    0          
4491 0 0       0 my $name = $cv->can('NAME_HEK') ? $cv->NAME_HEK : "anonlex";
4492 0         0 $ppname = "pp_lexsub_".$name;
4493 0         0 $fullname = "".$name;
4494             }
4495             elsif ($gv and $$gv) {
4496 0         0 my ($stashname, $gvname);
4497 0         0 $stashname = $gv->STASH->NAME;
4498 0         0 $gvname = $gv->NAME;
4499 0         0 $fullname = $stashname.'::'.$gvname;
4500 0 0       0 $ppname = ( ${ $gv->FORM } == $$cv ) ? "pp_form_" : "pp_sub_";
  0         0  
4501 0 0       0 if ( $gvname ne "__ANON__" ) {
4502 0 0       0 $ppname .= ( $stashname eq "main" ) ? $gvname : "$stashname\::$gvname";
4503 0         0 $ppname =~ s/::/__/g;
4504 0         0 $ppname =~ s/(\W)/sprintf("0x%x", ord($1))/ge;
  0         0  
4505 0 0       0 if ( $gvname eq "INIT" ) {
4506 0         0 $ppname .= "_$initsub_index";
4507 0         0 $initsub_index++;
4508             }
4509             }
4510             }
4511 0 0       0 if ( !$ppname ) {
4512 0         0 $ppname = "pp_anonsub_$anonsub_index";
4513 0         0 $anonsub_index++;
4514             }
4515 0         0 $startfield = saveoptree( $ppname, $root, $cv->START, $padlist->ARRAY ); # XXX padlist is ignored
4516             #warn sprintf( "done saving op tree for CV 0x%x, flags (%s), name %s, root=0x%x => start=%s\n",
4517             # $$cv, $debug{flags}?$cv->flagspv:sprintf("0x%x",$cv->FLAGS), $ppname, $$root, $startfield )
4518             # if $debug{cv};
4519             # XXX missing cv_start for AUTOLOAD on 5.8
4520 0 0       0 $startfield = objsym($root->next) unless $startfield; # 5.8 autoload has only root
4521 0 0       0 $startfield = "0" unless $startfield; # XXX either CONST ANON or empty body
4522 0 0       0 if ($$padlist) {
4523             # XXX readonly comppad names and symbols invalid
4524             #local $B::C::pv_copy_on_grow = 1 if $B::C::ro_inc;
4525             warn sprintf( "saving PADLIST 0x%x for CV 0x%x\n", $$padlist, $$cv )
4526 0 0 0     0 if $debug{cv} and $debug{gv};
4527             # XXX avlen 2
4528 0         0 $padlistsym = $padlist->save($fullname.' :pad', $cv);
4529             warn sprintf( "done saving %s 0x%x for CV 0x%x\n",
4530             $padlistsym, $$padlist, $$cv )
4531 0 0 0     0 if $debug{cv} and $debug{gv};
4532             # do not record a forward for the pad only
4533              
4534             # issue 298: dynamic CvPADLIST(&END) since 5.18 - END{} blocks
4535             # and #169 and #304 Attribute::Handlers
4536 0 0 0     0 if ($] > 5.017 and
      0        
4537             ($B::C::dyn_padlist or $fullname =~ /^(main::END|main::INIT|Attribute::Handlers)/))
4538             {
4539 0         0 $init->add("{ /* &$fullname needs a dynamic padlist */",
4540             " PADLIST *pad;",
4541             " Newxz(pad, sizeof(PADLIST), PADLIST);",
4542             " Copy($padlistsym, pad, sizeof(PADLIST), char);",
4543             " CvPADLIST($sym) = pad;",
4544             "}");
4545             } else {
4546 0         0 $init->add( "CvPADLIST($sym) = $padlistsym;" );
4547             }
4548             }
4549 0 0       0 warn $fullname."\n" if $debug{sub};
4550             }
4551             elsif ($cv->is_lexsub($gv)) {
4552             ;
4553             }
4554             elsif (!exists &$fullname) {
4555 0 0       0 warn $fullname." not found\n" if $debug{sub};
4556             warn "No definition for sub $fullname (unable to autoload)\n"
4557 0 0       0 if $debug{cv};
4558 0 0 0     0 $init->add( "/* $fullname not found */" ) if $verbose or $debug{sub};
4559             # XXX empty CV should not be saved. #159, #235
4560             # $svsect->remove( $sv_ix );
4561             # $xpvcvsect->remove( $xpvcv_ix );
4562             # delsym( $cv );
4563 0 0       0 if (!$new_cv_fw) {
4564 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t0");
4565             }
4566 0 0       0 $CvFLAGS &= ~0x1000 if $PERL514; # CVf_DYNFILE
4567 0 0 0     0 $CvFLAGS &= ~0x400 if $gv and $$gv and $PERL514; #CVf_CVGV_RC
      0        
4568 0 0       0 $symsect->add(sprintf(
4569             "CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x".($PERL510?", {0}":''),
4570             $sv_ix, $xpvcv_ix, $cv->REFCNT, $CvFLAGS));
4571 0         0 return get_cv($fullname, 0);
4572             }
4573              
4574             # Now it is time to record the CV
4575 0 0       0 if ($new_cv_fw) {
4576 0         0 $sv_ix = $svsect->index + 1;
4577 0 0       0 if (!$cvforward{$sym}) { # avoid duplicates
4578 0         0 $symsect->add(sprintf("%s\t&sv_list[%d]", $sym, $sv_ix )); # forward the old CVIX to the new CV
4579 0         0 $cvforward{$sym}++;
4580             }
4581 0         0 $sym = savesym( $cv, "&sv_list[$sv_ix]" );
4582             }
4583              
4584             # $pv = '' unless defined $pv; # Avoid use of undef warnings
4585             #warn sprintf( "CV prototype %s for CV 0x%x\n", cstring($pv), $$cv )
4586             # if $pv and $debug{cv};
4587 0 0       0 my $proto = defined $pv ? cstring($pv) : 'NULL';
4588 0         0 my $pvsym = 'NULL';
4589 0 0       0 my $cur = defined $pv ? $cv->CUR : 0;
4590 0         0 my $len = $cur + 1;
4591 0 0 0     0 $len++ if IsCOW($cv) and !$B::C::cow;
4592 0 0       0 $len = 0 if $B::C::const_strings;
4593             # need to survive cv_undef as there is no protection against static CVs
4594 0 0       0 my $refcnt = $cv->REFCNT + ($PERL510 ? 1 : 0);
4595             # GV cannot be initialized statically
4596 0         0 my $xcv_outside = ${ $cv->OUTSIDE };
  0         0  
4597 0 0 0     0 if ($xcv_outside == ${ main_cv() } and !$MULTI) {
  0 0       0  
4598             # Provide a temp. debugging hack for CvOUTSIDE. The address of the symbol &PL_main_cv
4599             # is known to the linker, the address of the value PL_main_cv not. This is set later
4600             # (below) at run-time.
4601 0         0 $xcv_outside = '&PL_main_cv';
4602             } elsif (ref($cv->OUTSIDE) eq 'B::CV') {
4603 0         0 $xcv_outside = 0; # just a placeholder for a run-time GV
4604             }
4605 0 0       0 if ($PERL510) {
    0          
4606 0         0 $pvsym = save_hek($pv,$fullname,1);
4607             # XXX issue 84: we need to check the cv->PV ptr not the value.
4608             # "" is different to NULL for prototypes
4609 0 0       0 $len = $cur ? $cur+1 : 0;
4610             # TODO:
4611             # my $ourstash = "0"; # TODO stash name to bless it (test 16: "main::")
4612 0 0       0 if ($PERL522) {
    0          
4613 0         0 $CvFLAGS &= ~0x1000; # CVf_DYNFILE off
4614 0 0       0 $CvFLAGS |= 0x200000 if $CPERL52; # CVf_STATIC on
4615 0         0 my $xpvc = sprintf
4616             # stash magic cur {len} cvstash {start} {root} {cvgv} cvfile {cvpadlist} outside outside_seq cvflags cvdepth
4617             ("Nullhv, {0}, %u, {%u}, %s, {%s}, {s\\_%x}, {%s}, %s, {%s}, (CV*)%s, %s, 0x%x, %d",
4618             $cur, $len, "Nullhv",#CvSTASH later
4619             $startfield, $$root,
4620             "0", #GV later
4621             "NULL", #cvfile later (now a HEK)
4622             $padlistsym,
4623             $xcv_outside, #if main_cv set later
4624             ivx($cv->OUTSIDE_SEQ),
4625             $CvFLAGS,
4626             $cv->DEPTH);
4627             # repro only with 5.15.* threaded -q (70c0620) Encode::Alias::define_alias
4628 0 0       0 warn "lexwarnsym in XPVCV OUTSIDE: $xpvc" if $xpvc =~ /, \(CV\*\)iv\d/; # t/testc.sh -q -O3 227
4629 0 0       0 if (!$new_cv_fw) {
4630 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4631             #$symsect->add
4632             # (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}"),
4633             # $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4634             # ));
4635             } else {
4636 0         0 $xpvcvsect->comment('STASH mg_u cur len CV_STASH START_U ROOT_U GV file PADLIST OUTSIDE outside_seq flags depth');
4637 0         0 $xpvcvsect->add($xpvc);
4638 0 0       0 $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {%s}",
4639             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS,
4640             $CPERL52 ? $proto : "0"));
4641 0 0       0 $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4642             }
4643             } elsif ($PERL514) {
4644             # cv_undef wants to free it when CvDYNFILE(cv) is true.
4645             # E.g. DateTime: boot_POSIX. newXS reuses cv if autoloaded. So turn it off globally.
4646 0         0 $CvFLAGS &= ~0x1000; # CVf_DYNFILE off
4647 0         0 my $xpvc = sprintf
4648             # stash magic cur len cvstash start root cvgv cvfile cvpadlist outside outside_seq cvflags cvdepth
4649             ("Nullhv, {0}, %u, %u, %s, {%s}, {s\\_%x}, %s, %s, %s, (CV*)%s, %s, 0x%x, %d",
4650             $cur, $len, "Nullhv",#CvSTASH later
4651             $startfield, $$root,
4652             "0", #GV later
4653             "NULL", #cvfile later (now a HEK)
4654             $padlistsym,
4655             $xcv_outside, #if main_cv set later
4656             ivx($cv->OUTSIDE_SEQ),
4657             $CvFLAGS,
4658             $cv->DEPTH);
4659             #warn "lexwarnsym in XPVCV OUTSIDE: $xpvc" if $xpvc =~ /, \(CV\*\)iv\d/; # t/testc.sh -q -O3 227
4660 0 0       0 if (!$new_cv_fw) {
4661 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4662             #$symsect->add
4663             # (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}"),
4664             # $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4665             # ));
4666             } else {
4667 0         0 $xpvcvsect->comment('STASH mg_u cur len CV_STASH START_U ROOT_U GV file PADLIST OUTSIDE outside_seq flags depth');
4668 0         0 $xpvcvsect->add($xpvc);
4669 0         0 $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {0}",
4670             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS));
4671 0 0       0 $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4672             }
4673             } else { # 5.10-5.13
4674             # Note: GvFORM ends also here. #149 (B::FM), t/testc.sh -O3 -DGCF,-v 149
4675 0 0       0 my $depth = ref($cv) eq 'B::CV' ? $cv->DEPTH : 0;
4676 0 0       0 my $outside_seq = ref($cv) eq 'B::CV' ? $cv->OUTSIDE_SEQ : '0'; # XXX? #238
4677 0         0 my $xpvc = sprintf
4678             ("{%d}, %u, %u, {%s}, {%s}, %s,"
4679             ." %s, {%s}, {s\\_%x}, %s, %s, %s,"
4680             ." (CV*)%s, %s, 0x%x",
4681             0, # GvSTASH later. test 29 or Test::Harness
4682             $cur, $len,
4683             $depth,
4684             "NULL", "Nullhv", #MAGIC + STASH later
4685             "Nullhv",#CvSTASH later
4686             $startfield,
4687             $$root,
4688             "0", #GV later
4689             "NULL", #cv_file later (now a HEK)
4690             $padlistsym,
4691             $xcv_outside, #if main_cv set later
4692             $outside_seq,
4693             $CvFLAGS
4694             );
4695 0 0       0 if (!$new_cv_fw) {
4696 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4697             #$symsect->add
4698             # (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}",
4699             # $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4700             # ));
4701             } else {
4702 0         0 $xpvcvsect->comment('GvSTASH cur len depth mg_u MG_STASH CV_STASH START_U ROOT_U CV_GV cv_file PADLIST OUTSIDE outside_seq cv_flags');
4703 0         0 $xpvcvsect->add($xpvc);
4704 0         0 $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {0}",
4705             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS));
4706 0 0       0 $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4707             }
4708             }
4709 0 0       0 if ($$cv) {
4710 0 0 0     0 if ($PERL518 and (!$gv or ref($gv) eq 'B::SPECIAL')) {
      0        
4711 0 0       0 my $lexsub = $cv->can('NAME_HEK') ? $cv->NAME_HEK : "_anonlex_";
4712 0 0       0 $lexsub = '' unless defined $lexsub;
4713 0 0       0 warn "lexsub name $lexsub" if $debug{gv};
4714 0         0 my ($cstring, $cur, $utf8) = strlen_flags($lexsub);
4715 0 0 0     0 if (!$PERL56 and $utf8) {
4716 0         0 $cur = -$cur;
4717             }
4718 0         0 $init->add( "{ /* need a dynamic name hek */",
4719             sprintf(" HEK *lexhek = share_hek(savepvn(%s, %d), %d);",
4720             $cstring, abs($cur), $cur),
4721             sprintf(" CvNAME_HEK_set(s\\_%x, lexhek);", $$cv),
4722             "}");
4723             } else {
4724 0         0 my $gvstash = $gv->STASH;
4725             # defer GvSTASH because with DEBUGGING it checks for GP but
4726             # there's no GP yet.
4727             # But with -fstash the gvstash is set later
4728 0 0 0     0 $init->add( sprintf( "GvXPVGV(s\\_%x)->xnv_u.xgv_stash = s\\_%x;",
4729             $$cv, $$gvstash ) ) if $gvstash and !$B::C::stash;
4730             warn sprintf( "done saving GvSTASH 0x%x for CV 0x%x\n", $$gvstash, $$cv )
4731 0 0 0     0 if $gvstash and $debug{cv} and $debug{gv};
      0        
4732             }
4733             }
4734 0 0       0 if ( $cv->OUTSIDE_SEQ ) {
4735 0         0 my $cop = $symtable{ sprintf( "s\\_%x", $cv->OUTSIDE_SEQ ) };
4736 0 0       0 $init->add( sprintf( "CvOUTSIDE_SEQ(%s) = %s;", $sym, $cop ) ) if $cop;
4737             }
4738             }
4739             elsif ($PERL56) {
4740 0         0 my $xpvc = sprintf("%s, %u, %u, %s, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub, "
4741             ."$xsubany, Nullgv, \"\", %d, s\\_%x, (CV*)%s, 0x%x",
4742             $proto, $cur, $len, ivx($cv->IVX),
4743             nvx($cv->NVX), $startfield, $$root, $cv->DEPTH,
4744             $$padlist, $xcv_outside, $cv->CvFLAGS
4745             );
4746 0 0       0 if ($new_cv_fw) {
4747 0         0 $xpvcvsect->comment('pv cur len off nv magic mg_stash cv_stash start root xsub '
4748             .'xsubany cv_gv cv_file cv_depth cv_padlist cv_outside cv_flags');
4749 0         0 $xpvcvsect->add($xpvc);
4750 0         0 $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x"),
4751             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS);
4752 0 0       0 $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4753             } else {
4754 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4755             }
4756             }
4757             else { #5.8
4758 0         0 my $xpvc = sprintf("%s, %u, %u, %s, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub,"
4759             ." $xsubany, Nullgv, \"\", %d, s\\_%x, (CV*)s\\_%x, 0x%x, 0x%x",
4760             $proto, $cur, $len, ivx($cv->IVX),
4761             nvx($cv->NVX), $startfield, $$root, $cv->DEPTH,
4762             $$padlist, $xcv_outside, $cv->CvFLAGS, $cv->OUTSIDE_SEQ
4763             );
4764 0 0       0 if ($new_cv_fw) {
4765 0         0 $xpvcvsect->comment('pv cur len off nv magic mg_stash cv_stash '
4766             .'start root xsub xsubany cv_gv cv_file cv_depth cv_padlist '
4767             .'cv_outside cv_flags outside_seq');
4768 0         0 $xpvcvsect->add($xpvc);
4769 0         0 $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x"),
4770             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS);
4771 0 0       0 $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4772             } else {
4773 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4774             }
4775             }
4776              
4777 0 0 0     0 if ($CPERL52 and $Config{uselongdouble}) {
4778             # some very odd static struct init bug: CvOUTSIDE is pointing to CvROOT, CvROOT is corrupt.
4779             # CvPADLIST also pointing somewhere else. with gcc-5 and 4.8.
4780 0         0 $init->add(sprintf("xpvcv_list[$xpvcv_ix].xcv_root_u.xcv_root = s\\_%x;", $$root));
4781 0         0 $init->add("xpvcv_list[$xpvcv_ix].xcv_padlist_u.xcv_padlist = $padlistsym;");
4782             }
4783              
4784 0         0 $xcv_outside = ${ $cv->OUTSIDE };
  0         0  
4785 0 0 0     0 if ($xcv_outside == ${ main_cv() } or ref($cv->OUTSIDE) eq 'B::CV') {
  0 0 0     0  
      0        
4786             # patch CvOUTSIDE at run-time
4787 0 0       0 if ( $xcv_outside == ${ main_cv() } ) {
  0         0  
4788 0         0 $init->add( "CvOUTSIDE($sym) = PL_main_cv;",
4789             "SvREFCNT_inc(PL_main_cv);" );
4790 0 0       0 if ($$padlist) {
4791 0 0       0 if ($PERL522) {
    0          
4792 0         0 $init->add( "CvPADLIST($sym)->xpadl_outid = CvPADLIST(PL_main_cv)->xpadl_id;");
4793             } elsif ($] >= 5.017005) {
4794 0         0 $init->add( "CvPADLIST($sym)->xpadl_outid = PadlistNAMES(CvPADLIST(PL_main_cv));");
4795             }
4796             }
4797             } else {
4798 0         0 $init->add( sprintf("CvOUTSIDE(%s) = (CV*)s\\_%x;", $sym, $xcv_outside) );
4799             #if ($PERL522) {
4800             # $init->add( sprintf("CvPADLIST(%s)->xpadl_outid = CvPADLIST(s\\_%x)->xpadl_id;",
4801             # $sym, $xcv_outside));
4802             #}
4803             }
4804             }
4805             elsif ($] >= 5.017005 and $xcv_outside and $$padlist) {
4806 0         0 my $padl = $cv->OUTSIDE->PADLIST->save;
4807 0 0       0 if ($PERL522) {
4808 0         0 $init->add( sprintf("CvPADLIST(%s)->xpadl_outid = CvPADLIST(s\\_%x)->xpadl_id;",
4809             $sym, $xcv_outside));
4810             } else {
4811             # Make sure that the outer padlist is allocated before PadlistNAMES is accessed.
4812             # This needs to be postponed (test 227)
4813 0         0 $init1->add( sprintf( "CvPADLIST(%s)->xpadl_outid = PadlistNAMES(%s);", $sym, $padl) );
4814             }
4815             }
4816 0 0 0     0 if ($gv and $$gv) {
4817             #test 16: Can't call method "FETCH" on unblessed reference. gdb > b S_method_common
4818 0 0 0     0 warn sprintf( "Saving GV 0x%x for CV 0x%x\n", $$gv, $$cv ) if $debug{cv} and $debug{gv};
4819 0         0 $gv->save;
4820 0 0       0 if ($PERL514) { # FIXME 5.18.0 with lexsubs
4821             # XXX gvcv might be PVMG
4822 0         0 $init->add( sprintf( "CvGV_set((CV*)%s, (GV*)%s);", $sym, objsym($gv)) );
4823             # Since 5.13.3 and CvGV_set there are checks that the CV is not RC (refcounted).
4824             # Assertion "!CvCVGV_RC(cv)" failed: file "gv.c", line 219, function: Perl_cvgv_set
4825             # We init with CvFLAGS = 0 and set it later, as successfully done in the Bytecode compiler
4826 0 0       0 if ($CvFLAGS & 0x0400) { # CVf_CVGV_RC
4827             warn sprintf( "CvCVGV_RC turned off. CV flags=0x%x %s CvFLAGS=0x%x \n",
4828             $cv->FLAGS, $debug{flags}?$cv->flagspv:"", $CvFLAGS & ~0x400)
4829 0 0       0 if $debug{cv};
    0          
4830             $init->add( sprintf( "CvFLAGS((CV*)%s) = 0x%x; %s", $sym, $CvFLAGS,
4831 0 0       0 $debug{flags}?"/* ".$cv->flagspv." */":"" ) );
4832             }
4833 0         0 $init->add("CvSTART($sym) = $startfield;"); # XXX TODO someone is overwriting CvSTART also
4834             } else {
4835 0         0 $init->add( sprintf( "CvGV(%s) = %s;", $sym, objsym($gv) ) );
4836             }
4837             warn sprintf("done saving GV 0x%x for CV 0x%x\n",
4838 0 0 0     0 $$gv, $$cv) if $debug{cv} and $debug{gv};
4839             }
4840 0 0       0 unless ($optimize_cop) {
4841 0         0 my $file = $cv->FILE();
4842 0 0 0     0 if ($MULTI) {
    0          
4843 0         0 $init->add( savepvn( "CvFILE($sym)", $file ) );
4844             } elsif ($B::C::const_strings && length $file) {
4845 0         0 $init->add( sprintf( "CvFILE(%s) = (char *) %s;", $sym, constpv( $file ) ) );
4846             } else {
4847 0         0 $init->add( sprintf( "CvFILE(%s) = %s;", $sym, cstring( $file ) ) );
4848             }
4849             }
4850 0         0 my $stash = $cv->STASH;
4851 0 0 0     0 if ($$stash and ref($stash)) {
4852             # $init->add("/* saving STASH $fullname */\n" if $debug{cv};
4853 0         0 $stash->save($fullname);
4854             # $sym fixed test 27
4855 0         0 $init->add( sprintf( "CvSTASH_set((CV*)%s, s\\_%x);", $sym, $$stash ) );
4856             # 5.18 bless does not inc sv_objcount anymore. broken by ddf23d4a1ae (#208)
4857             # We workaround this 5.18 de-optimization by adding it if at least a DESTROY
4858             # method exists.
4859 0 0 0     0 $init->add("++PL_sv_objcount;") if $cvname eq 'DESTROY' and $] >= 5.017011;
4860             warn sprintf( "done saving STASH 0x%x for CV 0x%x\n", $$stash, $$cv )
4861 0 0 0     0 if $debug{cv} and $debug{gv};
4862             }
4863 0         0 my $magic = $cv->MAGIC;
4864 0 0 0     0 if ($magic and $$magic) {
4865 0         0 $cv->save_magic($fullname); # XXX will this work?
4866             }
4867 0 0       0 if (!$new_cv_fw) {
4868 0 0       0 $symsect->add(sprintf(
4869             "CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x".($PERL510?", {0}":''),
4870             $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4871             )
4872             );
4873             }
4874 0 0       0 if ($cur) {
4875 0 0       0 warn sprintf( "Saving CV proto %s for CV $sym 0x%x\n", cstring($pv), $$cv ) if $debug{cv};
4876             }
4877             # issue 84: empty prototypes sub xx(){} vs sub xx{}
4878 0 0       0 if (defined $pv) {
4879 0 0 0     0 if ($PERL510 and $cur) {
    0          
4880 0         0 $init->add( sprintf("SvPVX(&sv_list[%d]) = HEK_KEY(%s);", $sv_ix, $pvsym));
4881             } elsif (!$B::C::const_strings) { # not static, they are freed when redefined
4882 0         0 $init->add( sprintf("SvPVX(&sv_list[%d]) = savepvn(%s, %u);",
4883             $sv_ix, $proto, $cur));
4884             } else {
4885 0         0 $init->add( sprintf("SvPVX(&sv_list[%d]) = %s;",
4886             $sv_ix, $proto));
4887             }
4888             }
4889 0 0       0 $cv->OUTSIDE->save if $xcv_outside;
4890 0         0 return $sym;
4891             }
4892              
4893             package B::C;
4894             my @_v = Internals::V() if $] >= 5.011;
4895 0     0   0 sub __ANON__::_V { @_v };
4896              
4897             sub B::GV::save {
4898 0     0   0 my ($gv, $filter) = @_;
4899 0         0 my $sym = objsym($gv);
4900 0 0       0 if ( defined($sym) ) {
4901 0 0       0 warn sprintf( "GV 0x%x already saved as $sym\n", $$gv ) if $debug{gv};
4902 0         0 return $sym;
4903             }
4904             else {
4905 0         0 my $ix = $gv_index++;
4906 0         0 $sym = savesym( $gv, "gv_list[$ix]" );
4907 0 0       0 warn sprintf( "Saving GV 0x%x as $sym\n", $$gv ) if $debug{gv};
4908             }
4909             warn sprintf( " GV %s $sym type=%d, flags=0x%x %s\n", $gv->NAME,
4910             # B::SV::SvTYPE not with 5.6
4911 0 0 0     0 B::SV::SvTYPE($gv), $gv->FLAGS) if $debug{gv} and !$PERL56;
4912 0 0 0     0 if ($PERL510 and $gv->FLAGS & 0x40000000) { # SVpbm_VALID
4913 0 0       0 warn sprintf( " GV $sym isa FBM\n") if $debug{gv};
4914 0         0 return B::BM::save($gv);
4915             }
4916              
4917 0         0 my $gvname = $gv->NAME;
4918 0         0 my $package;
4919 0 0       0 if (ref($gv->STASH) eq 'B::SPECIAL') {
4920 0         0 $package = '__ANON__';
4921 0 0       0 warn sprintf( "GV STASH = SPECIAL $gvname\n") if $debug{gv};
4922             } else {
4923 0         0 $package = $gv->STASH->NAME;
4924             }
4925 0 0       0 return q/(SV*)&PL_sv_undef/ if skip_pkg($package);
4926              
4927 0         0 my $fullname = $package . "::" . $gvname;
4928 0         0 my $fancyname;
4929             sub Save_HV() { 1 }
4930             sub Save_AV() { 2 }
4931             sub Save_SV() { 4 }
4932             sub Save_CV() { 8 }
4933             sub Save_FORM() { 16 }
4934             sub Save_IO() { 32 }
4935 0 0 0     0 if ( $filter and $filter =~ m/ :pad/ ) {
4936 0         0 $fancyname = cstring($filter);
4937 0         0 $filter = 0;
4938             } else {
4939 0         0 $fancyname = cstring($fullname);
4940             }
4941             # checked for defined'ness in Carp. So the GV must exist, the CV not
4942 0 0 0     0 if ($fullname =~ /^threads::(tid|AUTOLOAD)$/ and !$ITHREADS) {
4943 0         0 $filter = Save_CV;
4944             }
4945             # no need to assign any SV/AV/HV to them (172)
4946 0 0 0     0 if ($PERL518 and $fullname =~ /^DynaLoader::dl_(
4947             require_symbols|
4948             modules|
4949             shared_objects|
4950             resolve_using|
4951             librefs)/x)
4952             {
4953 0         0 $filter = Save_SV + Save_AV + Save_HV;
4954             }
4955             # skip static %Encode::Encoding since 5.20. GH #200.
4956             # Let it be initialized by boot_Encode/Encode_XSEncoding
4957             #if ($] >= 5.020 and $fullname eq 'Encode::Encoding') {
4958             # warn "skip %Encode::Encoding - XS initialized\n" if $debug{gv};
4959             # $filter = Save_HV;
4960             #}
4961              
4962 0         0 my $is_empty = $gv->is_empty;
4963 0 0 0     0 if (!defined $gvname and $is_empty) { # 5.8 curpad name
4964 0         0 return q/(SV*)&PL_sv_undef/;
4965             }
4966 0 0       0 my $name = $package eq 'main' ? $gvname : $fullname;
4967 0         0 my $cname = cstring($name);
4968 0 0 0     0 my $notqual = ($] >= 5.008009 and $package eq 'main') ? 'GV_NOTQUAL' : '0';
4969 0 0       0 warn " GV name is $fancyname\n" if $debug{gv};
4970 0         0 my $egvsym;
4971 0         0 my $is_special = ref($gv) eq 'B::SPECIAL';
4972              
4973             # If we come across a stash, we therefore have code using this symbol.
4974             # But this does not mean that we need to save the package then.
4975             # if (defined %Exporter::) should not import Exporter, it should return undef.
4976             #if ( $gvname =~ m/::$/ ) {
4977             # my $package = $gvname;
4978             # $package =~ s/::$//;
4979             # mark_package($package); #wrong
4980             #}
4981 0 0       0 if ($fullname =~ /^(bytes|utf8)::AUTOLOAD$/) {
4982 0         0 $gv = force_heavy($package); # defer to run-time autoload, or compile it in?
4983 0         0 $sym = savesym( $gv, $sym ); # override new gv ptr to sym
4984             }
4985 0 0       0 if ( !$is_empty ) {
4986 0         0 my $egv = $gv->EGV;
4987 0 0 0     0 unless (ref($egv) eq 'B::SPECIAL' or ref($egv->STASH) eq 'B::SPECIAL') {
4988 0         0 my $estash = $egv->STASH->NAME;
4989 0 0       0 if ( $$gv != $$egv ) {
4990             warn(sprintf( "EGV name is %s, saving it now\n",
4991             $estash . "::" . $egv->NAME )
4992 0 0       0 ) if $debug{gv};
4993 0         0 $egvsym = $egv->save;
4994             }
4995             }
4996             }
4997             #if ($fullname eq 'threads::tid' and !$ITHREADS) { # checked for defined'ness in Carp
4998             # $init->add(qq[$sym = (GV*)&PL_sv_undef;]);
4999             # return $sym;
5000             #}
5001 0 0 0     0 if ($fullname =~ /^main::STDOUT$/i and $PERL56) {
5002 0         0 return 'Nullgv'; # perl.c: setdefout(Nullgv)
5003             }
5004 0         0 my $core_syms = {ENV => 'PL_envgv',
5005             ARGV => 'PL_argvgv',
5006             INC => 'PL_incgv',
5007             STDIN => 'PL_stdingv',
5008             STDERR => 'PL_stderrgv',
5009             "\010" => 'PL_hintgv', # ^H
5010             "_" => 'PL_defgv',
5011             "@" => 'PL_errgv',
5012             "\022" => 'PL_replgv', # ^R
5013             };
5014 0         0 my $is_coresym;
5015             # those are already initialized in init_predump_symbols()
5016             # and init_main_stash()
5017 0         0 for my $s (sort keys %$core_syms) {
5018 0 0       0 if ($fullname eq 'main::'.$s) {
5019 0         0 $sym = savesym( $gv, $core_syms->{$s} );
5020             # $init->add( sprintf( "SvREFCNT($sym) = $u32fmt;", $gv->REFCNT ) );
5021             # return $sym;
5022 0         0 $is_coresym++;
5023             }
5024             }
5025 0 0 0     0 if ($fullname =~ /^main::std(in|out|err)$/) { # same as uppercase above
    0          
    0          
5026 0         0 $init->add(qq[$sym = gv_fetchpv($cname, $notqual, SVt_PVGV);]);
5027 0         0 $init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) );
5028 0         0 return $sym;
5029             }
5030             elsif ($fullname eq 'main::0') { # dollar_0 already handled before, so don't overwrite it
5031 0         0 $init->add(qq[$sym = gv_fetchpv($cname, $notqual, SVt_PV);]);
5032 0         0 $init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) );
5033 0         0 return $sym;
5034             }
5035             elsif ($B::C::ro_inc and $fullname =~ /^main::([0-9])$/) { # ignore PV regexp captures with -O2
5036 0         0 $filter = Save_SV;
5037             }
5038             # gv_fetchpv loads Errno resp. Tie::Hash::NamedCapture, but needs *INC #90
5039             #elsif ( $fullname eq 'main::!' or $fullname eq 'main::+' or $fullname eq 'main::-') {
5040             # $init1->add(qq[$sym = gv_fetchpv($name, TRUE, SVt_PVGV);]); # defer until INC is setup
5041             # $init1->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) );
5042             # return $sym;
5043             #}
5044 0         0 my $svflags = $gv->FLAGS;
5045 0         0 my $savefields = 0;
5046              
5047 0         0 my $gp;
5048 0 0       0 my $gvadd = $notqual ? "$notqual|GV_ADD" : "GV_ADD";
5049 0 0 0     0 if ( $PERL510 and $gv->isGV_with_GP and !$is_coresym) {
    0 0        
5050 0         0 $gp = $gv->GP; # B limitation
5051             # warn "XXX EGV='$egvsym' for IMPORTED_HV" if $gv->GvFLAGS & 0x40;
5052 0 0 0     0 if ( defined($egvsym) && $egvsym !~ m/Null/ ) {
    0 0        
    0 0        
    0 0        
      0        
5053             warn(sprintf("Shared GV alias for *$fullname 0x%x%s %s to $egvsym\n",
5054             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5055 0 0       0 )) if $debug{gv};
    0          
5056             # Shared glob *foo = *bar
5057 0 0       0 $init->add("$sym = ".gv_fetchpvn($package eq 'main' ? $gvname : $fullname,
5058             "$gvadd|GV_ADDMULTI", "SVt_PVGV").";");
5059 0         0 $init->add( "GvGP_set($sym, GvGP($egvsym));" );
5060 0         0 $is_empty = 1;
5061             }
5062             elsif ( $gp and exists $gptable{0+$gp} ) {
5063             warn(sprintf("Shared GvGP for *$fullname 0x%x%s %s GP:0x%x\n",
5064             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5065             $gv->FILE, $gp
5066 0 0       0 )) if $debug{gv};
    0          
5067 0         0 $init->add("$sym = ".gv_fetchpvn($name, $notqual, "SVt_PVGV").";");
5068 0         0 $init->add( sprintf("GvGP_set(%s, %s);", $sym, $gptable{0+$gp}) );
5069 0         0 $is_empty = 1;
5070             }
5071             elsif ( $gp and !$is_empty and $gvname =~ /::$/) {
5072             warn(sprintf("Shared GvGP for stash %$fullname 0x%x%s %s GP:0x%x\n",
5073             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5074             $gv->FILE, $gp
5075 0 0       0 )) if $debug{gv};
    0          
5076 0         0 $init->add("$sym = ".gv_fetchpvn($name, "GV_ADD", "SVt_PVHV").";");
5077 0 0       0 $gptable{0+$gp} = "GvGP($sym)" if 0+$gp;
5078             }
5079             elsif ( $gp and !$is_empty ) {
5080             warn(sprintf("New GV for *$fullname 0x%x%s %s GP:0x%x\n",
5081             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5082             $gv->FILE, $gp
5083 0 0       0 )) if $debug{gv};
    0          
5084             # XXX !PERL510 and OPf_COP_TEMP we need to fake PL_curcop for gp_file hackery
5085 0         0 $init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PV").";");
5086             #$init->add(qq[$sym = gv_fetchpv($name, $gvadd, SVt_PV);]);
5087 0         0 $savefields = Save_HV | Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO;
5088 0         0 $gptable{0+$gp} = "GvGP($sym)";
5089             }
5090             else {
5091 0         0 $init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PVGV").";");
5092             # $init->add(qq[$sym = gv_fetchpv($name, $gvadd, SVt_PVGV);]);
5093             }
5094             } elsif (!$is_coresym) {
5095 0         0 $init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PV").";");
5096             # $init->add(qq[$sym = gv_fetchpv($name, $gvadd, SVt_PV);]);
5097             }
5098 0         0 my $gvflags = $gv->GvFLAGS;
5099 0 0 0     0 if ($gvflags > 256 and !$PERL510) { # $gv->GvFLAGS as U8 single byte only
5100 0         0 $gvflags = $gvflags & 255;
5101             }
5102             $init->add( sprintf( "SvFLAGS(%s) = 0x%x;%s", $sym, $svflags,
5103             $debug{flags}?" /* ".$gv->flagspv." */":"" ),
5104             sprintf( "GvFLAGS(%s) = 0x%x; %s", $sym, $gvflags,
5105 0 0       0 $debug{flags}?"/* ".$gv->flagspv(SVt_PVGV)." */":"" ));
    0          
5106 0 0       0 $init->add( sprintf( "GvLINE(%s) = %d;", $sym,
    0          
5107             ($gv->LINE > 2147483647 # S32 INT_MAX
5108             ? 4294967294 - $gv->LINE
5109             : $gv->LINE )))
5110             unless $is_empty;
5111              
5112             # XXX hack for when Perl accesses PVX of GVs, only if SvPOK
5113             #if (!($svflags && 0x400)) { # defer to run-time (0x400 -> SvPOK) for convenience
5114             # XXX also empty "main::" destruction accesses a PVX, so do not check if_empty
5115 0 0       0 if ( !$PERL510 ) {
5116 0         0 $init->add("if (SvPOK($sym) && !SvPVX($sym)) SvPVX($sym) = (char*)emptystring;");
5117             }
5118              
5119             # walksymtable creates an extra reference to the GV (#197)
5120 0 0       0 if ( $gv->REFCNT > 1 ) {
5121 0         0 $init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT) );
5122             }
5123 0 0       0 return $sym if $is_empty;
5124              
5125 0         0 my $gvrefcnt = $gv->GvREFCNT;
5126 0 0       0 if ( $gvrefcnt > 1 ) {
5127 0         0 $init->add( sprintf( "GvREFCNT(%s) += $u32fmt;", $sym, $gvrefcnt - 1) );
5128             }
5129              
5130 0 0       0 warn "check which savefields for \"$gvname\"\n" if $debug{gv};
5131             # some non-alphabetic globs require some parts to be saved
5132             # ( ex. %!, but not $! )
5133 0 0 0     0 if ( $gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/ ) {
    0          
    0          
    0          
    0          
5134 0         0 $savefields = Save_HV | Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO;
5135             }
5136             elsif ( $fullname eq 'main::!' ) { #Errno
5137 0         0 $savefields = Save_HV | Save_SV | Save_CV;
5138             }
5139             elsif ( $fullname eq 'main::ENV' or $fullname eq 'main::SIG' ) {
5140 0         0 $savefields = Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO;
5141             }
5142             elsif ( $fullname eq 'main::ARGV' ) {
5143 0         0 $savefields = Save_HV | Save_SV | Save_CV | Save_FORM | Save_IO;
5144             }
5145             elsif ( $fullname =~ /^main::STD(IN|OUT|ERR)$/ ) {
5146 0         0 $savefields = Save_FORM | Save_IO;
5147             }
5148 0 0 0     0 $savefields &= ~$filter if ($filter and $filter !~ m/ :pad/
      0        
      0        
      0        
5149             and $filter =~ m/^\d+$/ and $filter > 0 and $filter < 64);
5150             # issue 79: Only save stashes for stashes.
5151             # But not other values to avoid recursion into unneeded territory.
5152             # We walk via savecv, not via stashes.
5153 0 0 0     0 if (ref($gv) eq 'B::STASHGV' and $gvname !~ /::$/) {
5154 0         0 return $sym;
5155             }
5156              
5157             # attributes::bootstrap is created in perl_parse.
5158             # Saving it would overwrite it, because perl_init() is
5159             # called after perl_parse(). But we need to xsload it.
5160 0 0       0 if ($fullname eq 'attributes::bootstrap') {
5161 0 0       0 unless ( defined( &{ $package . '::bootstrap' } ) ) {
  0         0  
5162 0 0       0 warn "Forcing bootstrap of $package\n" if $verbose;
5163 0         0 eval { $package->bootstrap };
  0         0  
5164             }
5165 0         0 mark_package('attributes', 1);
5166 0 0       0 if ($] >= 5.011) {
5167 0         0 $savefields &= ~Save_CV;
5168 0         0 $xsub{attributes} = 'Dynamic-'. $INC{'attributes.pm'}; # XSLoader
5169 0         0 $use_xsloader = 1;
5170             } else {
5171 0         0 $xsub{attributes} = 'Static';
5172             }
5173             }
5174              
5175             # avoid overly dynamic POSIX redefinition warnings: GH #335, #345
5176 0 0 0     0 if ($PERL522 and $fullname =~ /^POSIX::M/) {
5177 0         0 $savefields &= ~Save_CV;
5178             }
5179 0         0 my $gvsv;
5180 0 0       0 if ($savefields) {
5181             # Don't save subfields of special GVs (*_, *1, *# and so on)
5182 0 0       0 warn "GV::save saving subfields $savefields\n" if $debug{gv};
5183 0         0 $gvsv = $gv->SV;
5184 0 0 0     0 if ( $$gvsv && $savefields & Save_SV ) {
5185 0 0       0 warn "GV::save \$".$sym." $gvsv\n" if $debug{gv};
5186 0         0 my $core_svs = { # special SV syms to assign to the right GvSV
5187             "\\" => 'PL_ors_sv',
5188             "/" => 'PL_rs',
5189             "@" => 'PL_errors',
5190             };
5191 0         0 for my $s (sort keys %$core_svs) {
5192 0 0       0 if ($fullname eq 'main::'.$s) {
5193 0         0 savesym( $gvsv, $core_svs->{$s} ); # TODO: This could bypass BEGIN settings (->save is ignored)
5194             }
5195             }
5196 0 0 0     0 if ($gvname eq 'VERSION' and $xsub{$package} and $gvsv->FLAGS & SVf_ROK and !$PERL56) {
      0        
      0        
5197 0 0       0 warn "Strip overload from $package\::VERSION, fails to xs boot (issue 91)\n" if $debug{gv};
5198 0         0 my $rv = $gvsv->object_2svref();
5199 0         0 my $origsv = $$rv;
5200 55     55   353 no strict 'refs';
  55         90  
  55         28120  
5201 0         0 ${$fullname} = "$origsv";
  0         0  
5202 0         0 svref_2object(\${$fullname})->save($fullname);
  0         0  
5203 0         0 $init->add( sprintf( "GvSVn(%s) = (SV*)s\\_%x;", $sym, $$gvsv ) );
5204             } else {
5205 0         0 $gvsv->save($fullname); #even NULL save it, because of gp_free nonsense
5206             # we need sv magic for the core_svs (PL_rs -> gv) (#314)
5207 0 0       0 if (exists $core_svs->{$gvname}) {
5208 0 0       0 if ($gvname eq "\\") { # ORS special case #318 (initially NULL)
5209 0         0 return $sym;
5210             } else {
5211 0 0       0 $gvsv->save_magic($fullname) if ref($gvsv) eq 'B::PVMG';
5212 0         0 $init->add( sprintf( "SvREFCNT(s\\_%x) += 1;", $$gvsv ) );
5213             }
5214             }
5215 0         0 $init->add( sprintf( "GvSVn(%s) = (SV*)s\\_%x;", $sym, $$gvsv ) );
5216             }
5217 0 0       0 if ($fullname eq 'main::$') { # $$ = PerlProc_getpid() issue #108
5218 0 0       0 warn sprintf( " GV $sym \$\$ perlpid\n") if $debug{gv};
5219 0         0 $init->add( "sv_setiv(GvSV($sym), (IV)PerlProc_getpid());" );
5220             }
5221 0 0       0 warn "GV::save \$$fullname\n" if $debug{gv};
5222             }
5223 0         0 my $gvav = $gv->AV;
5224 0 0 0     0 if ( $$gvav && $savefields & Save_AV ) {
5225 0 0       0 warn "GV::save \@$fullname\n" if $debug{gv};
5226 0         0 $gvav->save($fullname);
5227 0         0 $init->add( sprintf( "GvAV(%s) = s\\_%x;", $sym, $$gvav ) );
5228 0 0       0 if ($fullname eq 'main::-') {
5229 0         0 $init->add( sprintf("AvFILLp(s\\_%x) = -1;", $$gvav),
5230             sprintf("AvMAX(s\\_%x) = -1;", $$gvav));
5231             }
5232             }
5233 0         0 my $gvhv = $gv->HV;
5234 0 0 0     0 if ( $$gvhv && $savefields & Save_HV ) {
5235 0 0       0 if ($fullname ne 'main::ENV') {
5236 0 0       0 warn "GV::save \%$fullname\n" if $debug{gv};
5237 0 0 0     0 if ($fullname eq 'main::!') { # force loading Errno
    0          
5238 0         0 $init->add("/* \%! force saving of Errno */");
5239 0         0 mark_package('Config', 1); # Errno needs Config to set the EGV
5240 0         0 walk_syms('Config');
5241 0         0 mark_package('Errno', 1); # B::C needs Errno but does not import $!
5242             } elsif ($fullname eq 'main::+' or $fullname eq 'main::-') {
5243 0         0 $init->add("/* \%$gvname force saving of Tie::Hash::NamedCapture */");
5244 0 0       0 if ($PERL514) {
5245 0         0 mark_package('Config', 1); # DynaLoader needs Config to set the EGV
5246 0         0 walk_syms('Config');
5247 0         0 svref_2object(\&{'Tie::Hash::NamedCapture::bootstrap'})->save;
  0         0  
5248             }
5249 0         0 mark_package('Tie::Hash::NamedCapture', 1);
5250             }
5251             # skip static %Encode::Encoding since 5.20. GH #200. sv_upgrade cannot upgrade itself.
5252             # Let it be initialized by boot_Encode/Encode_XSEncodingm with exceptions.
5253             # GH #200 and t/testc.sh 75
5254 0 0 0     0 if ($] >= 5.020 and $fullname eq 'Encode::Encoding') {
    0          
5255 0 0       0 warn "skip some %Encode::Encoding - XS initialized\n" if $debug{gv};
5256 0         0 my %tmp_Encode_Encoding = %Encode::Encoding;
5257 0         0 %Encode::Encoding = (); # but we need some non-XS encoding keys
5258 0         0 for my $k (qw(utf8 utf-8-strict Unicode Internal Guess)) {
5259 0 0       0 $Encode::Encoding{$k} = $tmp_Encode_Encoding{$k} if exists $tmp_Encode_Encoding{$k};
5260             }
5261 0         0 $gvhv->save($fullname);
5262 0         0 $init->add( "/* deferred some XS enc pointers for \%Encode::Encoding */",
5263             sprintf("GvHV(%s) = s\\_%x;", $sym, $$gvhv ) );
5264 0         0 %Encode::Encoding = %tmp_Encode_Encoding;
5265             }
5266             # XXX TODO 49: crash at BEGIN { %warnings::Bits = ... }
5267             elsif ($fullname ne 'main::INC') {
5268 0         0 $gvhv->save($fullname);
5269 0         0 $init->add( sprintf( "GvHV(%s) = s\\_%x;", $sym, $$gvhv ) );
5270             }
5271             }
5272             }
5273 0         0 my $gvcv = $gv->CV;
5274 0 0 0     0 if ( !$$gvcv and $savefields & Save_CV ) {
5275 0 0       0 warn "Empty CV $fullname, AUTOLOAD and try again\n" if $debug{gv};
5276 55     55   255 no strict 'refs';
  55         73  
  55         10576  
5277             # Fix test 31, catch unreferenced AUTOLOAD. The downside:
5278             # It stores the whole optree and all its children.
5279             # Similar with test 39: re::is_regexp
5280 0         0 svref_2object( \*{"$package\::AUTOLOAD"} )->save
5281 0 0 0     0 if $package and exists ${"$package\::"}{AUTOLOAD};
  0         0  
5282 0         0 svref_2object( \*{"$package\::CLONE"} )->save
5283 0 0 0     0 if $package and exists ${"$package\::"}{CLONE};
  0         0  
5284 0         0 $gvcv = $gv->CV; # try again
5285             }
5286 0 0 0     0 if ( $$gvcv and $savefields & Save_CV
      0        
      0        
      0        
5287             and ref($gvcv) eq 'B::CV'
5288             and ref($gvcv->GV->EGV) ne 'B::SPECIAL'
5289             and !skip_pkg($package) )
5290             {
5291 0         0 my $package = $gvcv->GV->EGV->STASH->NAME;
5292 0         0 my $oname = $gvcv->GV->EGV->NAME;
5293 0         0 my $origname = $package . "::" . $oname;
5294 0         0 my $cvsym;
5295 0 0 0     0 if ( $gvcv->XSUB and $oname ne '__ANON__' and $fullname ne $origname ) { #XSUB CONSTSUB alias
    0 0        
      0        
5296             warn "Boot $package, XS CONSTSUB alias of $fullname to $origname\n"
5297 0 0       0 if $debug{pkg};
5298 0         0 mark_package($package, 1);
5299             {
5300 55     55   220 no strict 'refs';
  55         80  
  55         61849  
  0         0  
5301 0         0 svref_2object( \&{"$package\::bootstrap"} )->save
5302 0 0 0     0 if $package and defined &{"$package\::bootstrap"};
  0         0  
5303             }
5304             # XXX issue 57: incomplete xs dependency detection
5305 0         0 my %hack_xs_detect =
5306             ('Scalar::Util' => 'List::Util',
5307             'Sub::Exporter' => 'Params::Util',
5308             );
5309 0 0       0 if (my $dep = $hack_xs_detect{$package}) {
5310 0         0 svref_2object( \&{"$dep\::bootstrap"} )->save;
  0         0  
5311             }
5312             # must save as a 'stub' so newXS() has a CV to populate
5313 0 0       0 warn "save stub CvGV for $sym GP assignments $origname\n" if $debug{gv};
5314 0         0 $init2->add(
5315             sprintf("if ((sv = (SV*)%s))", get_cv($origname, "GV_ADD")),
5316             sprintf(" GvCV_set(%s, (CV*)SvREFCNT_inc_simple_NN(sv));", $sym));
5317             # TODO: add evtl. to SvRV also.
5318             }
5319             elsif (!$PERL510 or $gp) {
5320 0 0       0 if ($fullname eq 'Internals::V') { # local_patches if $] >= 5.011
5321 0         0 $gvcv = svref_2object( \&__ANON__::_V );
5322             }
5323             # TODO: may need fix CvGEN if >0 to re-validate the CV methods
5324             # on PERL510 (>0 +
5325 0 0       0 warn "GV::save &$fullname...\n" if $debug{gv};
5326 0         0 $cvsym = $gvcv->save($fullname);
5327             # backpatch "$sym = gv_fetchpv($name, GV_ADD, SVt_PV)" to SVt_PVCV
5328 0 0       0 if ($cvsym =~ /get_cv/) {
    0          
5329 0 0 0     0 if (!$xsub{$package} and in_static_core($package, $gvname)) {
    0          
5330 0         0 my $in_gv;
5331 0         0 for (@{ $init->[-1]{current} }) {
  0         0  
5332 0 0       0 if ($in_gv) {
5333 0         0 s/^.*\Q$sym\E.*=.*;//;
5334 0         0 s/GvGP_set\(\Q$sym\E.*;//;
5335             }
5336 0         0 my $gv_get = gv_fetchpvn($name, "GV_ADD", "SVt_PV");
5337 0         0 my $new_gv_get = gv_fetchpvn($name, "GV_ADD", "SVt_PVCV");
5338 0 0       0 if (/^\Q$sym = $gv_get;\E/) {
5339 0         0 s/^\Q$sym = $gv_get;\E/$sym = $new_gv_get;/;
5340 0         0 $in_gv++;
5341 0 0       0 warn "removed $sym GP assignments $origname (core CV)\n" if $debug{gv};
5342             }
5343             }
5344 0         0 $init->add( sprintf( "GvCV_set(%s, (CV*)SvREFCNT_inc(%s));", $sym, $cvsym ));
5345             }
5346             elsif ($xsub{$package}) {
5347             # must save as a 'stub' so newXS() has a CV to populate later in dl_init()
5348 0 0       0 warn "save stub CvGV for $sym GP assignments $origname (XS CV)\n" if $debug{gv};
5349 0 0       0 my $get_cv = get_cv($oname ne "__ANON__" ? $origname : $fullname, "GV_ADD");
5350 0         0 $init2->add(sprintf("if ((sv = (SV*)%s))", $get_cv),
5351             sprintf(" GvCV_set(%s, (CV*)SvREFCNT_inc_simple_NN(sv));", $sym));
5352             }
5353             else {
5354 0         0 $init->add( sprintf( "GvCV_set(%s, (CV*)(%s));", $sym, $cvsym ));
5355             }
5356 0 0       0 if ($gvcv->XSUBANY) {
5357             # some XSUB's set this field. but which part?
5358 0         0 my $xsubany = $gvcv->XSUBANY;
5359 0 0       0 if ($package =~ /^DBI::(common|db|dr|st)/) {
    0          
5360             # DBI uses the any_ptr for dbi_ima_t *ima, and all dr,st,db,fd,xx handles
5361             # for which several ptrs need to be patched. #359
5362             # the ima is internal only
5363 0         0 my $dr = $1;
5364             warn sprintf("eval_pv: DBI->_install_method(%s-) (XSUBANY=0x%x)\n",
5365 0 0 0     0 $fullname, $xsubany) if $verbose and $debug{cv};
5366 0         0 $init2->add_eval(sprintf("DBI->_install_method('%s', 'DBI.pm', \$DBI::DBI_methods{%s}{%s})",
5367             $fullname, $dr, $fullname));
5368             } elsif ($package eq 'Tie::Hash::NamedCapture') {
5369             # pretty high _ALIAS CvXSUBANY.any_i32 values
5370             } else {
5371             # try if it points to an already registered symbol
5372 0         0 my $anyptr = $symtable{ sprintf( "s\\_%x", $xsubany ) };
5373 0 0 0     0 if ($anyptr and $xsubany > 1000) { # not a XsubAliases
    0 0        
    0 0        
5374 0         0 $init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_ptr = &%s;", $sym, $anyptr ));
5375             } # some heuristics TODO. long or ptr? TODO 32bit
5376             elsif ($xsubany > 0x100000
5377             and ($xsubany < 0xffffff00 or $xsubany > 0xffffffff))
5378             {
5379 0 0 0     0 if ($package eq 'POSIX' and $gvname =~ /^is/) {
    0 0        
5380             # need valid XSANY.any_dptr
5381 0         0 $init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_dptr = (void*)&%s;", $sym, $gvname));
5382             } elsif ($package eq 'List::MoreUtils' and $gvname =~ /_iterator$/) {
5383             # should be only the 2 iterators
5384 0         0 $init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_ptr = (void*)&%s;", $sym,
5385             "XS_List__MoreUtils__".$gvname));
5386             } else {
5387 0 0       0 warn sprintf("TODO: Skipping %s->XSUBANY = 0x%x\n", $fullname, $xsubany ) if $verbose;
5388 0         0 $init2->add( sprintf( "/* TODO CvXSUBANY(GvCV(%s)).any_ptr = 0x%lx; */", $sym, $xsubany ));
5389             }
5390             } elsif ($package eq 'Fcntl') {
5391             # S_ macro values
5392             } else {
5393             # most likely any_i32 values for the XsubAliases provided by xsubpp
5394 0         0 $init2->add( sprintf( "/* CvXSUBANY(GvCV(%s)).any_i32 = 0x%x; XSUB Alias */", $sym, $xsubany ));
5395             }
5396             }
5397             }
5398             }
5399             elsif ($cvsym =~ /^(cv|&sv_list)/) {
5400 0         0 $init->add( sprintf( "GvCV_set(%s, (CV*)(%s));", $sym, $cvsym ));
5401             }
5402             else {
5403 0 0 0     0 warn "wrong CvGV for $sym $origname: $cvsym\n" if $debug{gv} or $verbose;
5404             }
5405             }
5406             # special handling for backref magic
5407 0 0 0     0 if ($PERL514 and $cvsym and $cvsym !~ /(get_cv|NULL|lexwarn)/ and $gv->MAGICAL) {
      0        
      0        
5408 0         0 my @magic = $gv->MAGIC;
5409 0         0 foreach my $mg (@magic) {
5410 0 0       0 if ($mg->TYPE eq '<') {
5411 0         0 $init->add( "sv_magic((SV*)$sym, (SV*)$cvsym, '<', 0, 0);",
5412             "CvCVGV_RC_off($cvsym);");
5413 0 0       0 if (!($mg->FLAGS & 2)) {
5414 0         0 mg_RC_off($mg, $sym, '<'); # 390
5415             }
5416             }
5417             }
5418             }
5419             }
5420 0 0 0     0 if (!$PERL510 or $gp) {
5421 0 0       0 if ( $] > 5.009 ) {
5422             # TODO implement heksect to place all heks at the beginning
5423             #$heksect->add($gv->FILE);
5424             #$init->add(sprintf("GvFILE_HEK($sym) = hek_list[%d];", $heksect->index));
5425              
5426             # XXX Maybe better leave it NULL or asis, than fighting broken
5427 0 0 0     0 if ($B::C::stash and $fullname =~ /::$/) {
5428             # ignore stash hek asserts when adding the stash
5429             # he->shared_he_he.hent_hek == hek assertions (#46 with IO::Poll::)
5430             } else {
5431 0         0 my $file = save_hek($gv->FILE,$fullname,1);
5432 0 0 0     0 $init->add(sprintf("GvFILE_HEK(%s) = %s;", $sym, $file))
5433             if $file ne 'NULL' and !$optimize_cop;
5434             }
5435             # $init->add(sprintf("GvNAME_HEK($sym) = %s;", save_hek($gv->NAME))) if $gv->NAME;
5436             } else {
5437             # XXX ifdef USE_ITHREADS and PL_curcop->op_flags & OPf_COP_TEMP
5438             # GvFILE is at gp+1
5439 0 0       0 $init->add( sprintf( "GvFILE(%s) = %s;", $sym, cstring( $gv->FILE ) ))
5440             unless $optimize_cop;
5441             warn "GV::save GvFILE(*$fullname) " . cstring( $gv->FILE ) . "\n"
5442 0 0 0     0 if $debug{gv} and !$ITHREADS;
5443             }
5444 0         0 my $gvform = $gv->FORM;
5445 0 0 0     0 if ( $$gvform && $savefields & Save_FORM ) {
5446 0 0       0 warn "GV::save GvFORM(*$fullname) ...\n" if $debug{gv};
5447 0         0 $gvform->save($fullname);
5448 0         0 $init->add( sprintf( "GvFORM(%s) = (CV*)s\\_%x;", $sym, $$gvform ));
5449             # glob_assign_glob analog to CV
5450 0 0       0 $init->add( sprintf( "SvREFCNT_inc(s\\_%x);", $$gvform )) if $PERL510;
5451 0 0       0 warn "GV::save GvFORM(*$fullname) done\n" if $debug{gv};
5452             }
5453 0         0 my $gvio = $gv->IO;
5454 0 0 0     0 if ( $$gvio && $savefields & Save_IO ) {
5455 0 0       0 warn "GV::save GvIO(*$fullname)...\n" if $debug{gv};
5456 0 0 0     0 if ( $fullname =~ m/::DATA$/ &&
    0 0        
      0        
5457             ( $fullname eq 'main::DATA' or $B::C::save_data_fh) ) # -O2 or 5.8
5458             {
5459 55     55   288 no strict 'refs';
  55         83  
  55         2247  
5460 0         0 my $fh = *{$fullname}{IO};
  0         0  
5461 55     55   212 use strict 'refs';
  55         83  
  55         479673  
5462 0 0       0 warn "GV::save_data $sym, $fullname ...\n" if $debug{gv};
5463 0         0 $gvio->save($fullname, 'is_DATA');
5464 0         0 $init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) );
5465 0 0       0 $gvio->save_data( $sym, $fullname, <$fh> ) if $fh->opened;
5466             } elsif ( $fullname =~ m/::DATA$/ && !$B::C::save_data_fh ) {
5467 0         0 $gvio->save($fullname, 'is_DATA');
5468 0         0 $init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) );
5469 0         0 warn "Warning: __DATA__ handle $fullname not stored. Need -O2 or -fsave-data.\n";
5470             } else {
5471 0         0 $gvio->save($fullname);
5472 0         0 $init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) );
5473             }
5474 0 0       0 warn "GV::save GvIO(*$fullname) done\n" if $debug{gv};
5475             }
5476 0         0 $init->add("");
5477             }
5478             }
5479             # Shouldn't need to do save_magic since gv_fetchpv handles that. Esp. < and IO not
5480             # $gv->save_magic($fullname) if $PERL510;
5481 0 0       0 warn "GV::save *$fullname done\n" if $debug{gv};
5482 0         0 return $sym;
5483             }
5484              
5485             sub B::AV::save {
5486 0     0   0 my ($av, $fullname, $cv) = @_;
5487 0         0 my $sym = objsym($av);
5488 0 0       0 return $sym if defined $sym;
5489              
5490 0 0       0 $fullname = '' unless $fullname;
5491 0         0 my ($fill, $avreal, $max, $static_av, $av_cow, $av_cog);
5492 0         0 my $ispadlist = ref($av) eq 'B::PADLIST';
5493 0         0 my $ispadnamelist = ref($av) eq 'B::PADNAMELIST';
5494 0 0 0     0 if ($ispadnamelist or $ispadlist) {
5495 0         0 $fill = $av->MAX;
5496             } else {
5497             # cornercase: tied array without FETCHSIZE
5498 0         0 eval { $fill = $av->FILL; };
  0         0  
5499 0 0       0 $fill = -1 if $@; # catch error in tie magic
5500             }
5501 0         0 $max = $fill;
5502 0 0       0 my $svpcast = $ispadlist ? "(PAD*)" : "(SV*)";
5503 0 0       0 $svpcast = "(PADNAME*)" if $ispadnamelist;
5504              
5505 0 0 0     0 if ($PERL522 and $ispadnamelist) {
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
      0        
      0        
5506 0         0 $padnlsect->comment("xpadnl_fill, xpadnl_alloc, xpadnl_max, xpadnl_max_named, xpadnl_refcnt");
5507             # TODO: max_named walk all names and look for non-empty names
5508 0         0 my $refcnt = $av->REFCNT + 1; # XXX defer free to global destruction: 28
5509 0         0 my $maxnamed = $av->MAXNAMED;
5510 0         0 $padnlsect->add("$fill, NULL, $fill, $maxnamed, $refcnt /* +1 */");
5511 0         0 $padnl_index = $padnlsect->index;
5512 0         0 $sym = savesym( $av, "&padnamelist_list[$padnl_index]" );
5513 0         0 push @B::C::static_free, $sym;
5514             }
5515             elsif ($ispadlist and $] >= 5.021008) { # id+outid as U32 (PL_padlist_generation++)
5516 0         0 $padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_id, xpadl_outid");
5517 0         0 my ($id, $outid) = ($av->ID, $av->OUTID);
5518 0         0 $padlistsect->add("$fill, NULL, $id, $outid");
5519 0         0 $padlist_index = $padlistsect->index;
5520 0         0 $sym = savesym( $av, "&padlist_list[$padlist_index]" );
5521             }
5522             elsif ($ispadlist and $] >= 5.017006 and $] < 5.021008) { # id added again with b4db586814
5523 0         0 $padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_outid");
5524 0         0 $padlistsect->add("$fill, NULL, NULL"); # Perl_pad_new(0)
5525 0         0 $padlist_index = $padlistsect->index;
5526 0         0 $sym = savesym( $av, "&padlist_list[$padlist_index]" );
5527 0 0 0     0 if ($cv and $cv->OUTSIDE and ref($cv->OUTSIDE) ne 'B::SPECIAL' and $cv->OUTSIDE->PADLIST) {
      0        
      0        
5528 0         0 my $outid = $cv->OUTSIDE->PADLIST->save();
5529 0 0       0 $init->add("($sym)->xpadl_outid = (PADNAMELIST*)$outid;") if $outid;
5530             }
5531             }
5532             elsif ($ispadlist and $] >= 5.017004) {
5533 0         0 $padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_id, xpadl_outid");
5534 0         0 $padlistsect->add("$fill, NULL, 0, 0"); # Perl_pad_new(0)
5535 0         0 $padlist_index = $padlistsect->index;
5536 0         0 $sym = savesym( $av, "&padlist_list[$padlist_index]" );
5537 0 0 0     0 if ($cv and $cv->OUTSIDE and ref($cv->OUTSIDE) ne 'B::SPECIAL' and $cv->OUTSIDE->PADLIST) {
      0        
      0        
5538 0         0 my $outid = $cv->OUTSIDE->PADLIST->save();
5539 0 0       0 $init->add("($sym)->xpadl_outid = (PADNAMELIST*)$outid;") if $outid;
5540             }
5541             }
5542             # we set it static, not perl. (c)perl only observes it.
5543             # decide if to store the array static (with run-time cow overhead) or dynamic
5544             elsif ($CPERL52 and $B::C::av_init and $fill > -1
5545             and (isAvSTATIC($av) or canAvSTATIC($av, $fullname)))
5546             {
5547 0         0 $xpvavsect->comment( "stash, magic, fill, max, static alloc" );
5548 0         0 my $alloc = "";
5549 0         0 my $count = 0;
5550 0         0 my $flags = $av->FLAGS;
5551             # decide upon cow (const array, SVf_READONLY) or just cog (forbid av_extend)
5552 0 0 0     0 my $av_cow = ($flags & SVf_READONLY or $fullname =~ /(::ISA|::INC|curpad_name)$/) ? 1 : 0;
5553 0         0 my $magic = ''; # need to skip ->ARRAY with 'D' magic, test 90
5554 0         0 foreach my $mg ($av->MAGIC) {
5555 0         0 $magic = $mg->TYPE;
5556 0 0       0 if ($magic eq 'D') {
5557 0         0 last;
5558             }
5559             }
5560 0 0       0 my @array = $magic eq 'D' ? () : $av->ARRAY;
5561 0         0 my $n = scalar @array;
5562 0 0       0 my $name = ($av_cow ? "avcow_" : "avcog_") . $n;
5563 0         0 my $avstaticsect;
5564 0 0       0 if ($av_cow) {
5565 0 0       0 $avcowsect{ $n } = new B::C::Section($name, \%symtable, 0) unless exists $avcowsect{ $n };
5566 0         0 $avstaticsect = $avcowsect{ $n };
5567             } else {
5568 0 0       0 $avcogsect{ $n } = new B::C::Section($name, \%symtable, 0) unless exists $avcogsect{ $n };
5569 0         0 $avstaticsect = $avcogsect{ $n };
5570             }
5571 0         0 my $sect = sprintf("&%s_list[%u]", $name, $avstaticsect->index + 1);
5572             # protect against duplicates
5573 0         0 $sym = savesym( $av, sprintf("(AV*)&sv_list[%u]", $svsect->index + 1));
5574              
5575             # $B::C::const_strings = 0 if $flags & 0x40008000 == 0x40008000; # SVp_SCREAM|SVpbm_VALID
5576 0 0       0 my @values = map { $_->save($fullname."[".$count++."]") || () } @array;
  0         0  
5577 0         0 for (my $i=0; $i <= $#array; $i++) {
5578             # if any value is non-static (GV), fall back to dynamic AV::save
5579 0 0       0 if (!is_constant($values[$i])) {
5580 0         0 $alloc = '';
5581 0         0 last;
5582             }
5583 0         0 $alloc .= $values[$i].", ";
5584             }
5585 0 0 0     0 if ($alloc and $n) {
5586 0         0 $static_av = 1;
5587             warn sprintf("turn on %s %s\n", $av_cow ? "AvIsCOW" : "AvSTATIC", $sym, $fullname)
5588 0 0       0 if $debug{av};
    0          
5589 0         0 $flags |= SVf_IsCOW; # turn on AvSTATIC
5590             # $flags |= SVf_READONLY if $av_cow; # and turn on COW
5591 0         0 $alloc = substr($alloc,0,-2);
5592 0         0 $avstaticsect->add( $alloc );
5593 0         0 $xpvavsect->add("Nullhv, {0}, $fill, $max, (SV**)$sect");
5594 0 0       0 $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}",
5595             $xpvavsect->index, $av->REFCNT, $flags,
5596             ($C99?".svu_array=(SV**)":"(char*)").$sect));
5597 0         0 $sym = savesym( $av, sprintf("(AV*)&sv_list[%u]", $svsect->index));
5598             } else {
5599             warn sprintf("turn off AvSTATIC %s %s\n", $sym, $fullname)
5600 0 0       0 if $debug{av};
5601 0         0 $flags &= ~SVf_IsCOW; # turn off AvSTATIC
5602 0         0 my $line = "Nullhv, {0}, -1, -1, 0";
5603 0 0 0     0 $line = "Nullhv, {0}, $fill, $max, 0" if $B::C::av_init or $B::C::av_init2;
5604 0         0 $xpvavsect->add($line);
5605 0         0 $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {0}",
5606             $xpvavsect->index, $av->REFCNT, $flags));
5607             }
5608             }
5609             elsif ($PERL514) {
5610 0         0 $xpvavsect->comment( "stash, magic, fill, max, alloc" );
5611             # 5.13.3: STASH, MAGIC, fill max ALLOC
5612 0         0 my $line = "Nullhv, {0}, -1, -1, 0";
5613 0 0 0     0 $line = "Nullhv, {0}, $fill, $max, 0" if $B::C::av_init or $B::C::av_init2;
5614 0         0 $xpvavsect->add($line);
5615 0         0 $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}",
5616             $xpvavsect->index, $av->REFCNT, $av->FLAGS,
5617             '0'));
5618             #$avreal = $av->FLAGS & 0x40000000; # SVpav_REAL (unused)
5619             }
5620             elsif ($PERL510) {
5621 0         0 $xpvavsect->comment( "xnv_u, fill, max, xiv_u, magic, stash" );
5622             # 5.9.4+: nvu fill max iv MG STASH
5623 0         0 my $line = "{0}, -1, -1, {0}, {0}, Nullhv";
5624 0 0 0     0 $line = "{0}, $fill, $max, {0}, {0}, Nullhv" if $B::C::av_init or $B::C::av_init2;
5625 0 0       0 $line = "Nullhv, {0}, $fill, $max, NULL" if $PERL514;
5626 0         0 $xpvavsect->add($line);
5627 0         0 $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}",
5628             $xpvavsect->index, $av->REFCNT, $av->FLAGS,
5629             '0'));
5630             #$avreal = $av->FLAGS & 0x40000000; # SVpav_REAL (unused)
5631             }
5632             else {
5633 0         0 $xpvavsect->comment( "array, fill, max, off, nv, magic, stash, alloc, arylen, flags" );
5634             # 5.8: ARRAY fill max off nv MG STASH ALLOC arylen flags
5635 0         0 my $line = "0, -1, -1, 0, 0.0, 0, Nullhv, 0, 0";
5636 0 0 0     0 $line = "0, $fill, $max, 0, 0.0, 0, Nullhv, 0, 0" if $B::C::av_init or $B::C::av_init2;
5637 0 0       0 $line .= sprintf( ", 0x%x", $av->AvFLAGS ) if $] < 5.009;
5638             #$avreal = $av->AvFLAGS & 1; # AVf_REAL
5639 0         0 $xpvavsect->add($line);
5640 0         0 $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x",
5641             $xpvavsect->index, $av->REFCNT, $av->FLAGS));
5642             }
5643              
5644 0         0 my ($magic, $av_index) = ('');
5645 0 0       0 $svsect->debug($fullname, $av->flagspv) if $debug{flags};
5646 0 0 0     0 if (!$ispadlist and !$ispadnamelist) {
5647 0         0 my $sv_ix = $svsect->index;
5648 0         0 $av_index = $xpvavsect->index;
5649             # protect against recursive self-references (Getopt::Long)
5650 0         0 $sym = savesym( $av, "(AV*)&sv_list[$sv_ix]" );
5651 0         0 $magic = $av->save_magic($fullname);
5652 0 0 0     0 push @B::C::static_free, $sym if $PERL518 and $av->FLAGS & SVs_OBJECT;
5653             }
5654              
5655 0 0       0 if ( $debug{av} ) {
5656 0         0 my $line = sprintf( "saving AV %s 0x%x [%s] FILL=%d", $fullname, $$av, B::class($av), $fill);
5657 0 0       0 $line .= sprintf( " AvFLAGS=0x%x", $av->AvFLAGS ) if $] < 5.009;
5658 0         0 warn "$line\n";
5659             }
5660              
5661             # XXX AVf_REAL is wrong test: need to save comppadlist but not stack
5662 0 0 0     0 if ($fill > -1 and $magic !~ /D/ and !$static_av) {
      0        
5663 0         0 my @array = $av->ARRAY; # crashes with D magic (Getopt::Long)
5664 0 0       0 if ( $debug{av} ) {
5665 0         0 my $i = 0;
5666 0         0 foreach my $el (@array) {
5667 0         0 my $val = '';
5668             # if SvIOK print iv, POK pv
5669 0 0       0 if ($el->can('FLAGS')) {
5670 0 0       0 $val = $el->IVX if $el->FLAGS & SVf_IOK;
5671 0 0       0 $val = cstring($el->PV) if $el->FLAGS & SVf_POK;
5672             }
5673 0         0 warn sprintf( "AV $av \[%d] = %s $val\n", $i++, B::class($el) );
5674             }
5675             }
5676              
5677             # my @names = map($_->save, @array);
5678             # XXX Better ways to write loop?
5679             # Perhaps svp[0] = ...; svp[1] = ...; svp[2] = ...;
5680             # Perhaps I32 i = 0; svp[i++] = ...; svp[i++] = ...; svp[i++] = ...;
5681              
5682             # micro optimization: op/pat.t ( and other code probably )
5683             # has very large pads ( 20k/30k elements ) passing them to
5684             # ->add is a performance bottleneck: passing them as a
5685             # single string cuts runtime from 6min20sec to 40sec
5686              
5687             # you want to keep this out of the no_split/split
5688             # map("\t*svp++ = (SV*)$_;", @names),
5689 0         0 my $acc = '';
5690             # Init optimization by Nick Koston
5691             # The idea is to create loops so there is less C code. In the real world this seems
5692             # to reduce the memory usage ~ 3% and speed up startup time by about 8%.
5693 0         0 my ($count, @values);
5694             {
5695 0         0 local $B::C::const_strings = $B::C::const_strings;
  0         0  
5696 0 0 0     0 if ($PERL510 and !$ispadlist) { # force dynamic PADNAME strings
5697 0 0       0 if ($] < 5.016) { $B::C::const_strings = 0 if $av->FLAGS & 0x40000000; } # SVpad_NAME
  0 0       0  
5698 0 0       0 else { $B::C::const_strings = 0 if ($av->FLAGS & 0x40008000 == 0x40008000); } # SVp_SCREAM|SVpbm_VALID
5699             }
5700 0 0       0 @values = map { $_->save($fullname."[".$count++."]") || () } @array;
  0         0  
5701             }
5702 0         0 $count = 0;
5703 0         0 for (my $i=0; $i <= $#array; $i++) {
5704 0 0 0     0 if ($fullname =~ m/^(INIT|END)$/ and $values[$i] and ref $array[$i] eq 'B::CV') {
      0        
5705 0 0       0 if ($array[$i]->XSUB) {
5706 0         0 $values[$i] =~ s/, 0\)/, GV_ADD\)/; # GvCV filled in later
5707             }
5708 0         0 $values[$i] = sprintf("SvREFCNT_inc(%s);", $values[$i]);
5709             }
5710 0 0 0     0 if ( $use_svpop_speedup
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
5711             && defined $values[$i]
5712             && defined $values[$i+1]
5713             && defined $values[$i+2]
5714             && $values[$i] =~ /^\&sv_list\[(\d+)\]/
5715             && $values[$i+1] eq "&sv_list[" . ($1+1) . "]"
5716             && $values[$i+2] eq "&sv_list[" . ($1+2) . "]" )
5717             {
5718 0         0 $count=0;
5719 0   0     0 while (defined($values[$i+$count+1]) and $values[$i+$count+1] eq "&sv_list[" . ($1+$count+1) . "]") {
5720 0         0 $count++;
5721             }
5722 0         0 $acc .= "\tfor (gcount=" . $1 . "; gcount<" . ($1+$count+1) . "; gcount++) {"
5723             ." *svp++ = $svpcast&sv_list[gcount]; };\n\t";
5724 0         0 $i += $count;
5725             } elsif ($use_av_undef_speedup
5726             && defined $values[$i]
5727             && defined $values[$i+1]
5728             && defined $values[$i+2]
5729             && $values[$i] =~ /^ptr_undef|&PL_sv_undef$/
5730             && $values[$i+1] =~ /^ptr_undef|&PL_sv_undef$/
5731             && $values[$i+2] =~ /^ptr_undef|&PL_sv_undef$/)
5732             {
5733 0         0 $count=0;
5734 0   0     0 while (defined $values[$i+$count+1] and $values[$i+$count+1] =~ /^ptr_undef|&PL_sv_undef$/) {
5735 0         0 $count++;
5736             }
5737 0         0 $acc .= "\tfor (gcount=0; gcount<" . ($count+1) . "; gcount++) {"
5738             ." *svp++ = $svpcast&PL_sv_undef; };\n\t";
5739 0         0 $i += $count;
5740             } else { # XXX 5.8.9d Test::NoWarnings has empty values
5741 0 0       0 $acc .= "\t*svp++ = $svpcast" . ($values[$i] ? $values[$i] : '&PL_sv_undef') . ";\n\t";
5742             }
5743             }
5744 0         0 $init->no_split;
5745              
5746 0 0       0 if ($ispadnamelist) {
    0          
    0          
    0          
5747 0         0 my $fill1 = $fill+1;
5748 0         0 $init->add("{", "\tPADNAME **svp;");
5749 0 0       0 $init->add("\tregister int gcount;") if $count;
5750 0         0 $init->add(
5751             "\tPADNAMELIST *padnl = $sym;",
5752             sprintf("\tNewxz(svp, %d, PADNAME *);", $fill+1),
5753             "\tPadnamelistARRAY(padnl) = svp;",
5754             );
5755 0         0 $init->add( substr( $acc, 0, -2 ) );
5756 0         0 $init->add("}");
5757             }
5758             elsif ($ispadlist) {
5759 0         0 my $fill1 = $fill+1;
5760 0         0 $init->add("{", "\tPAD **svp;");
5761 0 0       0 $init->add("\tregister int gcount;") if $count;
5762 0         0 $init->add(
5763             "\tPADLIST *padl = $sym;",
5764             sprintf("\tNewxz(svp, %d, PAD *);", $fill+1),
5765             "\tPadlistARRAY(padl) = svp;",
5766             );
5767 0         0 $init->add( substr( $acc, 0, -2 ) );
5768 0         0 $init->add("}");
5769             }
5770             # With -fav-init2 use independent_comalloc()
5771             elsif ($B::C::av_init2) {
5772 0         0 my $i = $av_index;
5773 0         0 $xpvav_sizes[$i] = $fill;
5774 0         0 my $init_add = "{ SV **svp = avchunks[$i]; AV *av = $sym;\n";
5775 0 0       0 $init_add .= "\tregister int gcount;\n" if $count;
5776 0 0       0 if ($fill > -1) {
5777 0 0       0 if ($PERL510) {
5778 0         0 $init_add .= "\tAvALLOC(av) = svp;\n".
5779             "\tAvARRAY(av) = svp;\n";
5780             } else {
5781 0         0 $init_add .= "\tAvALLOC(av) = svp;\n" .
5782             # XXX Dirty hack from av.c:Perl_av_extend()
5783             "\tSvPVX(av) = (char*)svp;";
5784             }
5785             }
5786 0         0 $init_add .= substr( $acc, 0, -2 );
5787 0         0 $init->add( $init_add . "}" );
5788             }
5789             # With -fav-init faster initialize the array as the initial av_extend()
5790             # is very expensive.
5791             # The problem was calloc, not av_extend.
5792             # Since we are always initializing every single element we don't need
5793             # calloc, only malloc. wmemset'ting the pointer to PL_sv_undef
5794             # might be faster also.
5795             elsif ($B::C::av_init) {
5796 0         0 $init->add(
5797             "{", "\tSV **svp;",
5798             "\tAV *av = $sym;");
5799 0 0       0 $init->add("\tregister int gcount;") if $count;
5800 0 0       0 my $fill1 = $fill < 3 ? 3 : $fill+1;
5801 0 0       0 if ($fill > -1) {
5802 0 0       0 $fill1 = $fill+1 if $fullname eq 'END';
5803             # Perl_safesysmalloc (= calloc => malloc) or Perl_malloc (= mymalloc)?
5804 0 0       0 if ($MYMALLOC) {
5805 0         0 $init->add(sprintf("\tNewx(svp, %d, SV*);", $fill1),
5806             "\tAvALLOC(av) = svp;");
5807             } else {
5808             # Bypassing Perl_safesysmalloc on darwin fails with "free from wrong pool", test 25.
5809             # So with DEBUGGING perls we have to track memory and use calloc.
5810 0         0 $init->add("#ifdef PERL_TRACK_MEMPOOL",
5811             sprintf("\tsvp = (SV**)Perl_safesysmalloc(%d * sizeof(SV*));", $fill1),
5812             "#else",
5813             sprintf("\tsvp = (SV**)malloc(%d * sizeof(SV*));", $fill1),
5814             "#endif",
5815             "\tAvALLOC(av) = svp;");
5816             }
5817 0 0       0 if ($PERL510) {
5818 0         0 $init->add("\tAvARRAY(av) = svp;");
5819             } else { # read-only AvARRAY macro
5820             # XXX Dirty hack from av.c:Perl_av_extend()
5821 0         0 $init->add("\tSvPVX(av) = (char*)svp;");
5822             }
5823             }
5824 0         0 $init->add( substr( $acc, 0, -2 ) ); # AvFILLp already in XPVAV
5825 0         0 $init->add( "}" );
5826             }
5827             else { # unoptimized with the full av_extend()
5828 0 0       0 my $fill1 = $fill < 3 ? 3 : $fill+1;
5829 0         0 $init->add("{", "\tSV **svp;");
5830 0 0       0 $init->add("\tregister int gcount;") if $count;
5831 0         0 $init->add("\tAV *av = $sym;\t/* $fullname */",
5832             "\tav_extend(av, $fill1);",
5833             "\tsvp = AvARRAY(av);");
5834 0         0 $init->add( substr( $acc, 0, -2 ) );
5835 0         0 $init->add( "\tAvFILLp(av) = $fill;" );
5836 0         0 $init->add( "}" );
5837             }
5838 0         0 $init->split;
5839              
5840             # we really added a lot of lines ( B::C::InitSection->add
5841             # should really scan for \n, but that would slow
5842             # it down
5843 0         0 $init->inc_count($#array);
5844             }
5845             else {
5846 0         0 my $max = $av->MAX;
5847 0 0 0     0 $init->add("av_extend($sym, $max);")
5848             if $max > -1 and !$static_av;
5849             }
5850 0 0       0 $init->add("SvREADONLY_on($sym);") if $av_cow;
5851 0         0 return $sym;
5852             }
5853              
5854             sub B::HV::save {
5855 0     0   0 my ($hv, $fullname) = @_;
5856 0 0       0 $fullname = '' unless $fullname;
5857 0         0 my $sym = objsym($hv);
5858 0 0       0 return $sym if defined $sym;
5859 0         0 my $name = $hv->NAME;
5860 0         0 my $is_stash = $name;
5861 0         0 my $magic;
5862 0 0       0 if ($name) {
5863             # It's a stash. See issue 79 + test 46
5864             warn sprintf( "Saving stash HV \"%s\" from \"$fullname\" 0x%x MAX=%d\n",
5865 0 0       0 $name, $$hv, $hv->MAX ) if $debug{hv};
5866              
5867             # A perl bug means HvPMROOT isn't altered when a PMOP is freed. Usually
5868             # the only symptom is that sv_reset tries to reset the PMf_USED flag of
5869             # a trashed op but we look at the trashed op_type and segfault.
5870             #my $adpmroot = ${$hv->PMROOT}; # XXX When was this fixed?
5871 0         0 my $adpmroot = 0;
5872 0         0 $sym = savestashpv($name);
5873 0         0 savesym( $hv, $sym );
5874 0 0       0 if ($adpmroot) {
5875 0         0 $init->add(sprintf( "HvPMROOT(hv%d) = (PMOP*)s\\_%x;",
5876             $hv_index, $adpmroot ) );
5877             }
5878 0 0 0     0 if ($PERL518 and $hv->FLAGS & SVf_AMAGIC and length($name)) {
      0        
5879             # fix overload stringify
5880 0 0       0 if ($hv->Gv_AMG) { # potentially removes the AMG flag
5881 0         0 $init2->add( sprintf("mro_isa_changed_in(%s); /* %s */", $sym, $name));
5882             }
5883             }
5884             # Add aliases if namecount > 1 (GH #331)
5885             # There was no B API for the count or multiple enames, so I added one.
5886 0 0       0 my @enames = ($PERL514 ? $hv->ENAMES : ());
5887 0 0       0 if (@enames > 1) {
5888 0 0       0 warn "Saving for $name multiple enames: ", join(" ",@enames), "\n" if $debug{hv};
5889 0         0 my $name_count = $hv->name_count;
5890             # If the stash name is empty xhv_name_count is negative, and names[0] should
5891             # be already set. but we rather write it.
5892 0         0 $init->no_split;
5893 0         0 my $hv_max = $hv->MAX + 1;
5894             # unshift @enames, $name if $name_count < 0; # stashpv has already set names[0]
5895 0         0 $init->add( "if (!SvOOK($sym)) {", # hv_auxinit is not exported
5896             " HE **a;",
5897             "#ifdef PERL_USE_LARGE_HV_ALLOC",
5898             sprintf( " Newxz(a, PERL_HV_ARRAY_ALLOC_BYTES(%d) + sizeof(struct xpvhv_aux), HE*);",
5899             $hv_max),
5900             "#else",
5901             sprintf( " Newxz(a, %d + sizeof(struct xpvhv_aux), HE*);", $hv_max),
5902             "#endif",
5903             " SvOOK_on($sym);",
5904             "}",
5905             "{",
5906             " struct xpvhv_aux *aux = HvAUX($sym);",
5907             sprintf( " Newx(aux->xhv_name_u.xhvnameu_names, %d, HEK*);", scalar @enames),
5908             sprintf( " aux->xhv_name_count = %d;", $name_count));
5909 0         0 my $i = 0;
5910 0         0 while (@enames) {
5911 0         0 my ($cstring, $cur, $utf8) = strlen_flags(shift @enames);
5912 0 0       0 $init->add(
5913             sprintf( " aux->xhv_name_u.xhvnameu_names[%u] = share_hek(%s, %d);",
5914             $i++, $cstring, $utf8 ? -$cur : $cur));
5915             }
5916 0         0 $init->add( "}" );
5917 0         0 $init->split;
5918             }
5919              
5920             # issue 79, test 46: save stashes to check for packages.
5921             # and via B::STASHGV we only save stashes for stashes.
5922             # For efficiency we skip most stash symbols unless -fstash.
5923             # However it should be now safe to save all stash symbols.
5924             # $fullname !~ /::$/ or
5925 0 0       0 if (!$B::C::stash) { # -fno-stash: do not save stashes
5926 0         0 $magic = $hv->save_magic('%'.$name.'::'); #symtab magic set in PMOP #188 (#267)
5927 0 0 0     0 if ($PERL510 and is_using_mro() && mro::get_mro($name) eq 'c3') {
      0        
5928 0         0 B::C::make_c3($name);
5929             }
5930 0 0 0     0 if ($magic and $magic =~ /c/) {
5931 0 0       0 warn "defer AMT magic of $name\n" if $debug{mg};
5932             # defer AMT magic of XS loaded hashes. #305 Encode::XS with tiehash magic
5933             # $init1->add(qq[$sym = gv_stashpvn($cname, $len, GV_ADDWARN|GV_ADDMULTI);]);
5934             }
5935 0         0 return $sym;
5936             }
5937 0 0 0     0 return $sym if skip_pkg($name) or $name eq 'main';
5938 0         0 $init->add( "SvREFCNT_inc($sym);" );
5939 0 0       0 warn "Saving stash keys for HV \"$name\" from \"$fullname\"\n" if $debug{hv};
5940             }
5941              
5942             # Ordinary HV or Stash
5943             # KEYS = 0, inc. dynamically below with hv_store. TODO: HvSTATIC readonly tables,
5944             # without hv_store
5945 0 0       0 if ($PERL510) {
5946 0         0 my $flags = $hv->FLAGS & ~SVf_READONLY;
5947 0 0       0 $flags &= ~SVf_PROTECT if $PERL522;
5948 0 0       0 if ($PERL514) { # fill removed with 5.13.1
5949 0         0 $xpvhvsect->comment( "stash mgu max keys" );
5950 0         0 $xpvhvsect->add(sprintf( "Nullhv, {0}, %d, %d",
5951             $hv->MAX, 0 ));
5952             } else {
5953 0         0 $xpvhvsect->comment( "GVSTASH fill max keys MG STASH" );
5954 0         0 $xpvhvsect->add(sprintf( "{0}, %d, %d, {%d}, {0}, Nullhv",
5955             0, $hv->MAX, 0 ));
5956             }
5957 0         0 $svsect->add(sprintf("&xpvhv_list[%d], $u32fmt, 0x%x, {0}",
5958             $xpvhvsect->index, $hv->REFCNT, $flags));
5959             # XXX failed at 16 (tied magic) for %main::
5960 0 0 0     0 if (!$is_stash and ($] >= 5.010 and $hv->FLAGS & SVf_OOK)) {
      0        
5961 0         0 $sym = sprintf("&sv_list[%d]", $svsect->index);
5962 0         0 my $hv_max = $hv->MAX + 1;
5963             # riter required, new _aux struct at the end of the HvARRAY. allocate ARRAY also.
5964 0         0 $init->add("{\tHE **a;",
5965             "#ifdef PERL_USE_LARGE_HV_ALLOC",
5966             sprintf("\tNewxz(a, PERL_HV_ARRAY_ALLOC_BYTES(%d) + sizeof(struct xpvhv_aux), HE*);",
5967             $hv_max),
5968             "#else",
5969             sprintf("\tNewxz(a, %d + sizeof(struct xpvhv_aux), HE*);", $hv_max),
5970             "#endif",
5971             "\tHvARRAY($sym) = a;",
5972             sprintf("\tHvRITER_set($sym, %d);", $hv->RITER),"}");
5973             }
5974             } # !5.10
5975             else {
5976 0         0 $xpvhvsect->comment( "array fill max keys nv mg stash riter eiter pmroot name" );
5977 0         0 $xpvhvsect->add(sprintf( "0, 0, %d, 0, 0.0, 0, Nullhv, %d, 0, 0, 0",
5978             $hv->MAX, $hv->RITER));
5979 0         0 $svsect->add(sprintf( "&xpvhv_list[%d], $u32fmt, 0x%x",
5980             $xpvhvsect->index, $hv->REFCNT, $hv->FLAGS));
5981             }
5982 0 0       0 $svsect->debug($fullname, $hv->flagspv) if $debug{flags};
5983 0         0 my $sv_list_index = $svsect->index;
5984             warn sprintf( "saving HV %s &sv_list[%d] 0x%x MAX=%d KEYS=%d\n",
5985 0 0       0 "%".$fullname, $sv_list_index, $$hv, $hv->MAX, $hv->KEYS ) if $debug{hv};
5986             # XXX B does not keep the UTF8 flag [RT 120535] #200
5987             # shared heks only since 5.10, our fixed C.xs variant
5988 0 0 0     0 my @contents = ($PERL510 && $hv->can('ARRAY_utf8')) ? $hv->ARRAY_utf8 : $hv->ARRAY;
5989             # protect against recursive self-reference
5990             # i.e. with use Moose at stash Class::MOP::Class::Immutable::Trait
5991             # value => rv => cv => ... => rv => same hash
5992 0 0       0 $sym = savesym( $hv, "(HV*)&sv_list[$sv_list_index]" ) unless $is_stash;
5993 0 0 0     0 push @B::C::static_free, $sym if $PERL518 and $hv->FLAGS & SVs_OBJECT;
5994              
5995 0 0       0 if (@contents) {
    0          
5996 0         0 local $B::C::const_strings = $B::C::const_strings;
5997 0         0 my ($i, $length);
5998 0         0 $length = scalar(@contents);
5999 0         0 for ( $i = 1 ; $i < @contents ; $i += 2 ) {
6000 0         0 my $key = $contents[$i - 1]; # string only
6001 0         0 my $sv = $contents[$i];
6002             warn sprintf("HV recursion? with $fullname\{$key\} -> %s\n", $sv->RV)
6003             if ref($sv) eq 'B::RV'
6004             #and $sv->RV->isa('B::CV')
6005             and defined objsym($sv)
6006 0 0 0     0 and $debug{hv};
      0        
6007 0 0       0 if ($is_stash) {
6008 0 0 0     0 if (ref($sv) eq "B::GV" and $sv->NAME =~ /::$/) {
6009 0         0 $sv = bless $sv, "B::STASHGV"; # do not expand stash GV's only other stashes
6010 0 0       0 warn "saving STASH $fullname".'{'.$key."}\n" if $debug{hv};
6011 0         0 $contents[$i] = $sv->save($fullname.'{'.$key.'}');
6012             } else {
6013 0 0       0 warn "skip STASH symbol *",$fullname.$key,"\n" if $debug{hv};
6014 0         0 $contents[$i] = undef;
6015 0         0 $length -= 2;
6016             # warn "(length=$length)\n" if $debug{hv};
6017             }
6018             } else {
6019 0 0       0 warn "saving HV \$".$fullname.'{'.$key."} $sv\n" if $debug{hv};
6020 0         0 $contents[$i] = $sv->save($fullname.'{'.$key.'}');
6021             #if ($key eq "" and $] >= 5.010) {
6022             # warn " turn off HvSHAREKEYS with empty keysv\n" if $debug{hv};
6023             # $init->add("HvSHAREKEYS_off(&sv_list[$sv_list_index]);");
6024             #}
6025             }
6026             }
6027 0 0       0 if ($length) { # there may be skipped STASH symbols
6028 0         0 $init->no_split;
6029 0 0       0 $init->add( "{",
6030             sprintf("\tHV *hv = %s%s;", $sym=~/^hv|\(HV/ ? '' : '(HV*)', $sym ));
6031 0         0 while (@contents) {
6032 0         0 my ( $key, $value ) = splice( @contents, 0, 2 );
6033 0 0       0 if ($value) {
6034 0 0 0     0 $value = "(SV*)$value" if $value !~ /^&sv_list/ or ($PERL510 and $] < 5.012);
      0        
6035 0         0 my ($cstring, $cur, $utf8) = strlen_flags($key);
6036             # issue 272: if SvIsCOW(sv) && SvLEN(sv) == 0 => sharedhek (key == "")
6037             # >= 5.10: SvSHARED_HASH: PV offset to hek_hash
6038 0 0       0 $cur = -$cur if $utf8;
6039 0         0 $init->add(sprintf( "\thv_store(hv, %s, %d, %s, 0);",
6040             $cstring, $cur, $value )); # !! randomized hash keys
6041 0 0       0 warn sprintf( " HV key \"%s\" = %s\n", $key, $value) if $debug{hv};
6042 0 0 0     0 if (!$swash_ToCf and $fullname =~ /^utf8::SWASHNEW/
      0        
      0        
6043             and $cstring eq '"utf8\034unicore/To/Cf.pl\0340"' and $cur == 23)
6044             {
6045 0         0 $swash_ToCf = $value;
6046 0 0       0 warn sprintf( "Found PL_utf8_tofold ToCf swash $value\n") if $verbose;
6047             }
6048             }
6049             }
6050 0         0 $init->add("}");
6051 0         0 $init->split;
6052 0 0       0 $init->add( sprintf("HvTOTALKEYS(%s) = %d;", $sym, $length / 2)) if !$PERL56;
6053             }
6054             } elsif ($PERL514) { # empty contents still needs to set keys=0
6055             # test 36, 140
6056 0         0 $init->add( "HvTOTALKEYS($sym) = 0;");
6057             }
6058 0         0 $magic = $hv->save_magic($fullname);
6059 0 0       0 $init->add( "SvREADONLY_on($sym);") if $hv->FLAGS & SVf_READONLY;
6060 0 0       0 if ($magic =~ /c/) {
6061             # defer AMT magic of XS loaded stashes
6062 0         0 my ($cname, $len, $utf8) = strlen_flags($name);
6063 0         0 $init2->add(qq[$sym = gv_stashpvn($cname, $len, GV_ADDWARN|GV_ADDMULTI|$utf8);]);
6064             }
6065 0 0 0     0 if ($PERL510 and $name and is_using_mro() and mro::get_mro($name) eq 'c3') {
      0        
      0        
6066 0         0 B::C::make_c3($name);
6067             }
6068 0         0 return $sym;
6069             }
6070              
6071             sub B::IO::save_data {
6072 0     0   0 my ( $io, $sym, $globname, @data ) = @_;
6073 0         0 my $data = join '', @data;
6074             # XXX using $DATA might clobber it!
6075 0         0 my $ref = svref_2object( \\$data )->save;
6076 0 0       0 $init->add("/* save $globname in RV ($ref) */") if $verbose;
6077 0         0 $init->add( "GvSVn( $sym ) = (SV*)$ref;");
6078              
6079 0 0       0 if ($PERL56) {
6080             # Pseudo FileHandle
6081 0         0 $init2->add_eval( sprintf 'open(%s, \'<\', $%s);', $globname, $globname );
6082             } else { # force inclusion of PerlIO::scalar as it was loaded in BEGIN.
6083 0         0 $init2->add_eval( sprintf 'open(%s, \'<:scalar\', $%s);', $globname, $globname );
6084             # => eval_pv("open(main::DATA, '<:scalar', $main::DATA);",1); DATA being a ref to $data
6085 0         0 $init->pre_destruct( sprintf 'eval_pv("close %s;", 1);', $globname );
6086 0         0 $use_xsloader = 1; # layers are not detected as XSUB CV, so force it
6087 0 0       0 require PerlIO unless $savINC{'PerlIO.pm'};
6088 0 0       0 require PerlIO::scalar unless $savINC{'PerlIO/scalar.pm'};
6089 0         0 mark_package("PerlIO", 1);
6090 0         0 $curINC{'PerlIO.pm'} = $INC{'PerlIO.pm'}; # as it was loaded from BEGIN
6091 0         0 mark_package("PerlIO::scalar", 1);
6092 0         0 $curINC{'PerlIO/scalar.pm'} = $INC{'PerlIO/scalar.pm'};
6093 0         0 $xsub{'PerlIO::scalar'} = 'Dynamic-'.$INC{'PerlIO/scalar.pm'}; # force dl_init boot
6094             }
6095             }
6096              
6097             sub B::IO::save {
6098 0     0   0 my ($io, $fullname, $is_DATA) = @_;
6099 0         0 my $sym = objsym($io);
6100 0 0       0 return $sym if defined $sym;
6101 0         0 my $pv = $io->PV;
6102 0 0       0 $pv = '' unless defined $pv;
6103 0         0 my ( $pvsym, $len, $cur );
6104 0 0       0 if ($pv) {
6105 0         0 $pvsym = savepv($pv);
6106 0         0 $cur = $io->CUR;
6107             } else {
6108 0         0 $pvsym = 'NULL';
6109 0         0 $cur = 0;
6110             }
6111 0 0       0 if ($cur) {
6112 0         0 $len = $cur + 1;
6113 0 0 0     0 $len++ if IsCOW($io) and !$B::C::cow;
6114             } else {
6115 0         0 $len = 0;
6116             }
6117             warn sprintf( "IO $fullname sv_list[%d] 0x%x (%s) = '%s'\n", $svsect->index+1, $$io, $io->SvTYPE, $pv )
6118 0 0 0     0 if $debug{sv} and $] > 5.008; # no method "SvTYPE" via package "B::IO"
6119 0 0       0 if ($PERL514) {
    0          
    0          
6120             # IFP in sv.sv_u.svu_fp
6121 0         0 $xpviosect->comment("STASH, xmg_u, cur, len, xiv_u, xio_ofp, xio_dirpu, page, page_len, ..., type, flags");
6122 0         0 my $tmpl = "Nullhv, /*STASH later*/\n\t{0}, /*MAGIC later*/\n\t%u, /*cur*/\n\t%u, /*len*/\n\t{%d}, /*LINES*/\n\t0, /*OFP later*/\n\t{0}, /*dirp_u later*/\n\t%d, /*PAGE*/\n\t%d, /*PAGE_LEN*/\n\t%d, /*LINES_LEFT*/\n\t%s, /*TOP_NAME*/\n\tNullgv, /*top_gv later*/\n\t%s, /*fmt_name*/\n\tNullgv, /*fmt_gv later*/\n\t%s, /*bottom_name*/\n\tNullgv, /*bottom_gv later*/\n\t%s, /*type*/\n\t0x%x /*flags*/";
6123 0 0       0 $tmpl =~ s{ /\*.+?\*/\n\t}{}g unless $verbose;
6124 0 0       0 $tmpl =~ s{ /\*flags\*/$}{} unless $verbose;
6125 0         0 $xpviosect->add(
6126             sprintf($tmpl,
6127             $cur, $len,
6128             $io->LINES, # moved to IVX with 5.11.1
6129             $io->PAGE, $io->PAGE_LEN,
6130             $io->LINES_LEFT, "NULL",
6131             "NULL", "NULL",
6132             cchar( $io->IoTYPE ), $io->IoFLAGS
6133             )
6134             );
6135 0 0       0 $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}",
6136             $xpviosect->index, $io->REFCNT, $io->FLAGS,
6137             $B::C::pv_copy_on_grow ? $pvsym : 0));
6138             }
6139             elsif ($] > 5.011000) {
6140 0         0 $xpviosect->comment("xnv_u, cur, len, lines, xmg_u, xmg_stash, xio_ifp, xio_ofp, xio_dirpu, ..., type, flags");
6141 0         0 my $tmpl = "{0}, /*xnv_u*/\n\t%u, /*cur*/\n\t%u, /*len*/\n\t{%d}, /*LINES*/\n\t{0}, /*MAGIC later*/\n\t(HV*)NULL, /*STASH later*/\n\t0, /*IFP later*/\n\t0, /*OFP later*/\n\t{0}, /*dirp_u later*/\n\t%d, /*PAGE*/\n\t%d, /*PAGE_LEN*/\n\t%d, /*LINES_LEFT*/\n\t%s, /*TOP_NAME*/\n\tNullgv, /*top_gv later*/\n\t%s, /*fmt_name*/\n\tNullgv, /*fmt_gv later*/\n\t%s, /*bottom_name*/\n\tNullgv, /*bottom_gv later*/\n\t%s, /*type*/\n\t0x%x /*flags*/";
6142 0 0       0 $tmpl =~ s{ /\*.+?\*/\n\t}{}g unless $verbose;
6143 0 0       0 $tmpl =~ s{ /\*flags\*/$}{} unless $verbose;
6144 0         0 $xpviosect->add(
6145             sprintf($tmpl,
6146             $cur, $len,
6147             $io->LINES, # moved to IVX with 5.11.1
6148             $io->PAGE, $io->PAGE_LEN,
6149             $io->LINES_LEFT, "NULL",
6150             "NULL", "NULL",
6151             cchar( $io->IoTYPE ), $io->IoFLAGS
6152             )
6153             );
6154 0 0       0 $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}",
6155             $xpviosect->index, $io->REFCNT, $io->FLAGS,
6156             $B::C::pv_copy_on_grow ? $pvsym : 0));
6157             }
6158             elsif ($PERL510) {
6159 0         0 $xpviosect->comment("xnv_u, cur, len, xiv_u, xmg_u, xmg_stash, xio_ifp, xio_ofp, xio_dirpu, lines, ..., type, flags");
6160 0         0 my $tmpl = "{0}, /*xnv_u*/\n\t%u, /*cur*/\n\t%u, /*len*/\n\t{%ld}, /*IVX*/\n\t{0}, /*MAGIC later*/\n\t(HV*)NULL, /*STASH later*/\n\t0, /*IFP later*/\n\t0, /*OFP later*/\n\t{0}, /*dirp_u later*/\n\t%d, /*LINES*/\n\t%d, /*PAGE*/\n\t%d, /*PAGE_LEN*/\n\t%d, /*LINES_LEFT*/\n\t%s, /*TOP_NAME*/\n\tNullgv, /*top_gv later*/\n\t%s, /*fmt_name*/\n\tNullgv, /*fmt_gv later*/\n\t%s, /*bottom_name*/\n\tNullgv, /*bottom_gv later*/\n\t%s, /*type*/\n\t0x%x /*flags*/";
6161 0 0       0 $tmpl =~ s{ /\*[^\*]+?\*/\n\t}{}g unless $verbose;
6162 0 0       0 $tmpl =~ s{ /\*flags\*/$}{} unless $verbose;
6163 0         0 $xpviosect->add(
6164             sprintf($tmpl,
6165             $cur, $len,
6166             $io->IVX,
6167             $io->LINES,
6168             $io->PAGE, $io->PAGE_LEN,
6169             $io->LINES_LEFT, "NULL",
6170             "NULL", "NULL",
6171             cchar( $io->IoTYPE ), $io->IoFLAGS
6172             )
6173             );
6174 0 0       0 $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}",
6175             $xpviosect->index, $io->REFCNT, $io->FLAGS,
6176             $B::C::pv_copy_on_grow ? $pvsym : 0));
6177             }
6178             else { # 5.6 and 5.8
6179 0         0 $xpviosect->comment("xpv_pv, cur, len, iv, nv, magic, stash, xio_ifp, xio_ofp, xio_dirpu, ..., subprocess, type, flags");
6180 0         0 $xpviosect->add(
6181             sprintf("%s, %u, %u, %ld, %s, 0, 0, 0, 0, {0}, %d, %d, %d, %d, %s, Nullgv, %s, Nullgv, %s, Nullgv, %d, %s, 0x%x",
6182             $pvsym, $cur, $len,
6183             $io->IVX, $io->NVX,
6184             $io->LINES, $io->PAGE,
6185             $io->PAGE_LEN, $io->LINES_LEFT,
6186             "NULL", "NULL",
6187             "NULL", $io->SUBPROCESS,
6188             cchar( $io->IoTYPE ), $io->IoFLAGS
6189             )
6190             );
6191 0         0 $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x",
6192             $xpviosect->index, $io->REFCNT, $io->FLAGS));
6193             }
6194 0 0       0 $svsect->debug($fullname, $io->flagspv) if $debug{flags};
6195 0         0 $sym = savesym( $io, sprintf( "(IO*)&sv_list[%d]", $svsect->index ) );
6196              
6197 0 0 0     0 if ($PERL510 and !$B::C::pv_copy_on_grow and $cur) {
      0        
6198 0         0 $init->add(sprintf("SvPVX(sv_list[%d]) = %s;", $svsect->index, $pvsym));
6199             }
6200 0         0 my ( $field );
6201 0         0 foreach $field (qw(TOP_GV FMT_GV BOTTOM_GV)) {
6202 0         0 my $fsym = $io->$field();
6203 0 0       0 if ($$fsym) {
6204 0         0 $init->add( sprintf( "Io%s(%s) = (GV*)s\\_%x;", $field, $sym, $$fsym ) );
6205 0         0 $fsym->save;
6206             }
6207             }
6208 0         0 foreach $field (qw(TOP_NAME FMT_NAME BOTTOM_NAME)) {
6209 0         0 my $fsym = $io->$field;
6210 0 0       0 $init->add(sprintf("Io%s(%s) = savepvn(%s, %u);", $field, $sym,
6211             cstring( $fsym ), length $fsym)) if $fsym;
6212             }
6213 0         0 $io->save_magic($fullname); # This handle the stash also (we need to inc the refcnt)
6214 0 0 0     0 if (!$PERL56 and !$is_DATA) { # PerlIO
6215             # deal with $x = *STDIN/STDOUT/STDERR{IO} and aliases
6216 0         0 my $perlio_func;
6217             # Note: all single-direction fp use IFP, just bi-directional pipes and
6218             # sockets use OFP also. But we need to set both, pp_print checks OFP.
6219 0         0 my $o = $io->object_2svref();
6220 0         0 eval "require ".ref($o).";";
6221 0         0 my $fd = $o->fileno();
6222             # use IO::Handle ();
6223             # my $fd = IO::Handle::fileno($o);
6224 0         0 my $i = 0;
6225 0         0 foreach (qw(stdin stdout stderr)) {
6226 0 0 0     0 if ($io->IsSTD($_) or (defined($fd) and $fd == -$i)) {
      0        
6227 0         0 $perlio_func = $_;
6228             }
6229 0         0 $i++;
6230             }
6231 0 0       0 if ($perlio_func) {
6232 0         0 $init->add("IoIFP(${sym}) = IoOFP(${sym}) = PerlIO_${perlio_func}();");
6233             #if ($fd < 0) { # fd=-1 signals an error
6234             # XXX print may fail at flush == EOF, wrong init-time?
6235             #}
6236             } else {
6237 0         0 my $iotype = $io->IoTYPE;
6238 0         0 my $ioflags = $io->IoFLAGS;
6239             # If an IO handle was opened at BEGIN, we try to re-init it, based on fd and IoTYPE.
6240             # IOTYPE:
6241             # - STDIN/OUT HANDLE IoIOFP alias
6242             # I STDIN/OUT/ERR HANDLE IoIOFP alias
6243             # < read-only HANDLE fdopen
6244             # > write-only HANDLE if fd<3 or IGNORE warn and comment
6245             # a append HANDLE -"-
6246             # + read and write HANDLE fdopen
6247             # s socket DIE
6248             # | pipe DIE
6249             # # NUMERIC HANDLE fdopen
6250             # space closed IGNORE
6251             # \0 ex/closed? IGNORE
6252 0 0 0     0 if ($iotype eq "\c@" or $iotype eq " ") {
    0          
    0          
6253             warn sprintf("Ignore closed IO Handle %s %s (%d)\n",
6254             cstring($iotype), $fullname, $ioflags)
6255 0 0       0 if $debug{gv};
6256             }
6257             elsif ($iotype =~ /[a>]/) { # write-only
6258 0 0 0     0 warn "Warning: Write BEGIN-block $fullname to FileHandle $iotype \&$fd\n"
6259             if $fd >= 3 or $verbose;
6260 0 0       0 my $mode = $iotype eq '>' ? 'w' : 'a';
6261             #$init->add( sprintf("IoIFP($sym) = IoOFP($sym) = PerlIO_openn(aTHX_ NULL,%s,%d,0,0,NULL,0,NULL);",
6262             # cstring($mode), $fd));
6263 0 0       0 $init->add(sprintf( "%sIoIFP(%s) = IoOFP(%s) = PerlIO_fdopen(%d, %s);%s",
    0          
6264             $fd<3?'':'/*', $sym, $sym, $fd, cstring($mode), $fd<3?'':'*/'));
6265             }
6266             elsif ($iotype =~ /[<#\+]/) {
6267             # skips warning if it's one of our PerlIO::scalar __DATA__ handles
6268 0 0 0     0 warn "Warning: Read BEGIN-block $fullname from FileHandle $iotype \&$fd\n"
6269             if $fd >= 3 or $verbose; # need to setup it up before
6270 0         0 $init->add("/* XXX WARNING: Read BEGIN-block $fullname from FileHandle */",
6271             "IoIFP($sym) = IoOFP($sym) = PerlIO_fdopen($fd, \"r\");");
6272 0         0 my $tell;
6273 0 0 0     0 if ($io->can("tell") and $tell = $io->tell()) {
6274 0         0 $init->add("PerlIO_seek(IoIFP($sym), $tell, SEEK_SET);")
6275             }
6276             } else {
6277             # XXX We should really die here
6278 0         0 warn sprintf("ERROR: Unhandled BEGIN-block IO Handle %s\&%d (%d) from %s\n",
6279             cstring($iotype), $fd, $ioflags, $fullname);
6280 0         0 $init->add("/* XXX WARNING: Unhandled BEGIN-block IO Handle ",
6281             "IoTYPE=$iotype SYMBOL=$fullname, IoFLAGS=$ioflags */",
6282             "IoIFP($sym) = IoOFP($sym) = PerlIO_fdopen($fd, \"$iotype\");");
6283             }
6284             }
6285             }
6286              
6287 0 0       0 if ( $PERL518 ) {
6288 0         0 my $stash = $io->SvSTASH;
6289 0 0 0     0 if ($stash and $$stash) {
6290 0         0 my $stsym = $stash->save("%".$stash->NAME);
6291 0         0 $init->add(
6292             sprintf( "SvREFCNT(%s) += 1;", $stsym ),
6293             sprintf( "SvSTASH_set(%s, %s);", $sym, $stsym )
6294             );
6295             warn sprintf( "done saving STASH %s %s for IO %s\n", $stash->NAME, $stsym, $sym )
6296 0 0       0 if $debug{gv};
6297             }
6298             }
6299              
6300 0         0 return $sym;
6301             }
6302              
6303             sub B::SV::save {
6304 0     0   0 my $sv = shift;
6305              
6306             # This is where we catch an honest-to-goodness Nullsv (which gets
6307             # blessed into B::SV explicitly) and any stray erroneous SVs.
6308 0 0       0 return 0 unless $$sv;
6309 0         0 warn sprintf( "cannot save that type of SV: %s (0x%x)\n", B::class($sv), $$sv );
6310             }
6311              
6312             sub output_all {
6313 0     0 0 0 my $init_name = shift;
6314 0         0 my $section;
6315 0 0       0 return if $check;
6316              
6317 0         0 my @sections =
6318             (
6319             $copsect, $opsect, $unopsect, $binopsect, $logopsect, $condopsect,
6320             $listopsect, $pmopsect, $svopsect, $padopsect, $pvopsect, $loopsect,
6321             $methopsect, $unopauxsect,
6322             $xpvsect, $xpvavsect, $xpvhvsect, $xpvcvsect, $padlistsect,
6323             $padnlsect, $xpvivsect, $xpvuvsect, $xpvnvsect, $xpvmgsect, $xpvlvsect,
6324             $xrvsect, $xpvbmsect, $xpviosect, $svsect, $padnamesect,
6325             );
6326 0 0       0 if ($PERL522) {
6327 0         0 pop @sections;
6328 0         0 for my $n (sort keys %padnamesect) {
6329 0         0 push @sections, $padnamesect{$n};
6330             }
6331             }
6332 0 0       0 if ($CPERL52) {
6333 0         0 for my $n (sort keys %avcowsect) {
6334 0         0 push @sections, $avcowsect{$n};
6335             }
6336 0         0 for my $n (sort keys %avcogsect) {
6337 0         0 push @sections, $avcogsect{$n};
6338             }
6339             }
6340 0 0 0     0 printf "\t/* %s */", $symsect->comment if $symsect->comment and $verbose;
6341 0         0 $symsect->output( \*STDOUT, "#define %s\n" );
6342 0         0 print "\n";
6343 0         0 output_declarations();
6344             # XXX add debug versions with ix=opindex if $debug{flags}
6345 0         0 foreach $section (@sections) {
6346 0         0 my $lines = $section->index + 1;
6347 0 0       0 if ($lines) {
6348 0         0 my $name = $section->name;
6349 0         0 my $typename = $section->typename;
6350             # static SV** arrays for AvSTATIC, HvSTATIC, ...
6351 0 0 0     0 if ($typename eq 'SV*' and $name =~ /^(?:avco[gw])_(\d+)$/) {
6352 0         0 my $n = $1;
6353 0 0       0 $typename = 'const SV*' if $name =~ /^avcow_/;
6354 0         0 print "Static $typename ${name}_list[$lines][$n];\n";
6355             } else {
6356 0         0 print "Static $typename ${name}_list[$lines];\n";
6357             }
6358             }
6359             }
6360              
6361             # hack for when Perl accesses PVX of GVs
6362 0         0 print 'Static const char emptystring[] = "\0";',"\n";
6363             # newXS for core XS needs a filename
6364 0         0 print 'Static const char xsfile[] = "universal.c";',"\n";
6365 0 0       0 if ($MULTI) {
6366 0         0 print "#define ptr_undef 0\n";
6367             } else {
6368 0 0       0 if ($] > 5.01903) {
6369 0         0 print "#define ptr_undef NULL\n";
6370             } else {
6371 0         0 print "#define ptr_undef &PL_sv_undef\n";
6372             }
6373 0 0       0 if ($PERL510) { # XXX const sv SIGSEGV
6374 0         0 print "#undef CopFILE_set\n";
6375 0         0 print "#define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv))\n";
6376             }
6377             }
6378             # print "#define MyPVX(sv) ".($] < 5.010 ? "SvPVX(sv)" : "((sv)->sv_u.svu_pv)")."\n";
6379 0 0       0 if ($] < 5.008008 ) {
6380 0         0 print <<'EOT';
6381             #ifndef SvSTASH_set
6382             # define SvSTASH_set(sv,hv) SvSTASH((sv)) = (hv)
6383             #endif
6384             #ifndef Newxz
6385             # define Newxz(v,n,t) Newz(0,v,n,t)
6386             #endif
6387             EOT
6388             }
6389 0 0       0 if ($] < 5.008009 ) {
6390 0         0 print <<'EOT';
6391             #ifndef SvREFCNT_inc_simple_NN
6392             # define SvREFCNT_inc_simple_NN(sv) (++SvREFCNT(sv), (SV*)(sv))
6393             #endif
6394             #ifndef STR_WITH_LEN
6395             #define STR_WITH_LEN(s) ("" s ""), (sizeof(s)-1)
6396             #endif
6397             EOT
6398             }
6399 0 0       0 if ($] < 5.013007 ) {
6400 0         0 print <<'EOT';
6401             #ifndef CvSTASH_set
6402             # define CvSTASH_set(cv,hv) CvSTASH((cv)) = (hv)
6403             #endif
6404             EOT
6405             }
6406 0 0       0 if ($] < 5.013010 ) { # added with c43ae56ff9cd before 5.13.10 at 2011-01-21
6407 0         0 print <<'EOT';
6408             #ifndef GvCV_set
6409             # define GvCV_set(gv,cv) (GvCV(gv) = (cv))
6410             #endif
6411             #ifndef GvGP_set
6412             # define GvGP_set(gv,gp) (GvGP(gv) = (gp))
6413             #endif
6414             EOT
6415             }
6416 0 0 0     0 if ($] >= 5.021005 and $] < 5.023) {
6417 0         0 print <<'EOT';
6418             /* PadlistNAMES broken as lvalue with v5.21.6-197-g0f94cb1,
6419             fixed with 5.22.1 and 5.23.0 */
6420             #if (PERL_VERSION == 22) || ( PERL_VERSION == 21 && PERL_SUBVERSION > 5)
6421             # undef PadlistNAMES
6422             # define PadlistNAMES(pl) *((PADNAMELIST **)PadlistARRAY(pl))
6423             #endif
6424             EOT
6425             }
6426             # handy accessors only in cperl for now:
6427 0         0 print <<'EOT';
6428             #ifndef get_svs
6429             # define get_svs(str, flags) get_sv((str), (flags))
6430             # define get_avs(str, flags) get_av((str), (flags))
6431             # define get_hvs(str, flags) get_hv((str), (flags))
6432             #endif
6433             EOT
6434 0 0 0     0 if (%init2_remap and !$HAVE_DLFCN_DLOPEN) {
6435 0         0 print <<'EOT';
6436             XS(XS_DynaLoader_dl_load_file);
6437             XS(XS_DynaLoader_dl_find_symbol);
6438             EOT
6439             }
6440 0 0 0     0 printf "\t/* %s */\n", $decl->comment if $decl->comment and $verbose;
6441 0         0 $decl->output( \*STDOUT, "%s\n" );
6442 0         0 print "\n";
6443              
6444 0         0 foreach $section (@sections) {
6445 0         0 my $lines = $section->index + 1;
6446 0 0       0 if ($lines) {
6447 0         0 my $name = $section->name;
6448 0         0 my $typename = $section->typename;
6449             # static SV** arrays for AvSTATIC, HvSTATIC, ...
6450 0 0 0     0 if ($typename eq 'SV*' and $name =~ /^(?:avco[wg])_(\d+)$/) {
6451 0         0 my $n = $1;
6452 0 0       0 $typename = 'const SV*' if $name =~ /^avcow_/;
6453 0         0 printf "Static %s %s_list[%u][%u] = {\n", $typename, $name, $lines, $n;
6454             } else {
6455 0         0 printf "Static %s %s_list[%u] = {\n", $typename, $name, $lines;
6456             }
6457 0 0 0     0 printf "\t/* %s */\n", $section->comment
6458             if $section->comment and $verbose;
6459 0         0 $section->output( \*STDOUT, "\t{ %s }, /* %s_list[%d] %s */%s\n" );
6460 0         0 print "};\n\n";
6461             }
6462             }
6463              
6464 0         0 fixup_ppaddr();
6465 0         0 print "static void perl_init0(pTHX) /* fixup_ppaddr */\n{\n\t";
6466 0 0       0 print "register int i;\n" if @{ $init0->[-1]{values} };
  0         0  
6467 0         0 $init0->output( \*STDOUT, "\t%s\n" );
6468 0         0 print "};\n\n";
6469              
6470 0 0 0     0 printf "\t/* %s */\n", $init->comment if $init->comment and $verbose;
6471 0         0 $init->output( \*STDOUT, "\t%s\n", $init_name );
6472 0 0       0 printf "/* deferred init1 of regexp */\n" if $verbose;
6473 0 0 0     0 printf "/* %s */\n", $init1->comment if $init1->comment and $verbose;
6474 0         0 $init1->output( \*STDOUT, "\t%s\n", 'perl_init1' );
6475 0         0 my $init2_name = 'perl_init2';
6476 0 0       0 printf "/* deferred init of XS/Dyna loaded modules */\n" if $verbose;
6477 0 0 0     0 printf "/* %s */\n", $init2->comment if $init2->comment and $verbose;
6478 0         0 my $remap = 0;
6479 0         0 for my $pkg (sort keys %init2_remap) {
6480 0 0       0 if (exists $xsub{$pkg}) { # check if not removed in between
6481 0         0 my ($stashfile) = $xsub{$pkg} =~ /^Dynamic-(.+)$/;
6482             # get so file from pm. Note: could switch prefix from vendor/site//
6483 0         0 $init2_remap{$pkg}{FILE} = dl_module_to_sofile($pkg, $stashfile);
6484 0         0 $remap++;
6485             }
6486             }
6487 0 0       0 if ($remap) {
6488             # XXX now emit arch-specific dlsym code
6489 0         0 $init2->no_split;
6490 0         0 $init2->add("{");
6491 0 0       0 if ($HAVE_DLFCN_DLOPEN) {
6492 0         0 $init2->add(" #include ");
6493 0         0 $init2->add(" void *handle;");
6494             } else {
6495 0         0 $init2->add(" void *handle;");
6496 0         0 $init2->add(" dTARG; dSP;",
6497             " targ=sv_newmortal();");
6498             }
6499 0         0 for my $pkg (sort keys %init2_remap) {
6500 0 0       0 if (exists $xsub{$pkg}) {
6501 0 0       0 if ($HAVE_DLFCN_DLOPEN) {
6502 0         0 my $ldopt = 'RTLD_NOW|RTLD_NOLOAD';
6503 0 0       0 $ldopt = 'RTLD_NOW' if $^O =~ /bsd/i; # 351 (only on solaris and linux, not any bsd)
6504 0         0 $init2->add( "", sprintf(" handle = dlopen(%s, %s);", cstring($init2_remap{$pkg}{FILE}), $ldopt));
6505             }
6506             else {
6507             $init2->add(" PUSHMARK(SP);",
6508 0         0 sprintf(" XPUSHs(newSVpvs(%s));", cstring($init2_remap{$pkg}{FILE})),
6509             " PUTBACK;",
6510             " XS_DynaLoader_dl_load_file(aTHX_ NULL);",
6511             " SPAGAIN;",
6512             " handle = INT2PTR(void*,POPi);",
6513             " PUTBACK;",
6514             );
6515             }
6516 0         0 for my $mg (@{$init2_remap{$pkg}{MG}}) {
  0         0  
6517 0 0       0 warn "init2 remap xpvmg_list[$mg->{ID}].xiv_iv to dlsym of $pkg\: $mg->{NAME}\n"
6518             if $verbose;
6519 0 0       0 if ($HAVE_DLFCN_DLOPEN) {
6520             $init2->add(sprintf(" xpvmg_list[%d].xiv_iv = PTR2IV( dlsym(handle, %s) );",
6521 0         0 $mg->{ID}, cstring($mg->{NAME})));
6522             } else {
6523             $init2->add(" PUSHMARK(SP);",
6524             " XPUSHi(PTR2IV(handle));",
6525             sprintf(" XPUSHs(newSVpvs(%s));", cstring($mg->{NAME})),
6526             " PUTBACK;",
6527             " XS_DynaLoader_dl_find_symbol(aTHX_ NULL);",
6528             " SPAGAIN;",
6529 0         0 sprintf(" xpvmg_list[%d].xiv_iv = POPi;", $mg->{ID}),
6530             " PUTBACK;",
6531             );
6532             }
6533             }
6534             }
6535             }
6536 0         0 $init2->add("}");
6537 0         0 $init2->split;
6538             }
6539 0         0 $init2->output( \*STDOUT, "\t%s\n", $init2_name );
6540 0 0       0 if ($verbose) {
6541 0         0 my $caller = caller;
6542 0 0       0 warn $caller eq 'B::CC' ? B::CC::compile_stats() : compile_stats();
6543 0         0 warn "NULLOP count: $nullop_count\n";
6544             }
6545             }
6546              
6547             sub output_declarations {
6548 0     0 0 0 print <<'EOT';
6549             #define UNUSED 0
6550             #define sym_0 0
6551              
6552             static void
6553             my_mg_RC_off(pTHX_ SV* sv, int type) {
6554             MAGIC *mg;
6555             for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
6556             if (mg->mg_type == type && (mg->mg_flags | MGf_REFCOUNTED))
6557             mg->mg_flags &= ~MGf_REFCOUNTED;
6558             }
6559             }
6560              
6561             EOT
6562 0 0 0     0 if ($PERL510 and IS_MSVC) {
6563             # initializing char * differs in levels of indirection from int
6564 0         0 print "#pragma warning( disable : 4047 )\n";
6565             # targ: unreferenced local variable
6566 0         0 print "#pragma warning( disable : 4101 )\n";
6567             }
6568              
6569             # Need fresh re-hash of strtab. share_hek does not allow hash = 0
6570 0 0       0 if ( $PERL510 ) {
6571 0         0 print <<'_EOT0';
6572             PERL_STATIC_INLINE HEK *
6573             my_share_hek( pTHX_ const char *str, I32 len );
6574             #undef share_hek
6575             #define share_hek(str, len) my_share_hek( aTHX_ str, len );
6576              
6577             PERL_STATIC_INLINE HEK *
6578             my_share_hek_0( pTHX_ const char *str, I32 len);
6579              
6580             #define HEK_HE(hek) \
6581             ((struct shared_he *)(((char *)(hek)) \
6582             - STRUCT_OFFSET(struct shared_he, \
6583             shared_he_hek)))
6584             #define HEK_shared_he(hek) \
6585             ((struct shared_he *)(((char *)(hek)) \
6586             - STRUCT_OFFSET(struct shared_he, \
6587             shared_he_hek))) \
6588             ->shared_he_he
6589              
6590             #define hek_hek_refcount(hek) \
6591             HEK_shared_he(hek).he_valu.hent_refcount
6592              
6593             #define unshare_hek_hek(hek) --(hek_hek_refcount(hek))
6594              
6595             _EOT0
6596              
6597             }
6598 0 0       0 if ($PERL522) {
6599 0         0 print <<'EOF';
6600             /* unfortunately we have to override this perl5.22 struct.
6601             The Padname string buffer in xpadn_str is pointed by xpadn_pv.
6602             */
6603             #define _PADNAME_BASE \
6604             char * xpadn_pv; \
6605             HV * xpadn_ourstash; \
6606             union { \
6607             HV * xpadn_typestash; \
6608             CV * xpadn_protocv; \
6609             } xpadn_type_u; \
6610             U32 xpadn_low; \
6611             U32 xpadn_high; \
6612             U32 xpadn_refcnt; \
6613             int xpadn_gen; \
6614             U8 xpadn_len; \
6615             U8 xpadn_flags
6616              
6617             #ifdef PERL_PADNAME_MINIMAL
6618             #define MY_PADNAME_BASE _PADNAME_BASE
6619             #else
6620             #define MY_PADNAME_BASE struct padname xpadn_padname
6621             #endif
6622              
6623             EOF
6624              
6625 0         0 for my $s (sort keys %padnamesect) {
6626 0 0       0 if ($padnamesect{$s}->index >= 0) {
6627 0         0 print <<"EOF";
6628             struct my_padname_with_str_$s {
6629             MY_PADNAME_BASE;
6630             char xpadn_str[$s];
6631             };
6632             typedef struct my_padname_with_str_$s PADNAME_$s;
6633             EOF
6634             }
6635             }
6636             #} elsif ($PERL518) {
6637             # print "typedef PADNAME MyPADNAME;\n";
6638             }
6639 0 0 0     0 if ($PERL510 and !$PERL514) {
6640 0         0 print "typedef struct refcounted_he COPHH;\n";
6641 0         0 print <<'EOF';
6642             #define cophh_store_pvn(cophh, keypv, keylen, hash, value, flags) \
6643             Perl_refcounted_he_new(aTHX_ cophh, newSVpvn_flags(keypv, keylen, flags), value)
6644             #define cophh_store_pvs(cophh, key, value, flags) \
6645             Perl_refcounted_he_new(aTHX_ cophh, Perl_newSVpvn_flags(aTHX_ STR_WITH_LEN(key), SVs_TEMP), value)
6646             #define CopHINTHASH_set(c,h) ((c)->cop_hints_hash = (h))
6647             EOF
6648             }
6649 0 0       0 if ($B::C::Config::have_HEK_STATIC) {
6650 0         0 print "/* store full char[] to avoid excess elements in array\n";
6651 0         0 print " (HEK only declared as char[1]) */\n";
6652 0         0 print "struct hek_ptr { U32 hek_hash; I32 hek_len; char hek_key[]; };\n";
6653             }
6654             # Tricky hack for -fcog since 5.10 on !c99 compilers required. We need a char* as
6655             # *first* sv_u element to be able to statically initialize it. A int does not allow it.
6656             # gcc error: initializer element is not computable at load time
6657             # We introduce a SVPV as SV.
6658             # In core since 5.12
6659 0 0 0     0 if ($PERL510 and $] < 5.012 and !$C99) {
      0        
6660 0         0 print <<'EOT0';
6661             typedef struct svpv {
6662             void * sv_any;
6663             U32 sv_refcnt;
6664             U32 sv_flags;
6665             union {
6666             char* svu_pv;
6667             IV svu_iv;
6668             UV svu_uv;
6669             SV* svu_rv;
6670             SV** svu_array;
6671             HE** svu_hash;
6672             GP* svu_gp;
6673             } sv_u;
6674             #ifdef DEBUG_LEAKING_SCALARS
6675             PERL_BITFIELD32 sv_debug_optype:9;
6676             PERL_BITFIELD32 sv_debug_inpad:1;
6677             PERL_BITFIELD32 sv_debug_cloned:1;
6678             PERL_BITFIELD32 sv_debug_line:16;
6679             # if PERL_VERSION < 11
6680             U32 sv_debug_serial; /* 5.10 only */
6681             # endif
6682             # if PERL_VERSION > 8
6683             char * sv_debug_file;
6684             # endif
6685             #endif
6686             } SVPV;
6687             EOT0
6688              
6689             }
6690 0 0       0 if ($PERL512) {
    0          
6691 0         0 print "typedef struct p5rx RE;\n";
6692             }
6693             elsif ($PERL510) {
6694 0         0 print "typedef SV * RE;\n";
6695             }
6696             else {
6697 0         0 print "typedef char * RE;\n";
6698             }
6699 0 0       0 if ($] == 5.010000) {
6700 0         0 print "#ifndef RX_EXTFLAGS\n";
6701 0         0 print "# define RX_EXTFLAGS(rx) ((rx)->extflags)\n";
6702 0         0 print "#endif\n";
6703             }
6704 0 0 0     0 if ($] >= 5.021001 and !$CPERL52) {
6705 0         0 print "Static IV PL_sv_objcount = 0; /* deprecated with 5.21.1 but still needed and used */\n";
6706             }
6707 0         0 print "SV* sv;\n";
6708 0 0       0 print "Static GV *gv_list[$gv_index];\n" if $gv_index;
6709             }
6710              
6711             sub output_boilerplate {
6712 0     0 0 0 my $creator = "created at ".scalar localtime()." with B::C $B::C::VERSION ";
6713 0 0       0 $creator .= $B::C::REVISION if $B::C::REVISION;
6714 0         0 $creator .= " for $^X";
6715 0         0 print "/* $creator */\n";
6716             # Store the sv_list index in sv_debug_file when debugging
6717 0 0 0     0 print "#define DEBUG_LEAKING_SCALARS 1\n" if $debug{flags} and $DEBUG_LEAKING_SCALARS;
6718 0 0       0 if ($B::C::Config::have_independent_comalloc) {
6719 0         0 print <<'_EOT1';
6720             #ifdef NEED_MALLOC_283
6721             # include "malloc-2.8.3.h"
6722             #endif
6723             _EOT1
6724              
6725             }
6726 0         0 print <<'_EOT2';
6727             #define PERL_CORE
6728             #include "EXTERN.h"
6729             #include "perl.h"
6730             #include "XSUB.h"
6731              
6732             /* Workaround for mapstart: the only op which needs a different ppaddr */
6733             #undef Perl_pp_mapstart
6734             #define Perl_pp_mapstart Perl_pp_grepstart
6735             #undef OP_MAPSTART
6736             #define OP_MAPSTART OP_GREPSTART
6737              
6738             #ifdef BROKEN_STATIC_REDECL
6739             #define Static extern
6740             #else
6741             #define Static static
6742             #endif /* BROKEN_STATIC_REDECL */
6743              
6744             #ifdef BROKEN_UNION_INIT
6745             #error BROKEN_UNION_INIT no longer needed, as Perl requires an ANSI compiler
6746             #endif
6747              
6748             /* No longer available when C is defined. */
6749             #ifndef Nullsv
6750             # define Null(type) ((type)NULL)
6751             # define Nullsv Null(SV*)
6752             # define Nullhv Null(HV*)
6753             # define Nullgv Null(GV*)
6754             # define Nullop Null(OP*)
6755             #endif
6756             #ifndef GV_NOTQUAL
6757             # define GV_NOTQUAL 0
6758             #endif
6759             /* Since 5.8.8 */
6760             #ifndef Newx
6761             # define Newx(v,n,t) New(0,v,n,t)
6762             #endif
6763             /* Since 5.14 */
6764             #if !defined(PERL_STATIC_INLINE)
6765             # ifdef HAS_STATIC_INLINE
6766             # define PERL_STATIC_INLINE static inline
6767             # else
6768             # define PERL_STATIC_INLINE static
6769             # endif
6770             #endif
6771             /* cperl compat */
6772             #ifndef HEK_STATIC
6773             # define HEK_STATIC(hek) 0
6774             #endif
6775              
6776             _EOT2
6777              
6778 0 0       0 if ($] < 5.008008) {
6779 0         0 print "#define GvSVn(s) GvSV(s)\n";
6780             }
6781              
6782             # XXX boot_DynaLoader is exported only >=5.8.9
6783             # does not compile on darwin with EXTERN_C declaration
6784             # See branch `boot_DynaLoader`
6785 0         0 print <<'_EOT4';
6786              
6787             #define XS_DynaLoader_boot_DynaLoader boot_DynaLoader
6788             EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
6789              
6790             static void xs_init (pTHX);
6791             static void dl_init (pTHX);
6792             _EOT4
6793              
6794 0 0 0     0 print <<'_EOT' if $CPERL51 and $^O ne 'MSWin32';
6795             EXTERN_C void dl_boot (pTHX);
6796             _EOT
6797              
6798 0 0 0     0 if ($B::C::av_init2 and $B::C::Config::use_declare_independent_comalloc) {
6799 0         0 print "void** dlindependent_comalloc(size_t, size_t*, void**);\n";
6800             }
6801 0 0       0 if ($B::C::av_init2) {
6802 0         0 my $last = $xpvavsect->index;
6803 0         0 my $size = $last + 1;
6804 0 0       0 if ($last) {
6805 0         0 $decl->add("Static void* avchunks[$size];");
6806 0         0 $decl->add("Static size_t avsizes[$size] = ");
6807 0         0 my $ptrsize = $Config{ptrsize};
6808 0         0 my $acc = "";
6809 0         0 for (0..$last) {
6810 0 0       0 if ($xpvav_sizes[$_] > 0) {
6811 0         0 $acc .= $xpvav_sizes[$_] * $ptrsize;
6812             } else {
6813 0         0 $acc .= 3 * $ptrsize;
6814             }
6815 0 0       0 $acc .= "," if $_ != $last;
6816 0 0       0 $acc .= "\n\t" unless ($_+1) % 30;
6817             }
6818 0         0 $decl->add("\t{$acc};");
6819 0         0 $init->add_initav("if (!independent_comalloc( $size, avsizes, avchunks ))");
6820 0         0 $init->add_initav(" Perl_die(aTHX_ \"panic: AV alloc failed\");");
6821             }
6822             }
6823 0 0       0 if ( !$B::C::destruct ) {
6824 0         0 print <<'_EOT4';
6825             static int fast_perl_destruct( PerlInterpreter *my_perl );
6826             static void my_curse( pTHX_ SV* const sv );
6827              
6828             #ifndef dVAR
6829             # ifdef PERL_GLOBAL_STRUCT
6830             # define dVAR pVAR = (struct perl_vars*)PERL_GET_VARS()
6831             # else
6832             # define dVAR dNOOP
6833             # endif
6834             #endif
6835             _EOT4
6836              
6837             } else {
6838 0         0 print <<'_EOT5';
6839             int my_perl_destruct( PerlInterpreter *my_perl );
6840             _EOT5
6841              
6842             }
6843 0 0       0 if ($] < 5.008009) {
6844 0         0 print <<'_EOT3';
6845             #ifndef savesharedpvn
6846             char *savesharedpvn(const char *const s, const STRLEN len);
6847             #endif
6848             _EOT3
6849              
6850             }
6851             }
6852              
6853             sub init_op_addr {
6854 0     0 0 0 my ( $op_type, $num ) = @_;
6855 0         0 my $op_list = $op_type . "_list";
6856              
6857 0         0 $init0->add( split /\n/, <<_EOT6 );
6858             for (i = 0; i < ${num}; ++i) {
6859             ${op_list}\[i].op_ppaddr = PL_ppaddr[PTR2IV(${op_list}\[i].op_ppaddr)];
6860             }
6861             _EOT6
6862              
6863             }
6864              
6865             sub output_main_rest {
6866              
6867 0 0   0 0 0 if ( $PERL510 ) {
6868 0         0 print <<'_EOT7';
6869             /* The first assignment got already refcount bumped */
6870             PERL_STATIC_INLINE HEK *
6871             my_share_hek( pTHX_ const char *str, I32 len) {
6872             U32 hash;
6873             PERL_HASH(hash, str, abs(len));
6874             return share_hek_hek(Perl_share_hek(aTHX_ str, len, hash));
6875             }
6876              
6877             _EOT7
6878             }
6879 0 0       0 if ( $PERL510 ) {
6880 0         0 print <<'_EOT7';
6881             PERL_STATIC_INLINE HEK *
6882             my_share_hek_0( pTHX_ const char *str, I32 len) {
6883             U32 hash;
6884             PERL_HASH(hash, str, abs(len));
6885             return Perl_share_hek(aTHX_ str, len, hash);
6886             }
6887              
6888             _EOT7
6889             }
6890              
6891 0 0       0 if ($] < 5.008009) {
6892 0         0 print <<'_EOT7a';
6893             #ifndef savesharedpvn
6894             char *savesharedpvn(const char *const s, const STRLEN len) {
6895             char *const d = (char*)PerlMemShared_malloc(len + 1);
6896             if (!d) { exit(1); }
6897             d[len] = '\0';
6898             return (char *)memcpy(d, s, len);
6899             }
6900             #endif
6901             _EOT7a
6902              
6903             }
6904             # -fno-destruct only >=5.8
6905 0 0       0 if ( !$B::C::destruct ) {
6906 0         0 print <<'_EOT8';
6907              
6908             #ifndef SvDESTROYABLE
6909             #define SvDESTROYABLE(sv) 1
6910             #endif
6911             /* 5.8 */
6912             #ifndef CvISXSUB
6913             #define CvISXSUB(sv) CvXSUB(sv)
6914             #endif
6915             #ifndef SvRV_set
6916             #define SvRV_set(a,b) SvRV(a) = (b)
6917             #endif
6918             /* 5.6 */
6919             #ifndef PERL_EXIT_DESTRUCT_END
6920             #define PERL_EXIT_DESTRUCT_END 2
6921             #endif
6922              
6923             static void
6924             my_curse( pTHX_ SV* const sv ) {
6925             dSP;
6926             dVAR;
6927             HV* stash;
6928              
6929             #if PERL_VERSION > 7
6930             assert(SvOBJECT(sv));
6931             do {
6932             stash = SvSTASH(sv);
6933             assert(SvTYPE(stash) == SVt_PVHV);
6934             if (HvNAME(stash)) {
6935             CV* destructor = NULL;
6936             if (!SvOBJECT(stash)) destructor = (CV *)SvSTASH(stash);
6937             if (!destructor
6938             #if (PERL_VERSION > 18) || (PERL_VERSION == 18 && PERL_SUBVERSION > 1)
6939             || HvMROMETA(stash)->destroy_gen != PL_sub_generation
6940             #endif
6941             ) {
6942             GV * const gv = gv_fetchmeth_autoload(stash, "DESTROY", 7, 0);
6943             if (gv) {
6944             destructor = GvCV(gv);
6945             if (!SvOBJECT(stash)) {
6946             SvSTASH(stash) =
6947             destructor ? (HV *)destructor : ((HV *)0)+1;
6948             #if (PERL_VERSION > 18) || (PERL_VERSION == 18 && PERL_SUBVERSION > 1)
6949             HvAUX(stash)->xhv_mro_meta->destroy_gen = PL_sub_generation;
6950             #endif
6951             }
6952             }
6953             }
6954             assert(!destructor || destructor == ((CV *)0)+1
6955             || SvTYPE(destructor) == SVt_PVCV);
6956             if (destructor && destructor != ((CV *)0)+1
6957             /* A constant subroutine can have no side effects, so
6958             don't bother calling it. */
6959             && !CvCONST(destructor)
6960             /* Don't bother calling an empty destructor or one that
6961             returns immediately. */
6962             && (CvISXSUB(destructor)
6963             || (CvSTART(destructor)
6964             && (CvSTART(destructor)->op_next->op_type != OP_LEAVESUB)
6965             && (CvSTART(destructor)->op_next->op_type != OP_PUSHMARK
6966             || CvSTART(destructor)->op_next->op_next->op_type != OP_RETURN
6967             )
6968             ))
6969             )
6970             {
6971             SV* const tmpref = newRV(sv);
6972             DEBUG_D(PerlIO_printf(Perl_debug_log, "Calling %s::DESTROY\n", HvNAME(stash)));
6973             SvREADONLY_on(tmpref); /* DESTROY() could be naughty */
6974             ENTER;
6975             PUSHSTACKi(PERLSI_DESTROY);
6976             EXTEND(SP, 2);
6977             PUSHMARK(SP);
6978             PUSHs(tmpref);
6979             PUTBACK;
6980             call_sv((SV*)destructor, G_DISCARD|G_EVAL|G_KEEPERR|G_VOID);
6981             POPSTACK;
6982             SPAGAIN;
6983             LEAVE;
6984             if(SvREFCNT(tmpref) < 2) {
6985             /* tmpref is not kept alive! */
6986             SvREFCNT(sv)--;
6987             SvRV_set(tmpref, NULL);
6988             SvROK_off(tmpref);
6989             }
6990             SvREFCNT_dec(tmpref);
6991             }
6992             }
6993             } while (SvOBJECT(sv) && SvSTASH(sv) != stash);
6994              
6995             if (SvOBJECT(sv)) {
6996             /* Curse before freeing the stash, as freeing the stash could cause
6997             a recursive call into S_curse. */
6998             SvOBJECT_off(sv); /* Curse the object. */
6999             SvSTASH_set(sv,0); /* SvREFCNT_dec may try to read this */
7000             }
7001             #endif
7002             }
7003              
7004             static int fast_perl_destruct( PerlInterpreter *my_perl ) {
7005             dVAR;
7006             VOL signed char destruct_level; /* see possible values in intrpvar.h */
7007             HV *hv;
7008             #ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
7009             pid_t child;
7010             #endif
7011              
7012             #ifndef MULTIPLICITY
7013             # ifndef PERL_UNUSED_ARG
7014             # define PERL_UNUSED_ARG(x) ((void)x)
7015             # endif
7016             PERL_UNUSED_ARG(my_perl);
7017             #endif
7018              
7019             assert(PL_scopestack_ix == 1);
7020              
7021             /* wait for all pseudo-forked children to finish */
7022             #if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7023             PERL_WAIT_FOR_CHILDREN;
7024             #endif
7025              
7026             destruct_level = PL_perl_destruct_level;
7027             #ifdef DEBUGGING
7028             {
7029             const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
7030             if (s) {
7031             const int i = atoi(s);
7032             #ifdef DEBUGGING
7033             if (destruct_level < i) destruct_level = i;
7034             #endif
7035             #ifdef PERL_TRACK_MEMPOOL
7036             /* RT #114496, for perl_free */
7037             PL_perl_destruct_level = i;
7038             #endif
7039             }
7040             }
7041             #endif
7042              
7043             if (PL_exit_flags & PERL_EXIT_DESTRUCT_END) {
7044             dJMPENV;
7045             int x = 0;
7046              
7047             JMPENV_PUSH(x);
7048             if (PL_endav && !PL_minus_c) {
7049             #if PERL_VERSION > 13
7050             PL_phase = PERL_PHASE_END;
7051             #endif
7052             call_list(PL_scopestack_ix, PL_endav);
7053             }
7054             JMPENV_POP;
7055             }
7056             _EOT8
7057              
7058 0         0 for (0 .. $#B::C::static_free) {
7059             # set static op members to NULL
7060 0         0 my $s = $B::C::static_free[$_];
7061 0 0       0 if ($s =~ /\(OP\*\)&unopaux_list/) {
7062 0         0 print " ($s)->op_type = OP_NULL;\n";
7063             }
7064             }
7065              
7066 0         0 print <<'_EOT9';
7067             LEAVE;
7068             FREETMPS;
7069             assert(PL_scopestack_ix == 0);
7070              
7071             /* Need to flush since END blocks can produce output */
7072             my_fflush_all();
7073              
7074             PL_main_start = NULL;
7075             PL_main_cv = NULL;
7076             PL_curcop = &PL_compiling;
7077             #if PERL_VERSION >= 13
7078             PL_phase = PERL_PHASE_DESTRUCT;
7079             #endif
7080              
7081             #if PERL_VERSION > 7
7082             if (PL_threadhook(aTHX)) {
7083             /* Threads hook has vetoed further cleanup */
7084             #if (PERL_VERSION > 8) || ((PERL_VERSION == 8) && (PERL_SUBVERSION > 8))
7085             PL_veto_cleanup = TRUE;
7086             return STATUS_EXIT;
7087             #else
7088             return STATUS_NATIVE_EXPORT;
7089             #endif
7090             }
7091             #if defined(PERLIO_LAYERS)
7092             # if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7093             PerlIO_destruct(aTHX);
7094             # endif
7095             #endif
7096              
7097             /* B::C -O3 specific: first curse (i.e. call DESTROY) all our static SVs */
7098             if (PL_sv_objcount) {
7099             int i = 1;
7100             DEBUG_D(PerlIO_printf(Perl_debug_log, "\nCursing named global static sv_arena:\n"));
7101             PL_in_clean_all = 1;
7102             for (; i < SvREFCNT(&sv_list[0]); i++) {
7103             SV *sv = &sv_list[i];
7104             if (SvREFCNT(sv)) {
7105             #if PERL_VERSION > 11
7106             if (SvTYPE(sv) == SVt_IV && SvROK(sv))
7107             #else
7108             if (SvTYPE(sv) == SVt_RV)
7109             #endif
7110             sv = SvRV(sv);
7111             if (sv && SvOBJECT(sv) && SvTYPE(sv) >= SVt_PVMG && SvSTASH(sv)
7112             && SvTYPE(sv) != SVt_PVCV && SvTYPE(sv) != SVt_PVIO
7113             && PL_defstash /* Still have a symbol table? */
7114             && SvDESTROYABLE(sv))
7115             {
7116             SvREFCNT(sv) = 0;
7117             my_curse(aTHX_ sv);
7118             }
7119             }
7120             }
7121             }
7122             if (DEBUG_D_TEST) {
7123             SV* sva;
7124             PerlIO_printf(Perl_debug_log, "\n");
7125             for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) {
7126             PerlIO_printf(Perl_debug_log, "sv_arena: 0x%p - 0x%p (%lu)\n",
7127             sva, sva+SvREFCNT(sva), (long)SvREFCNT(sva));
7128             }
7129             }
7130             #endif
7131              
7132             #if PERL_VERSION > 7
7133             PL_stashcache = (HV*)&PL_sv_undef; /* sometimes corrupted */
7134             #endif
7135             #if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7136             if (PL_sv_objcount) {
7137             # if PERL_VERSION > 7
7138             PL_stashcache = newHV(); /* Hack: sometimes corrupted, holding a GV */
7139             # endif
7140             PL_in_clean_all = 1;
7141             sv_clean_objs(); /* and now curse the rest */
7142             PL_sv_objcount = 0;
7143             }
7144             #endif
7145              
7146             PL_warnhook = NULL;
7147             PL_diehook = NULL;
7148             /* call exit list functions */
7149             while (PL_exitlistlen-- > 0)
7150             PL_exitlist[PL_exitlistlen].fn(aTHX_ PL_exitlist[PL_exitlistlen].ptr);
7151             PL_exitlist = NULL;
7152              
7153             #if defined(PERLIO_LAYERS)
7154             # if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7155             PerlIO_cleanup(aTHX);
7156             # endif
7157             #endif
7158              
7159             #if PERL_VERSION > 7
7160             PL_stashcache = (HV*)&PL_sv_undef;
7161             #endif
7162             /* Silence strtab refcnt warnings during global destruction */
7163             Zero(HvARRAY(PL_strtab), HvMAX(PL_strtab), HE*);
7164             /* NULL the HEK "dfs" */
7165             #if PERL_VERSION > 10
7166             PL_registered_mros = (HV*)&PL_sv_undef;
7167             CopHINTHASH_set(&PL_compiling, NULL);
7168             #endif
7169              
7170             return 0;
7171             }
7172             _EOT9
7173              
7174             }
7175             # special COW handling for 5.10 because of S_unshare_hek_or_pvn limitations
7176             # XXX This fails in S_doeval SAVEFREEOP(PL_eval_root): test 15
7177             # if ( $PERL510 and (@B::C::static_free or $free->index > -1))
7178             else {
7179 0         0 print <<'_EOT7';
7180             int my_perl_destruct( PerlInterpreter *my_perl ) {
7181             VOL signed char destruct_level = PL_perl_destruct_level;
7182             const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
7183              
7184             /* set all our static pv and hek to &PL_sv_undef for perl_destruct() */
7185             _EOT7
7186              
7187             #for (0 .. $hek_index-1) {
7188             # # TODO: non-static only, seperate data structures please
7189             # printf " memset(HEK_HE(hek%d), 0, sizeof(struct shared_he));\n", $_;
7190             #}
7191 0         0 for (0 .. $#B::C::static_free) {
7192             # set the sv/xpv to &PL_sv_undef, not the pv itself.
7193             # If set to NULL pad_undef will fail in SvPVX_const(namesv) == '&'
7194             # XXX Another idea >5.10 is SvFLAGS(pv) = SVTYPEMASK
7195 0         0 my $s = $B::C::static_free[$_];
7196 0 0       0 if ($s =~ /^sv_list\[\d+\]\./) { # pv directly (unused)
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
7197 0         0 print " $s = NULL;\n";
7198             } elsif ($s =~ /^sv_list/) {
7199 0         0 print " SvLEN(&$s) = 0;\n";
7200 0         0 print " SvPV_set(&$s, (char*)&PL_sv_undef);\n";
7201             } elsif ($s =~ /^&sv_list/) {
7202 0         0 print " SvLEN($s) = 0;\n";
7203 0         0 print " SvPV_set($s, (char*)&PL_sv_undef);\n";
7204             } elsif ($s =~ /^\(HV\*\)&sv_list/) {
7205 0         0 print " SvREADONLY_on((SV*)$s);\n";
7206 0         0 print " SvREFCNT($s) = SvREFCNT_IMMORTAL;\n";
7207             } elsif ($s =~ /^\(AV\*\)&sv_list/) { # SVs_OBJECT flag, as the HV
7208             #print " SvREADONLY_on((SV*)$s);\n";
7209             #print " SvREFCNT($s) = SvREFCNT_IMMORTAL;\n";
7210             } elsif ($s =~ /^&padnamelist_list/) {
7211 0         0 print " Safefree(PadnamelistARRAY($s));\n";
7212 0         0 print " PadnamelistMAX($s) = 0;\n";
7213 0         0 print " PadnamelistREFCNT($s) = 0;\n";
7214             } elsif ($s =~ /^&padname(_\d+)?_list/) {
7215 0         0 print " PadnameREFCNT($s) = 0;\n";
7216             # dead code ---
7217             } elsif ($s =~ /^cop_list/) {
7218 0 0 0     0 if ($ITHREADS or !$MULTI) {
7219 0         0 print " CopFILE_set(&$s, NULL);";
7220             }
7221 0 0 0     0 if ($] >= 5.017) {
    0 0        
    0          
7222 0         0 print " CopSTASH_set(&$s, NULL);\n";
7223             } elsif ($] < 5.016 and $ITHREADS) {
7224 0         0 print " CopSTASHPV(&$s) = NULL;\n";
7225             } elsif ($] < 5.016 and !$ITHREADS) {
7226 0         0 print " CopSTASH(&$s) = NULL;\n";
7227             } else { # 5.16 experiment
7228 0         0 print " CopSTASHPV_set(&$s, NULL, 0);\n";
7229             }
7230             } elsif ($s =~ /\(OP\*\)&unopaux_list/) {
7231 0         0 print " ($s)->op_type = OP_NULL;\n";
7232             # end dead code ---
7233             #} elsif ($s =~ /^pv\d/) {
7234             # print " $s = \"\";\n";
7235             } elsif ($s ne 'ptr_undef') {
7236 0         0 warn("unknown $s at \@static_free[$_]");
7237             }
7238             }
7239 0         0 $free->output( \*STDOUT, "%s\n" );
7240              
7241 0         0 my $riter_type = "I32";
7242 0 0       0 if ($CPERL51) {
7243 0 0       0 $riter_type = $CPERL55 ? "U32" : "SSize_t";
7244             }
7245 0         0 my $hvmax_type = "STRLEN";
7246 0 0       0 if ($CPERL51) {
7247 0 0       0 $hvmax_type = $CPERL55 ? "U32" : "SSize_t";
7248             }
7249 0         0 print "#define RITER_T $riter_type\n";
7250 0         0 print "#define HVMAX_T $hvmax_type\n";
7251              
7252 0         0 print <<'_EOT7a';
7253              
7254             /* Avoid Unbalanced string table refcount warning with PERL_DESTRUCT_LEVEL=2 */
7255             if (s) {
7256             const int i = atoi(s);
7257             if (destruct_level < i) destruct_level = i;
7258             }
7259             if (destruct_level >= 1) {
7260             const HVMAX_T max = HvMAX(PL_strtab);
7261             HE * const * const array = HvARRAY(PL_strtab);
7262             RITER_T riter = 0;
7263             HE *hent = array[0];
7264             for (;;) {
7265             if (hent) {
7266             HE * const next = HeNEXT(hent);
7267             if (!HEK_STATIC(&((struct shared_he*)hent)->shared_he_hek))
7268             Safefree(hent);
7269             hent = next;
7270             }
7271             if (!hent) {
7272             if (++riter > max)
7273             break;
7274             hent = array[riter];
7275             }
7276             }
7277             /* Silence strtab refcnt warnings during global destruction */
7278             Zero(HvARRAY(PL_strtab), max, HE*);
7279             /* NULL the HEK "dfs" */
7280             #if PERL_VERSION > 10
7281             PL_registered_mros = (HV*)&PL_sv_undef;
7282             CopHINTHASH_set(&PL_compiling, NULL);
7283             #endif
7284             }
7285              
7286             /* B::C specific: prepend static svs to arena for sv_clean_objs */
7287             SvANY(&sv_list[0]) = (void *)PL_sv_arenaroot;
7288             PL_sv_arenaroot = &sv_list[0];
7289             #if PERL_VERSION > 7
7290             if (DEBUG_D_TEST) {
7291             SV* sva;
7292             PerlIO_printf(Perl_debug_log, "\n");
7293             for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) {
7294             PerlIO_printf(Perl_debug_log, "sv_arena: 0x%p - 0x%p (%lu)\n",
7295             sva, sva+SvREFCNT(sva), (long)SvREFCNT(sva));
7296             }
7297             }
7298              
7299             return perl_destruct( my_perl );
7300             #else
7301             perl_destruct( my_perl );
7302             return 0;
7303             #endif
7304             }
7305             _EOT7a
7306             }
7307              
7308 0         0 print <<'_EOT8';
7309              
7310             /* yanked from perl.c */
7311             static void
7312             xs_init(pTHX)
7313             {
7314             char *file = __FILE__;
7315             dTARG; dSP; CV * cv;
7316             _EOT8
7317 0 0 0     0 if ($CPERL51 and $debug{cv}) {
7318 0         0 print q{
7319             /* -DC set dl_debug to 3 */
7320             SV* sv = get_svs("DynaLoader::dl_debug", GV_ADD);
7321             sv_upgrade(sv, SVt_IV);
7322             SvIV_set(sv, 3);};
7323             }
7324             #if ($staticxs) { #FIXME!
7325             # print "\n#undef USE_DYNAMIC_LOADING
7326             #}
7327              
7328 0         0 delete $xsub{'DynaLoader'};
7329 0         0 delete $xsub{'UNIVERSAL'};
7330 0         0 print("/* XS bootstrapping code*/\n");
7331 0         0 print("\tSAVETMPS;\n");
7332 0         0 print("\ttarg=sv_newmortal();\n");
7333 0         0 foreach my $stashname ( sort keys %static_ext ) {
7334 0         0 my $stashxsub = $stashname;
7335 0         0 $stashxsub =~ s/::/__/g;
7336             #if ($stashxsub =~ m/\/(\w+)\.\w+$/ {$stashxsub = $1;}
7337             # cygwin has Win32CORE in static_ext
7338 0 0       0 warn "bootstrapping static $stashname added to xs_init\n" if $verbose;
7339 0         0 print "\tnewXS(\"$stashname\::bootstrap\", boot_$stashxsub, file);\n";
7340             }
7341 0         0 print "#ifdef USE_DYNAMIC_LOADING\n";
7342 0         0 print "\tPUSHMARK(sp);\n";
7343 0         0 printf "\tXPUSHp(\"DynaLoader\", %d);\n", length("DynaLoader");
7344 0         0 print "\tPUTBACK;\n";
7345 0 0       0 warn "bootstrapping DynaLoader added to xs_init\n" if $verbose;
7346 0         0 print "\tcv = newXS(\"DynaLoader::boot_DynaLoader\", boot_DynaLoader, file);\n";
7347 0         0 print "\tboot_DynaLoader(aTHX_ cv);\n";
7348 0         0 print "\tSPAGAIN;\n";
7349 0 0 0     0 if ($CPERL51 and $^O ne 'MSWin32') {
7350 0         0 print "\tdl_boot(aTHX);\n";
7351             }
7352 0         0 print "#endif\n";
7353              
7354             # my %core = map{$_ => 1} core_packages();
7355 0         0 foreach my $stashname ( sort keys %xsub ) {
7356 0         0 my $incpack = inc_packname($stashname);
7357 0 0       0 unless (exists $curINC{$incpack}) { # skip deleted packages
7358 0 0       0 warn "skip xs_init for $stashname !\$INC{$incpack}\n" if $debug{pkg};
7359 0         0 delete $include_package{$stashname};
7360 0 0       0 delete $xsub{$stashname} unless $static_ext{$stashname};
7361 0         0 next;
7362             }
7363 0 0 0     0 if ( $xsub{$stashname} !~ m/^Dynamic/ and !$static_ext{$stashname}) {
7364 0         0 my $stashxsub = $stashname;
7365 0 0       0 warn "bootstrapping $stashname added to xs_init\n" if $verbose;
7366 0         0 $stashxsub =~ s/::/__/g;
7367 0         0 print "\tPUSHMARK(sp);\n";
7368 0         0 printf "\tXPUSHp(\"%s\", %d);\n", # "::bootstrap" gets appended, TODO
7369             0 ? "strdup($stashname)" : $stashname, length($stashname);
7370 0         0 print "\tPUTBACK;\n";
7371 0         0 print "\tboot_$stashxsub(aTHX_ NULL);\n";
7372 0         0 print "\tSPAGAIN;\n";
7373             }
7374             }
7375 0         0 print "\tFREETMPS;\n/* end XS bootstrapping code */\n";
7376 0         0 print "}\n\n";
7377              
7378 0         0 my ($dl, $xs);
7379 0         0 my @dl_modules = @DynaLoader::dl_modules;
7380 0 0       0 my @PERLMODS = split(/\,/, $ENV{'PERLMODS'}) if $ENV{'PERLMODS'}; # from cpanel
7381 0         0 foreach my $perlmod (@PERLMODS) {
7382 0         0 warn "Extra module ${perlmod}\n";
7383 0 0       0 push @dl_modules, $perlmod unless grep { $_ ne $perlmod } @dl_modules;
  0         0  
7384             }
7385             # filter out unused dynaloaded B modules, used within the compiler only.
7386 0         0 for my $c (qw(B B::C)) {
7387 0 0 0     0 if (!$xsub{$c} and !$include_package{$c}) {
7388             # (hopefully, see test 103)
7389 0 0 0     0 warn "no dl_init for $c, not marked\n" if $verbose and !$skip_package{$c};
7390             # RT81332 pollute
7391 0         0 @dl_modules = grep { $_ ne $c } @dl_modules;
  0         0  
7392             # XXX Be sure to store the new @dl_modules
7393             }
7394             }
7395 0         0 for my $c (sort keys %skip_package) {
7396 0 0 0     0 warn "no dl_init for $c, skipped\n" if $verbose and $xsub{$c};
7397 0         0 delete $xsub{$c};
7398 0         0 $include_package{$c} = undef;
7399 0         0 @dl_modules = grep { $_ ne $c } @dl_modules;
  0         0  
7400             }
7401 0         0 @DynaLoader::dl_modules = @dl_modules;
7402 0 0       0 warn "\@dl_modules: ",join(" ",@dl_modules),"\n" if $verbose;
7403 0         0 foreach my $stashname (@dl_modules) {
7404 0         0 my $incpack = inc_packname($stashname);
7405             #unless (exists $INC{$incpack}) { # skip deleted packages
7406             # warn "XXX skip dl_init for $stashname !\$INC{$incpack}\n" if $debug{pkg};
7407             # delete $xsub{$stashname};
7408             # @dl_modules = grep { $_ ne $stashname } @dl_modules;
7409             #}
7410 0 0 0     0 if ($stashname eq 'attributes' and $] > 5.011) {
7411 0         0 $xsub{$stashname} = 'Dynamic-' . $INC{'attributes.pm'};
7412             }
7413             # actually boot all non-b-c dependent modules here. we assume XSLoader (Moose, List::MoreUtils)
7414 0 0 0     0 if (!exists( $xsub{$stashname} ) and $include_package{$stashname}) {
7415 0         0 $xsub{$stashname} = 'Dynamic-' . $INC{$incpack};
7416             # Class::MOP without Moose: find Moose.pm
7417 0 0       0 $xsub{$stashname} = 'Dynamic-' . $savINC{$incpack} unless $INC{$incpack};
7418 0 0       0 if (!$savINC{$incpack}) {
7419 0         0 eval "require $stashname;";
7420 0         0 $xsub{$stashname} = 'Dynamic-' . $INC{$incpack};
7421             }
7422 0 0       0 warn "Assuming xs loaded $stashname with $xsub{$stashname}\n" if $verbose;
7423             }
7424 0 0 0     0 if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic/ ) {
7425             # XSLoader.pm: $modlibname = (caller())[1]; needs a path at caller[1] to find auto,
7426             # otherwise we only have -e
7427 0 0       0 $xs++ if $xsub{$stashname} ne 'Dynamic';
7428 0         0 $dl++;
7429             }
7430 0         0 my $stashxsub = $stashname;
7431 0         0 $stashxsub =~ s/::/__/g;
7432 0 0 0     0 if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic-/
      0        
      0        
7433             and ($PERL522 or $staticxs)) {
7434 0         0 print "EXTERN_C void boot_$stashxsub(pTHX_ CV* cv);\n";
7435             }
7436             }
7437 0 0 0     0 warn "\%xsub: ",join(" ",sort keys %xsub),"\n" if $verbose and $debug{cv};
7438             # XXX Adding DynaLoader is too late here! The sections like $init are already dumped (#125)
7439 0 0 0     0 if ($dl and ! $curINC{'DynaLoader.pm'}) {
    0 0        
7440 0         0 die "Error: DynaLoader required but not dumped. Too late to add it.\n";
7441             } elsif ($xs and ! $curINC{'XSLoader.pm'}) {
7442 0         0 die "Error: XSLoader required but not dumped. Too late to add it.\n";
7443             }
7444 0         0 print <<'_EOT9';
7445              
7446             static void
7447             dl_init(pTHX)
7448             {
7449             char *file = __FILE__;
7450             _EOT9
7451              
7452 0 0       0 if ($dl) {
7453             # enforce attributes at the front of dl_init, #259
7454             # also Encode should be booted before PerlIO::encoding
7455 0         0 for my $front (qw(Encode attributes)) {
7456 0 0       0 if (grep { $_ eq $front } @dl_modules) {
  0         0  
7457 0         0 @dl_modules = grep { $_ ne $front } @dl_modules;
  0         0  
7458 0         0 unshift @dl_modules, $front;
7459             }
7460             }
7461 0 0       0 if ($staticxs) {open( XS, ">", $outfile.".lst" ) or return "$outfile.lst: $!\n"}
  0 0       0  
7462 0         0 print "\tdTARG; dSP;\n";
7463 0         0 print "/* DynaLoader bootstrapping */\n";
7464 0         0 print "\tENTER;\n";
7465 0 0       0 print "\t++cxstack_ix; cxstack[cxstack_ix].blk_oldcop = PL_curcop;\n" if $xs;
7466 0 0       0 print "\t/* assert(cxstack_ix == 0); */\n" if $xs;
7467 0         0 print "\tSAVETMPS;\n";
7468 0 0       0 print "\ttarg = sv_newmortal();\n" if $] < 5.008008;
7469              
7470 0 0 0     0 if (exists $xsub{"Coro::State"} and grep { $_ eq "Coro::State" } @dl_modules) {
  0         0  
7471             # Coro readonly symbols in BOOT (#293)
7472             # needed before dl_init, and after init
7473 0         0 print "\t{\n\t GV *sym;\n";
7474 0         0 for my $s (qw(Coro Coro::API Coro::current)) {
7475 0         0 print "\t sym = gv_fetchpv(\"$s\",0,SVt_PV);\n";
7476 0         0 print "\t if (sym && GvSVn(sym)) SvREADONLY_off(GvSVn(sym));\n";
7477             }
7478 0         0 print "\t sym = gv_fetchpv(\"Coro::pool_handler)\",0,SVt_PVCV);\n";
7479 0         0 print "\t if (sym && GvCV(sym)) SvREADONLY_off(GvCV(sym));\n";
7480 0         0 print "\t}\n";
7481             }
7482 0 0 0     0 if (exists $xsub{"EV"} and grep { $_ eq "EV" } @dl_modules) {
  0         0  
7483             # EV readonly symbols in BOOT (#368)
7484 0         0 print "\t{\n\t GV *sym;\n";
7485 0         0 for my $s (qw(EV::API)) {
7486 0         0 print "\t sym = gv_fetchpv(\"$s\",0,SVt_PV);\n";
7487 0         0 print "\t if (sym && GvSVn(sym)) SvREADONLY_off(GvSVn(sym));\n";
7488             }
7489 0         0 print "\t}\n";
7490             }
7491 0         0 foreach my $stashname (@dl_modules) {
7492 0 0 0     0 if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic/ ) {
7493 0         0 $use_xsloader = 1;
7494 0         0 print "\n\tPUSHMARK(sp);\n";
7495             # XXX -O1 or -O2 needs XPUSHs with dynamic pv
7496 0 0       0 printf "\t%s(%s, %d);\n", # "::bootstrap" gets appended
7497             $] < 5.008008 ? "XPUSHp" : "mXPUSHp", "\"$stashname\"", length($stashname);
7498 0 0       0 if ( $xsub{$stashname} eq 'Dynamic' ) {
7499 55     55   408 no strict 'refs';
  55         84  
  55         20154  
7500 0 0       0 warn "dl_init $stashname\n" if $verbose;
7501             # just in case we missed it. DynaLoader really needs the @ISA (#308)
7502 0         0 B::svref_2object( \@{$stashname."::ISA"} ) ->save;
  0         0  
7503 0         0 print "#ifndef STATICXS\n";
7504 0         0 print "\tPUTBACK;\n";
7505 0         0 print qq/\tcall_method("DynaLoader::bootstrap_inherit", G_VOID|G_DISCARD);\n/;
7506             }
7507             else { # XS: need to fix cx for caller[1] to find auto/...
7508 0         0 my ($stashfile) = $xsub{$stashname} =~ /^Dynamic-(.+)$/;
7509 0         0 print "#ifndef STATICXS\n";
7510 0 0 0     0 if ($] >= 5.015003 and $stashfile) {
7511 0 0       0 if ($CPERL51) {
7512 0         0 my $sofile;
7513             # search stashname in loaded sofiles
7514 0         0 my @modparts = split(/::/,$stashname);
7515 0         0 my $modfname = $modparts[-1];
7516 0         0 my $modpname = join('/',@modparts);
7517 0         0 my $needle = "auto/$modpname/$modfname\\.".$Config{dlext};
7518             #warn " load_file: @DynaLoader::dl_shared_objects";
7519             #warn " sofile?: $needle";
7520 0         0 for (@DynaLoader::dl_shared_objects) {
7521 0 0       0 if (m{$needle}) {
7522             #warn " load_file: found $_";
7523 0         0 $sofile = $_; last;
  0         0  
7524             }
7525             }
7526 0 0       0 unless ($sofile) {
7527 0         0 my $modlibname = $stashfile;
7528 0         0 my $c = scalar @modparts;
7529 0 0 0     0 if ($stashname eq 'Cwd' and $stashfile !~ /Cwd/) {
7530 0         0 warn "load_file: fixup Cwd vs $stashfile";
7531 0         0 $c = 3;
7532             }
7533 0         0 $modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename
7534 0         0 $sofile = "$modlibname/auto/$modpname/$modfname.".$Config{dlext};
7535             }
7536             #warn "load_file: $stashname, $stashfile, $sofile";
7537 0         0 $stashfile = $sofile;
7538             }
7539 0         0 my $stashfile_len = length($stashfile);
7540 0         0 $stashfile =~ s/(\\[^nrftacx"' ])/\\$1/g; # windows paths: \\ => \\\\
7541 0         0 printf "\tmXPUSHp(\"%s\", %d);\n", $stashfile, $stashfile_len;
7542             }
7543 0         0 print "\tPUTBACK;\n";
7544 0 0       0 warn "bootstrapping $stashname added to XSLoader dl_init\n" if $verbose;
7545             # XSLoader has the 2nd insanest API in whole Perl, right after make_warnings_object()
7546             # 5.15.3 workaround for [perl #101336]
7547 0 0       0 if ($] >= 5.015003) {
7548 55     55   258 no strict 'refs';
  55         81  
  55         64685  
7549 0 0       0 unless (grep /^DynaLoader$/, get_isa($stashname)) {
7550 0         0 push @{$stashname."::ISA"}, 'DynaLoader';
  0         0  
7551 0         0 svref_2object( \@{$stashname."::ISA"} ) ->save;
  0         0  
7552             }
7553 0 0       0 warn '@',$stashname,"::ISA=(",join(",",@{$stashname."::ISA"}),")\n" if $debug{gv};
  0         0  
7554             # TODO #364: if a VERSION was provided need to add it here
7555 0         0 print qq/\tcall_pv("XSLoader::load_file", G_VOID|G_DISCARD);\n/;
7556             } else {
7557 0 0       0 printf qq/\tCopFILE_set(cxstack[cxstack_ix].blk_oldcop, "%s");\n/,
7558             $stashfile if $stashfile;
7559             # TODO #364: if a VERSION was provided need to add it here
7560 0         0 print qq/\tcall_pv("XSLoader::load", G_VOID|G_DISCARD);\n/;
7561             }
7562             }
7563 0 0       0 if ($staticxs) {
7564 0         0 my ($laststash) = $stashname =~ /::([^:]+)$/;
7565 0         0 my $path = $stashname;
7566 0         0 $path =~ s/::/\//g;
7567 0 0       0 $path .= "/" if $path; # can be empty
7568 0 0       0 $laststash = $stashname unless $laststash; # without ::
7569 0         0 my $sofile = "auto/" . $path . $laststash . '\.' . $Config{dlext};
7570             #warn "staticxs search $sofile in @DynaLoader::dl_shared_objects\n"
7571             # if $verbose and $debug{pkg};
7572 0         0 for (@DynaLoader::dl_shared_objects) {
7573 0 0       0 if (m{^(.+/)$sofile$}) {
7574 0         0 print XS $stashname,"\t",$_,"\n";
7575 0 0       0 warn "staticxs $stashname\t$_\n" if $verbose;
7576 0         0 $sofile = '';
7577 0         0 last;
7578             }
7579             }
7580 0 0       0 print XS $stashname,"\n" if $sofile; # error case
7581 0 0 0     0 warn "staticxs $stashname\t - $sofile not loaded\n" if $sofile and $verbose;
7582             }
7583 0         0 print "#else\n";
7584 0         0 print "\tPUTBACK;\n";
7585 0         0 my $stashxsub = $stashname;
7586 0         0 $stashxsub =~ s/::/__/g;
7587 0 0 0     0 if ($PERL522 or $staticxs) {
7588             # CvSTASH(CvGV(cv)) is invalid without (issue 86)
7589             # TODO: utf8 stashname (does make sense when loading from the fs?)
7590 0 0 0     0 if ($PERL522 and $staticxs) { # GH 333
7591 0         0 print "\t{
7592             CV* cv = (CV*)SvREFCNT_inc_simple_NN(get_cv(\"$stashname\::bootstrap\", GV_ADD));
7593             CvISXSUB_on(cv); /* otherwise a perl assertion fails. */
7594             cv->sv_any->xcv_padlist_u.xcv_hscxt = &PL_stack_sp; /* xs_handshake */
7595             boot_$stashxsub(aTHX_ cv);
7596             }\n";
7597             } else {
7598 0         0 print "\tboot_$stashxsub(aTHX_ get_cv(\"$stashname\::bootstrap\", GV_ADD));\n";
7599             }
7600             } else {
7601 0         0 print "\tboot_$stashxsub(aTHX_ NULL);\n";
7602             }
7603 0         0 print "#endif\n";
7604 0         0 print "\tSPAGAIN;\n";
7605             #print "\tPUTBACK;\n";
7606             } else {
7607             warn "no dl_init for $stashname, ".
7608 0 0       0 (!$xsub{$stashname} ? "not bootstrapped\n" : "bootstrapped as $xsub{$stashname}\n")
    0          
7609             if $verbose;
7610             # XXX Too late. This might fool run-time DynaLoading.
7611             # We really should remove this via init from @DynaLoader::dl_modules
7612 0         0 @DynaLoader::dl_modules = grep { $_ ne $stashname } @DynaLoader::dl_modules;
  0         0  
7613              
7614             }
7615             }
7616 0         0 print "\tFREETMPS;\n";
7617 0 0       0 print "\tcxstack_ix--;\n" if $xs; # i.e. POPBLOCK
7618 0         0 print "\tLEAVE;\n";
7619 0         0 print "/* end DynaLoader bootstrapping */\n";
7620 0 0       0 close XS if $staticxs;
7621             }
7622 0         0 print "}\n";
7623             }
7624              
7625             sub output_main {
7626 0 0   0 0 0 if (!defined($module)) {
7627 0         0 print <<'_EOT10';
7628              
7629             /* if USE_IMPLICIT_SYS, we need a 'real' exit */
7630             #if defined(exit)
7631             #undef exit
7632             #endif
7633              
7634             int
7635             main(int argc, char **argv, char **env)
7636             {
7637             int exitstatus;
7638             int i;
7639             char **fakeargv;
7640             int options_count;
7641             PerlInterpreter *my_perl;
7642              
7643             PERL_SYS_INIT3(&argc,&argv,&env);
7644              
7645             #ifdef WIN32
7646             #define PL_do_undump 0
7647             #endif
7648             if (!PL_do_undump) {
7649             my_perl = perl_alloc();
7650             if (!my_perl)
7651             exit(1);
7652             perl_construct( my_perl );
7653             PL_perl_destruct_level = 0;
7654             }
7655             _EOT10
7656 0 0 0     0 if ($ITHREADS and $] > 5.007) {
7657             # XXX init free elems!
7658 0         0 my $pad_len = regex_padav->FILL; # first is an empty avref
7659 0         0 print <<_EOT11;
7660             #ifdef USE_ITHREADS
7661             if (!*PL_regex_pad) {
7662             /* Someone is overwriting regex_pad since 5.15, but not on -fno-warnings */
7663             PL_regex_padav = newAV();
7664             #if PERL_VERSION > 10
7665             av_push(PL_regex_padav, newSVpvs("")); /* First entry is empty */
7666             #else
7667             av_push(PL_regex_padav, newSViv(0));
7668             #endif
7669             PL_regex_pad = AvARRAY(PL_regex_padav);
7670             }
7671             for( i = 0; i < $pad_len; ++i ) {
7672             av_push( PL_regex_padav, newSViv(0) );
7673             }
7674             PL_regex_pad = AvARRAY( PL_regex_padav );
7675             #endif
7676             _EOT11
7677              
7678             }
7679 0 0       0 print " PL_exit_flags |= PERL_EXIT_DESTRUCT_END;\n" unless $PERL56;
7680 0 0       0 if ($] >= 5.008009) {
7681 0         0 print <<'_SAFE_PUTENV';
7682             #ifndef PERL_USE_SAFE_PUTENV
7683             PL_use_safe_putenv = 0;
7684             #endif
7685             _SAFE_PUTENV
7686             }
7687 0 0       0 if (!$PERL510) {
7688 0         0 print <<'_EOT12';
7689             #if defined(CSH)
7690             if (!PL_cshlen)
7691             PL_cshlen = strlen(PL_cshname);
7692             #endif
7693             _EOT12
7694             }
7695              
7696             # XXX With -e "" we need to fake parse_body() scriptname = BIT_BUCKET
7697 0         0 print <<'_EOT13';
7698             #ifdef ALLOW_PERL_OPTIONS
7699             #define EXTRA_OPTIONS 3
7700             #else
7701             #define EXTRA_OPTIONS 4
7702             #endif /* ALLOW_PERL_OPTIONS */
7703             Newx(fakeargv, argc + EXTRA_OPTIONS + 1, char *);
7704             fakeargv[0] = argv[0];
7705             fakeargv[1] = "-e";
7706             fakeargv[2] = "";
7707             options_count = 3;
7708             _EOT13
7709              
7710             # honour -T
7711 0 0 0     0 if (!$PERL56 and ${^TAINT}) {
7712 0         0 print <<'_EOT14';
7713             fakeargv[options_count] = "-T";
7714             ++options_count;
7715             _EOT14
7716              
7717             }
7718 0         0 print <<'_EOT15';
7719             #ifndef ALLOW_PERL_OPTIONS
7720             fakeargv[options_count] = "--";
7721             ++options_count;
7722             #endif /* ALLOW_PERL_OPTIONS */
7723             for (i = 1; i < argc; i++)
7724             fakeargv[i + options_count - 1] = argv[i];
7725             fakeargv[argc + options_count - 1] = 0;
7726              
7727             exitstatus = perl_parse(my_perl, xs_init, argc + options_count - 1,
7728             fakeargv, env);
7729             if (exitstatus)
7730             exit( exitstatus );
7731              
7732             TAINT;
7733             _EOT15
7734              
7735 0 0       0 if ($use_perl_script_name) {
7736 0         0 my $dollar_0 = cstring($0);
7737 0         0 print sprintf(qq{ sv_setpv_mg(get_svs("0", GV_ADD|GV_NOTQUAL), %s);\n}, $dollar_0);
7738 0         0 print sprintf(qq{ CopFILE_set(&PL_compiling, %s);\n}, $dollar_0);
7739             }
7740             else {
7741             #print q{ warn("PL_origalen=%d\n", PL_origalen);},"\n";
7742 0         0 print qq{ sv_setpv_mg(get_svs("0", GV_ADD|GV_NOTQUAL), argv[0]);\n};
7743 0         0 print qq{ CopFILE_set(&PL_compiling, argv[0]);\n};
7744             }
7745             # more global vars
7746 0 0       0 print " PL_hints = $^H;\n" if $^H;
7747 0 0       0 print " PL_unicode = ${^UNICODE};\n" if ${^UNICODE};
7748             # system-specific needs to be skipped: is set during init_i18nl10n if PerlIO
7749             # is compiled in and on a utf8 locale.
7750             #print " PL_utf8locale = ${^UTF8LOCALE};\n" if ${^UTF8LOCALE};
7751             #print " PL_utf8cache = ${^UTF8CACHE};\n" if ${^UTF8CACHE};
7752             # nomg
7753 0 0       0 print sprintf(qq{ sv_setpv(get_svs(";", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($;)) if $; ne "\34";
7754 0 0       0 print sprintf(qq{ sv_setpv(get_svs("\\"", GV_NOTQUAL), %s); /* \$" */\n}, cstring($")) if $" ne " ";
7755             # global IO vars
7756 0 0       0 if ($PERL56) {
7757 0 0       0 print sprintf(qq{ PL_ofs = %s; PL_ofslen = %u; /* \$, */\n}, cstring($,), length $,) if $,;
7758 0 0       0 print sprintf(qq{ PL_ors = %s; PL_orslen = %u; /* \$\\ */\n}, cstring($\), length $\) if $\;
7759             } else {
7760 0 0       0 print sprintf(qq{ sv_setpv_mg(GvSVn(PL_ofsgv), %s); /* \$, */\n}, cstring($,)) if $,;
7761 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs("\\\\", GV_ADD|GV_NOTQUAL), %s); /* \$\\ */\n}, cstring($\)) if $\; #ORS
7762             }
7763 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs("/", GV_NOTQUAL), %s);\n}, cstring($/)) if $/ ne "\n"; #RS
7764 0 0       0 print qq{ sv_setiv_mg(get_svs("|", GV_ADD|GV_NOTQUAL), $|);\n} if $|; #OUTPUT_AUTOFLUSH
7765             # global format vars
7766 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs("^A", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($^A)) if $^A; #ACCUMULATOR
7767 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs("^L", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($^L)) if $^L ne "\f"; #FORMFEED
7768 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs(":", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($:)) if $: ne " \n-"; #LINE_BREAK_CHARACTERS
7769 0 0       0 print sprintf(qq/ sv_setpv_mg(get_svs("^", GV_ADD|GV_NOTQUAL), savepvn(%s, %u));\n/, cstring($^), length($^))
7770             if $^ ne "STDOUT_TOP";
7771 0 0       0 print sprintf(qq/ sv_setpv_mg(get_svs("~", GV_ADD|GV_NOTQUAL), savepvn(%s, %u));\n/, cstring($~), length($~))
7772             if $~ ne "STDOUT";
7773 0 0       0 print qq{ sv_setiv_mg(get_svs("%", GV_ADD|GV_NOTQUAL), $%);\n} if $%; #PAGE_NUMBER
7774 0 0 0     0 print qq{ sv_setiv_mg(get_svs("-", GV_ADD|GV_NOTQUAL), $-);\n} unless ($- == 0 or $- == 60); #LINES_LEFT
7775 0 0       0 print qq{ sv_setiv_mg(get_svs("=", GV_ADD|GV_NOTQUAL), $=);\n} if $= != 60; #LINES_PER_PAGE
7776              
7777             # deprecated global vars
7778 55 0   55   33310 print qq{ {SV* s = get_svs("[",GV_NOTQUAL); sv_setiv(s, $[); mg_set(s);}\n} if $[; #ARRAY_BASE
  55         16111  
  55         48857  
  0         0  
7779 0 0       0 if ($] < 5.010) { # OFMT and multiline matching
7780 0         0 eval q[
7781             print sprintf(qq{ sv_setpv(GvSVn(gv_fetchpv("\$#", GV_ADD|GV_NOTQUAL, SVt_PV)), %s);\n},
7782             cstring($#)) if $#;
7783             print sprintf(qq{ sv_setiv(GvSVn(gv_fetchpv("\$*", GV_ADD|GV_NOTQUAL, SVt_IV)), %d);\n}, $*) if $*;
7784             ];
7785             }
7786              
7787 0         0 print sprintf(qq{ sv_setpv_mg(get_svs("\030", GV_ADD|GV_NOTQUAL), %s); /* \$^X */\n}, cstring($^X));
7788 0         0 print <<"EOT";
7789             TAINT_NOT;
7790              
7791             #if PERL_VERSION < 10 || ((PERL_VERSION == 10) && (PERL_SUBVERSION < 1))
7792             PL_compcv = 0;
7793             #else
7794             PL_compcv = MUTABLE_CV(newSV_type(SVt_PVCV));
7795             CvUNIQUE_on(PL_compcv);
7796             CvPADLIST(PL_compcv) = pad_new(0);
7797             #endif
7798              
7799             /* our special compiled init */
7800             perl_init(aTHX);
7801             EOT
7802 0 0       0 print " perl_init1(aTHX);\n" if $init1->index >= 0;
7803 0 0       0 print " dl_init(aTHX);\n" unless defined $module;
7804 0 0       0 print " perl_init2(aTHX);\n" if $init2->index >= 0;
7805 0         0 print "\n exitstatus = perl_run( my_perl );\n";
7806 0         0 foreach my $s ( @{ $init->[-1]{pre_destruct} } ) {
  0         0  
7807 0         0 print " ".$s."\n";
7808             }
7809              
7810 0 0       0 if ( !$B::C::destruct ) {
7811 0 0       0 warn "fast_perl_destruct (-fno-destruct)\n" if $verbose;
7812 0         0 print " fast_perl_destruct( my_perl );\n";
7813             #} elsif ( $PERL510 and (@B::C::static_free or $free->index > -1) ) {
7814             # warn "my_perl_destruct static strings\n" if $verbose;
7815             # print " my_perl_destruct( my_perl );\n";
7816             #} elsif ( $] >= 5.007003 ) {
7817             # print " perl_destruct( my_perl );\n";
7818             }
7819             else {
7820 0         0 print " my_perl_destruct( my_perl );\n";
7821             }
7822             # XXX endav is called via call_list and so it is freed right after usage. Setting dirty here is useless
7823             #print " PL_dirty = 1;\n" unless $B::C::pv_copy_on_grow; # protect against pad undef in END block
7824 0         0 print <<'EOT1';
7825             perl_free( my_perl );
7826              
7827             PERL_SYS_TERM();
7828              
7829             exit( exitstatus );
7830             }
7831             EOT1
7832              
7833             } # module
7834             }
7835              
7836             sub dump_symtable {
7837             # For debugging
7838 0     0 0 0 my ( $sym, $val );
7839 0         0 warn "----Symbol table:\n";
7840             #while ( ( $sym, $val ) = each %symtable )
7841 0         0 for $sym (sort keys %symtable) {
7842 0         0 $val = $symtable{$sym};
7843 0         0 warn "$sym => $val\n";
7844             }
7845 0         0 warn "---End of symbol table\n";
7846             }
7847              
7848             sub save_object {
7849 0     0 0 0 my $sv;
7850 0         0 foreach $sv (@_) {
7851 0         0 svref_2object($sv)->save;
7852             }
7853             }
7854              
7855       0 0   sub Dummy_BootStrap { }
7856              
7857             #ignore nullified cv
7858       0     sub B::SPECIAL::savecv {}
7859              
7860             sub B::GV::savecv {
7861 0     0   0 my $gv = shift;
7862 0         0 my $package = $gv->STASH->NAME;
7863 0         0 my $name = $gv->NAME;
7864 0         0 my $cv = $gv->CV;
7865 0         0 my $sv = $gv->SV;
7866 0         0 my $av = $gv->AV;
7867 0         0 my $hv = $gv->HV;
7868              
7869 0         0 my $fullname = $package . "::" . $name;
7870             warn sprintf( "Checking GV *%s 0x%x\n", cstring($fullname), $$gv )
7871 0 0 0     0 if $debug{gv} and $verbose;
7872             # We may be looking at this package just because it is a branch in the
7873             # symbol table which is on the path to a package which we need to save
7874             # e.g. this is 'Getopt' and we need to save 'Getopt::Long'
7875             #
7876 0 0 0     0 return if ( $package ne 'main' and !$include_package{$package} );
7877 0 0 0     0 return if ( $package eq 'main' and
7878             $name =~ /^([^\w].*|_\<.*|INC|ARGV|SIG|ENV|BEGIN|main::|!)$/ );
7879              
7880 0 0       0 warn sprintf( "Used GV \*$fullname 0x%x\n", $$gv ) if $debug{gv};
7881 0 0 0     0 return unless ( $$cv || $$av || $$sv || $$hv || $gv->IO || $gv->FORM );
      0        
      0        
      0        
      0        
7882 0 0 0     0 if ($$cv and $name eq 'bootstrap' and $cv->XSUB) {
      0        
7883             #return $cv->save($fullname);
7884 0 0       0 warn sprintf( "Skip XS \&$fullname 0x%x\n", $$cv ) if $debug{gv};
7885 0         0 return;
7886             }
7887 0 0 0     0 if ( $$cv and in_static_core($package, $name) and ref($cv) eq 'B::CV' # 5.8,4 issue32
      0        
      0        
7888             and $cv->XSUB ) {
7889 0 0       0 warn("Skip internal XS $fullname\n") if $debug{gv};
7890             # but prevent it from being deleted
7891 0 0       0 unless ($dumped_package{$package}) {
7892             #$dumped_package{$package} = 1;
7893 0         0 mark_package($package, 1);
7894             }
7895 0         0 return;
7896             }
7897 0 0       0 if ($package eq 'B::C') {
7898 0 0       0 warn sprintf( "Skip XS \&$fullname 0x%x\n", $$cv ) if $debug{gv};
7899 0         0 return;
7900             }
7901 0 0       0 if ($fullname =~ /^(bytes|utf8)::AUTOLOAD$/) {
7902 0         0 $gv = force_heavy($package);
7903             }
7904             # XXX fails and should not be needed. The B::C part should be skipped 9 lines above, but be defensive
7905 0 0 0     0 return if $fullname eq 'B::walksymtable' or $fullname eq 'B::C::walksymtable';
7906             # Config is marked on any Config symbol. TIE and DESTROY are exceptions,
7907             # used by the compiler itself
7908 0 0       0 if ($name eq 'Config') {
7909 0 0       0 mark_package('Config', 1) if !$include_package{'Config'};
7910             }
7911 0 0 0     0 $dumped_package{$package} = 1 if !exists $dumped_package{$package} and $package !~ /::$/;
7912 0 0       0 warn sprintf( "Saving GV \*$fullname 0x%x\n", $$gv ) if $debug{gv};
7913 0         0 $gv->save($fullname);
7914             }
7915              
7916             # Fixes bug #307: use foreach, not each
7917             # each is not safe to use (at all). walksymtable is called recursively which might add
7918             # symbols to the stash, which might cause re-ordered rehashes, which will fool the hash
7919             # iterator, leading to missing symbols in the binary.
7920             # Old perl5 bug: The iterator should really be stored in the op, not the hash.
7921             sub walksymtable {
7922 0     0 0 0 my ($symref, $method, $recurse, $prefix) = @_;
7923 0         0 my ($sym, $ref, $fullname);
7924 0 0       0 $prefix = '' unless defined $prefix;
7925              
7926             # If load_utf8_heavy doesn't happen before we walk utf8::
7927             # (when utf8_heavy has already been called) then the stored CV for utf8::S
7928             # WASHNEW could be wrong.
7929 0 0 0     0 load_utf8_heavy() if ( $prefix eq 'utf8::' && defined $symref->{'SWASHNEW'} );
7930              
7931             my @list = sort {
7932             # we want these symbols to be saved last to avoid incomplete saves
7933             # +/- reverse is to defer + - to fix Tie::Hash::NamedCapturespecial cases. GH #247
7934             # _loose_name redefined from utf8_heavy.pl GH #364
7935 0         0 foreach my $v (qw{- + utf8:: bytes::}) {
  0         0  
7936 0 0       0 $a eq $v and return 1;
7937 0 0       0 $b eq $v and return -1;
7938             }
7939             # reverse order for now to preserve original behavior before improved patch
7940 0         0 $b cmp $a
7941             } keys %$symref;
7942              
7943 0         0 foreach my $sym ( @list ) {
7944 55     55   287 no strict 'refs';
  55         82  
  55         8260  
7945 0         0 $ref = $symref->{$sym};
7946 0         0 $fullname = "*main::".$prefix.$sym;
7947 0 0       0 if ($sym =~ /::$/) {
7948 0         0 $sym = $prefix . $sym;
7949 0 0 0     0 if (svref_2object(\*$sym)->NAME ne "main::" && $sym ne "::" && &$recurse($sym)) {
      0        
7950 0         0 walksymtable(\%$fullname, $method, $recurse, $sym);
7951             }
7952             } else {
7953 0         0 svref_2object(\*$fullname)->$method();
7954             }
7955             }
7956             }
7957              
7958             sub walk_syms {
7959 0     0 0 0 my $package = shift;
7960 55     55   243 no strict 'refs';
  55         84  
  55         6185  
7961 0 0       0 return if $dumped_package{$package};
7962 0 0 0     0 warn "walk_syms $package\n" if $debug{pkg} and $verbose;
7963 0         0 $dumped_package{$package} = 1;
7964 0     0   0 walksymtable( \%{$package.'::'}, "savecv", sub { 1 }, $package.'::' );
  0         0  
  0         0  
7965             }
7966              
7967             # simplified walk_syms
7968             # needed to populate @B::C::Config::deps from Makefile.PL from within this %INC context
7969             sub walk_stashes {
7970 0     0 0 0 my ($symref, $prefix) = @_;
7971 55     55   239 no strict 'refs';
  55         78  
  55         11595  
7972 0 0       0 $prefix = '' unless defined $prefix;
7973 0         0 foreach my $sym ( sort keys %$symref ) {
7974 0 0       0 if ($sym =~ /::$/) {
7975 0         0 $sym = $prefix . $sym;
7976 0         0 $B::C::deps{ substr($sym,0,-2) }++;
7977 0 0 0     0 if ($sym ne "main::" && $sym ne "::") {
7978 0         0 walk_stashes(\%$sym, $sym);
7979             }
7980             }
7981             }
7982             }
7983              
7984             sub collect_deps {
7985 0     0 0 0 %B::C::deps = ();
7986 0         0 walk_stashes(\%main::);
7987 0         0 print join " ",(sort keys %B::C::deps);
7988             }
7989              
7990             sub mark_package {
7991 0     0 0 0 my $package = shift;
7992 0         0 my $force = shift;
7993 0 0       0 $force = 0 if $] < 5.010;
7994 0 0       0 return if skip_pkg($package); # or $package =~ /^B::C(C?)::/;
7995 0 0 0     0 if ( !$include_package{$package} or $force ) {
7996 55     55   237 no strict 'refs';
  55         78  
  55         14367  
7997 0 0 0     0 warn "mark_package($package, $force)\n" if $verbose and $debug{pkg};
7998 0         0 my @IO = qw(IO::File IO::Handle IO::Socket IO::Seekable IO::Poll);
7999 0 0       0 mark_package('IO') if grep { $package eq $_ } @IO;
  0         0  
8000 0 0       0 mark_package("DynaLoader") if $package eq 'XSLoader';
8001 0 0       0 $use_xsloader = 1 if $package =~ /^B|Carp$/; # to help CC a bit (49)
8002             # i.e. if force
8003 0 0 0     0 if (exists $include_package{$package}
      0        
8004             and !$include_package{$package}
8005             and $savINC{inc_packname($package)})
8006             {
8007 0 0       0 warn sprintf("$package previously deleted, save now%s\n",
    0          
8008             $force?" (forced)":"") if $verbose;
8009             # $include_package{$package} = 1;
8010 0         0 add_hashINC( $package );
8011 0         0 walk_syms( $package );
8012             } else {
8013             warn sprintf("mark $package%s\n", $force?" (forced)":"")
8014 0 0 0     0 if !$include_package{$package} and $verbose and $debug{pkg};
    0 0        
8015 0         0 $include_package{$package} = 1;
8016 0 0       0 push_package($package) if $] < 5.010;
8017 0 0       0 walk_syms( $package ) if !$B::C::walkall; # fixes i27-1
8018             }
8019 0         0 my @isa = get_isa($package);
8020 0 0       0 if ( @isa ) {
8021             # XXX walking the ISA is often not enough.
8022             # we should really check all new packages since the last full scan.
8023 0         0 foreach my $isa ( @isa ) {
8024 0 0       0 next if $isa eq $package;
8025 0 0       0 if ( $isa eq 'DynaLoader' ) {
8026 0 0       0 unless ( defined( &{ $package . '::bootstrap' } ) ) {
  0         0  
8027 0 0       0 warn "Forcing bootstrap of $package\n" if $verbose;
8028 0         0 eval { $package->bootstrap };
  0         0  
8029             }
8030             }
8031 0 0 0     0 if ( !$include_package{$isa} and !$skip_package{$isa} ) {
8032 55     55   237 no strict 'refs';
  55         74  
  55         34930  
8033 0 0       0 warn "$isa saved (it is in $package\'s \@ISA)\n" if $verbose;
8034 0         0 B::svref_2object( \@{$isa."::ISA"} ) ->save; #308
  0         0  
8035 0 0       0 if (exists $include_package{$isa} ) {
8036 0 0       0 warn "$isa previously deleted, save now\n" if $verbose; # e.g. Sub::Name
8037 0         0 mark_package($isa);
8038 0         0 walk_syms($isa); # avoid deep recursion
8039             } else {
8040             #warn "isa $isa save\n" if $verbose;
8041 0         0 mark_package($isa);
8042             }
8043             }
8044             }
8045             }
8046             }
8047 0         0 return 1;
8048             }
8049              
8050             # XS in CORE which do not need to be bootstrapped extra.
8051             # There are some specials like mro,re,UNIVERSAL.
8052             sub in_static_core {
8053 0     0 0 0 my ($stashname, $cvname) = @_;
8054 0 0       0 if ($stashname eq 'UNIVERSAL') {
8055 0         0 return $cvname =~ /^(isa|can|DOES|VERSION)$/;
8056             }
8057 0 0       0 %static_core_pkg = map {$_ => 1} static_core_packages()
  0         0  
8058             unless %static_core_pkg;
8059 0 0       0 return 1 if $static_core_pkg{$stashname};
8060 0 0       0 if ($stashname eq 'mro') {
8061 0         0 return $cvname eq 'method_changed_in';
8062             }
8063 0 0       0 if ($stashname eq 're') {
8064 0         0 return $cvname =~ /^(is_regexp|regname|regnames|regnames_count|regexp_pattern)$/;;
8065             }
8066 0 0       0 if ($stashname eq 'PerlIO') {
8067 0         0 return $cvname eq 'get_layers';
8068             }
8069 0 0       0 if ($stashname eq 'PerlIO::Layer') {
8070 0         0 return $cvname =~ /^(find|NoWarnings)$/;
8071             }
8072 0         0 return 0;
8073             }
8074              
8075             # XS modules in CORE. Reserved namespaces.
8076             # Note: mro,re,UNIVERSAL have both, static core and dynamic/static XS
8077             # version has an external ::vxs
8078             sub static_core_packages {
8079 0     0 0 0 my @pkg = qw(Internals utf8 UNIVERSAL);
8080 0 0       0 push @pkg, qw(strict coretypes DynaLoader XSLoader) if $CPERL51;
8081 0 0       0 push @pkg, 'attributes' if $] < 5.011; # partially static and dynamic
8082 0 0       0 push @pkg, 'version' if $] >= 5.010; # partially static and dynamic
8083 0 0       0 push @pkg, 'Tie::Hash::NamedCapture' if !$PERL514; # dynamic since 5.14
8084             #push @pkg, 'DynaLoader' if $Config{usedl};
8085             # Win32CORE only in official cygwin pkg. And it needs to be bootstrapped,
8086             # handled by static_ext.
8087 0 0       0 push @pkg, 'Cygwin' if $^O eq 'cygwin';
8088 0 0       0 push @pkg, 'NetWare' if $^O eq 'NetWare';
8089 0 0       0 push @pkg, 'OS2' if $^O eq 'os2';
8090 0 0       0 push @pkg, qw(VMS VMS::Filespec vmsish) if $^O eq 'VMS';
8091             #push @pkg, 'PerlIO' if $] >= 5.008006; # get_layers only
8092 0         0 push @pkg, split(/ /,$Config{static_ext});
8093 0         0 return @pkg;
8094             }
8095              
8096             sub skip_pkg {
8097 0     0 0 0 my $package = shift;
8098 0 0 0     0 if ( $package =~ /^(main::)?(Internals|O)::/
      0        
      0        
      0        
      0        
      0        
      0        
      0        
8099             #or $package =~ /::::/ # CORE/base/lex.t 54
8100             or $package =~ /^B::C::/
8101             or $package eq '__ANON__'
8102             or index($package, " ") != -1 # XXX skip invalid package names
8103             or index($package, "(") != -1 # XXX this causes the compiler to abort
8104             or index($package, ")") != -1 # XXX this causes the compiler to abort
8105             or exists $skip_package{$package}
8106             or ($DB::deep and $package =~ /^(DB|Term::ReadLine)/)) {
8107 0         0 return 1;
8108             }
8109 0         0 return 0;
8110             }
8111              
8112             # Do not delete/ignore packages which were brought in from the script,
8113             # i.e. not defined in B::C or O. Just to be on the safe side.
8114             sub can_delete {
8115 0     0 0 0 my $pkg = shift;
8116 0 0 0     0 if (exists $all_bc_deps{$pkg} and $B::C::can_delete_pkg) { return 1 };
  0         0  
8117 0         0 return undef;
8118             }
8119              
8120             sub should_save {
8121 55     55   244 no strict qw(vars refs);
  55         74  
  55         20214  
8122 0     0 0 0 my $package = shift;
8123 0         0 $package =~ s/::$//;
8124 0 0       0 if ( skip_pkg($package) ) {
8125 0 0       0 delete_unsaved_hashINC($package) if can_delete($package);
8126 0         0 return 0;
8127             }
8128 0 0       0 return $include_package{$package} = 0
8129             if ( $package =~ /::::/ ); # skip ::::ISA::CACHE etc.
8130 0 0       0 warn "Considering $package\n" if $debug{pkg}; #$include_package{$package}
8131 0 0       0 return if index($package, " ") != -1; # XXX skip invalid package names
8132 0 0       0 return if index($package, "(") != -1; # XXX this causes the compiler to abort
8133 0 0       0 return if index($package, ")") != -1; # XXX this causes the compiler to abort
8134             # core static mro has exactly one member, ext/mro has more
8135 0 0       0 if ($package eq 'mro') {
8136             # B::C is setting %mro:: to 3, make sure we have at least 10
8137 0 0       0 if (!is_using_mro()) { # core or ext?
8138 0 0       0 warn "ext/mro not loaded - skip\n" if $debug{pkg};
8139 0         0 return;
8140             } else {
8141 0 0       0 warn "ext/mro already loaded\n" if $debug{pkg};
8142             # $include_package{mro} = 1 if grep { $_ eq 'mro' } @DynaLoader::dl_modules;
8143 0         0 return $include_package{mro};
8144             }
8145             }
8146 0 0 0     0 if ($package eq 'attributes' and $] > 5.011
      0        
8147 0         0 and grep { $_ eq 'attributes' } @DynaLoader::dl_modules)
8148             {
8149 0         0 mark_package($package, 1);
8150 0         0 return 1;
8151             }
8152 0 0       0 if (exists $all_bc_deps{$package}) {
8153 0         0 foreach my $u ( grep( $include_package{$_}, sort keys %include_package ) ) {
8154             # If this package is a prefix to something we are saving, traverse it
8155             # but do not mark it for saving if it is not already
8156             # e.g. to get to B::OP we need to traverse B:: but need not save B
8157 0         0 my $p = $package;
8158 0         0 $p =~ s/(\W)/\\$1/g;
8159 0 0 0     0 return 1 if ( $u =~ /^$p\:\:/ ) && $include_package{$package};
8160             }
8161             }
8162             # Needed since 5.12.2: Check already if deleted
8163 0         0 my $incpack = inc_packname($package);
8164 0 0 0     0 if ( $] > 5.015001 and exists $all_bc_deps{$package}
      0        
      0        
8165             and !exists $curINC{$incpack} and $savINC{$incpack} ) {
8166 0         0 $include_package{$package} = 0;
8167 0 0       0 warn "Cached $package not in \%INC, already deleted (early)\n" if $debug{pkg};
8168 0         0 return 0;
8169             }
8170             # issue348: only drop B::C packages, not any from user code.
8171 0 0 0     0 if (($package =~ /^DynaLoader|XSLoader$/ and $use_xsloader)
      0        
8172             or (!exists $all_bc_deps{$package})) {
8173 0         0 $include_package{$package} = 1;
8174             }
8175             # If this package is in the same file as main:: or our source, save it. (72, 73)
8176 0 0       0 if ($mainfile) {
8177             # Find the first cv in this package for CV->FILE
8178 55     55   251 no strict 'refs';
  55         76  
  55         52780  
8179 0         0 for my $sym (sort keys %{$package.'::'}) {
  0         0  
8180 0 0       0 if (defined &{$package.'::'.$sym}) {
  0         0  
8181             # compare cv->FILE to $mainfile
8182 0         0 my $cv = svref_2object(\&{$package.'::'.$sym});
  0         0  
8183 0 0 0     0 if ($cv and $cv->can('FILE') and $cv->FILE) {
      0        
8184 0 0       0 $include_package{$package} = 1 if $mainfile eq $cv->FILE;
8185 0         0 last;
8186             }
8187             }
8188             }
8189             }
8190             # add overloaded but otherwise empty packages (#172)
8191 0 0 0     0 if ($savINC{'overload.pm'} and exists ${$package.'::'}{OVERLOAD} and exists ${$package.'::'}{'()'}) {
  0   0     0  
  0         0  
8192 0         0 mark_package($package, 1);
8193 0         0 mark_package('overload', 1);
8194 0         0 return 1;
8195             }
8196             # Omit the packages which we use (and which cause grief
8197             # because of fancy "goto &$AUTOLOAD" stuff).
8198             # XXX Surely there must be a nicer way to do this.
8199 0 0       0 if ( exists $include_package{$package} ) {
8200 0 0       0 if (! exists $all_bc_deps{$package}) {
    0          
8201 0         0 $include_package{$package} = 1;
8202 0         0 $curINC{$incpack} = $savINC{$incpack};
8203 0 0       0 warn "Cached new $package is kept\n" if $debug{pkg};
8204             }
8205             elsif (!$include_package{$package}) {
8206 0 0       0 delete_unsaved_hashINC($package) if can_delete($package);
8207 0 0       0 warn "Cached $package is already deleted\n" if $debug{pkg};
8208             } else {
8209 0 0       0 warn "Cached $package is cached\n" if $debug{pkg};
8210             }
8211 0         0 return $include_package{$package};
8212             }
8213              
8214             # Now see if current package looks like an OO class. This is probably too strong.
8215 0 0       0 if (!$all_bc_deps{$package}) {
8216 0         0 foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE)) {
8217             # 5.10 introduced version and Regexp::DESTROY, which we dont want automatically.
8218             # XXX TODO This logic here is wrong and unstable. Fixes lead to more failures.
8219             # The walker deserves a rewrite.
8220 0 0 0     0 if ( UNIVERSAL::can( $package, $m ) and $package !~ /^(B::C|version|Regexp|utf8|SelectSaver)$/ ) {
8221 0 0 0     0 next if $package eq 'utf8' and $m eq 'DESTROY'; # utf8::DESTROY is empty
8222             # we load Errno by ourself to avoid double Config warnings [perl #]
8223             # and we have special logic to detect and include it
8224 0 0 0     0 next if $package =~ /^(Errno|Tie::Hash::NamedCapture)$/ and $m eq 'TIEHASH';
8225             # XXX Config and FileHandle should not just return. If unneeded skip em.
8226 0 0 0     0 return 0 if $package eq 'Config' and $m =~ /DESTROY|TIEHASH/; # Config detected in GV
8227             # IO::File|IO::Handle added for B::CC only
8228 0 0 0     0 return 0 if $package =~ /^(FileHandle|IO::File|IO::Handle)/ and $m eq 'new';
8229 0 0       0 warn "$package has method $m: saving package\n" if $debug{pkg};
8230 0         0 return mark_package($package);
8231             }
8232             }
8233             }
8234 0 0 0     0 if ($package !~ /^PerlIO/ and can_delete($package)) {
8235 0         0 delete_unsaved_hashINC($package);
8236             }
8237 0 0       0 if (can_delete($package)) {
    0          
8238 0 0       0 warn "Delete $package\n" if $debug{pkg};
8239 0         0 return $include_package{$package} = 0;
8240             } elsif (! exists $all_bc_deps{$package}) { # and not in @deps
8241 0 0       0 warn "Keep $package\n" if $debug{pkg};
8242 0         0 return $include_package{$package} = 1;
8243             } else { # in @deps
8244             # warn "Ignore $package\n" if $debug{pkg};
8245 0         0 return;
8246             }
8247             }
8248              
8249             sub inc_packname {
8250 225     225 0 174 my $package = shift;
8251             # See below at the reverse packname_inc: utf8 => utf8.pm + utf8_heavy.pl
8252 225         457 $package =~ s/\:\:/\//g;
8253 225         193 $package .= '.pm';
8254 225         241 return $package;
8255             }
8256              
8257             sub packname_inc {
8258 0     0 0 0 my $package = shift;
8259 0         0 $package =~ s/\//::/g;
8260 0 0       0 if ($package =~ /^(Config_git\.pl|Config_heavy.pl)$/) {
8261 0         0 return 'Config';
8262             }
8263 0 0       0 if ($package eq 'utf8_heavy.pl') {
8264 0         0 return 'utf8';
8265             }
8266 0         0 $package =~ s/\.p[lm]$//;
8267 0         0 return $package;
8268             }
8269              
8270             sub delete_unsaved_hashINC {
8271 225     225 0 171 my $package = shift;
8272 225         254 my $incpack = inc_packname($package);
8273             # Not already saved package, so it is not loaded again at run-time.
8274 225 50       465 return if $dumped_package{$package};
8275             # Never delete external packages, but this check is done before
8276 225 0 33     893 return if $package =~ /^DynaLoader|XSLoader$/
      33        
8277             and defined $use_xsloader
8278             and $use_xsloader == 0;
8279 225 50 33     449 return if $^O eq 'MSWin32' and $package =~ /^Carp|File::Basename$/;
8280 225         337 $include_package{$package} = 0;
8281 225 50       328 if ($curINC{$incpack}) {
8282             #warn "Deleting $package from \%INC\n" if $debug{pkg};
8283 0 0       0 $savINC{$incpack} = $curINC{$incpack} if !$savINC{$incpack};
8284 0         0 $curINC{$incpack} = undef;
8285 0         0 delete $curINC{$incpack};
8286             }
8287             }
8288              
8289             sub add_hashINC {
8290 0     0 0 0 my $package = shift;
8291 0         0 my $incpack = inc_packname($package);
8292 0         0 $include_package{$package} = 1;
8293 0 0       0 unless ($curINC{$incpack}) {
8294 0 0       0 if ($savINC{$incpack}) {
8295 0 0       0 warn "Adding $package to \%INC (again)\n" if $debug{pkg};
8296 0         0 $curINC{$incpack} = $savINC{$incpack};
8297             # need to check xsub
8298 0 0       0 $use_xsloader = 1 if $package =~ /^DynaLoader|XSLoader$/;
8299             } else {
8300 0 0       0 warn "Adding $package to \%INC\n" if $debug{pkg};
8301 0         0 for (@INC) {
8302 0         0 my $p = $_.'/'.$incpack;
8303 0 0       0 if (-e $p) { $curINC{$incpack} = $p; last; }
  0         0  
  0         0  
8304             }
8305 0 0       0 $curINC{$incpack} = $incpack unless $curINC{$incpack};
8306             }
8307             }
8308             }
8309              
8310             sub walkpackages {
8311 0     0 0 0 my ( $symref, $recurse, $prefix ) = @_;
8312 55     55   265 no strict 'vars';
  55         81  
  55         10165  
8313 0 0       0 $prefix = '' unless defined $prefix;
8314             # check if already deleted - failed since 5.15.2
8315 0 0       0 return if $savINC{inc_packname(substr($prefix,0,-2))};
8316 0         0 for my $sym (sort keys %$symref) {
8317 0         0 my $ref = $symref->{$sym};
8318 0 0       0 next unless $ref;
8319 0         0 local (*glob);
8320 0         0 *glob = $ref;
8321 0 0       0 if ( $sym =~ /::$/ ) {
8322 0         0 $sym = $prefix . $sym;
8323 0 0 0     0 warn("Walkpackages $sym\n") if $debug{pkg} and $debug{walk};
8324             # This walker skips main subs to avoid recursion into O compiler subs again
8325             # and main syms are already handled
8326 0 0 0     0 if ( $sym ne "main::" && $sym ne "::" && &$recurse($sym) ) {
      0        
8327 0         0 walkpackages( \%glob, $recurse, $sym );
8328             }
8329             }
8330             }
8331             }
8332              
8333             sub save_unused_subs {
8334 55     55   249 no strict qw(refs);
  55         76  
  55         72372  
8335 0     0 0 0 my %sav_debug;
8336 0 0       0 if ( $debug{unused} ) {
8337 0         0 %sav_debug = %debug;
8338 0         0 %debug = ();
8339             }
8340 0 0       0 my $main = $module ? $module."::" : "main::";
8341              
8342             # -fwalkall: better strategy for compile-time added and required packages:
8343             # loop savecv and check pkg cache for new pkgs.
8344             # if so loop again with those new pkgs only, until the list of new pkgs is empty
8345 0         0 my ($walkall_cnt, @init_unused, @unused, @dumped) = (0);
8346             #do
8347 0         0 @init_unused = grep { $include_package{$_} } keys %include_package;
  0         0  
8348 0 0       0 if ($verbose) {
8349 0 0       0 warn "Prescan for unused subs in $main " . ($sav_debug{unused} ? " (silent)\n" : "\n");
8350             }
8351             # XXX TODO better strategy for compile-time added and required packages:
8352             # loop savecv and check pkg cache for new pkgs.
8353             # if so loop again with those new pkgs only, until the list of new pkgs is empty
8354 0         0 descend_marked_unused();
8355 0 0       0 walkpackages( \%{$main}, \&should_save, $main eq 'main::' ? undef : $main );
  0         0  
8356 0 0       0 warn "Saving unused subs in $main" . ($sav_debug{unused} ? " (silent)\n" : "\n")
    0          
8357             if $verbose;
8358 0         0 walksymtable( \%{$main}, "savecv", \&should_save );
  0         0  
8359 0         0 @unused = grep { $include_package{$_} } keys %include_package;
  0         0  
8360 0 0       0 @dumped = grep { $dumped_package{$_} and $_ ne 'main' } keys %dumped_package;
  0         0  
8361 0 0       0 warn sprintf("old unused: %d, new: %d, dumped: %d\n", scalar @init_unused, scalar @unused, scalar @dumped)
8362             if $verbose;
8363 0 0       0 if (!$B::C::walkall) {
8364 0         0 @unused = @init_unused = ();
8365             } else {
8366 0         0 my $done;
8367 0   0     0 do {
8368 0         0 $done = dump_rest();
8369 0         0 @unused = grep { $include_package{$_} } keys %include_package;
  0         0  
8370 0 0       0 @dumped = grep { $dumped_package{$_} and $_ ne 'main' } keys %dumped_package;
  0         0  
8371             } while @unused > @dumped and $done;
8372 0 0       0 last if $walkall_cnt++ > 3;
8373             }
8374             #} while @unused > @init_unused;
8375              
8376 0 0       0 if ( $sav_debug{unused} ) {
8377 0         0 %debug = %sav_debug;
8378             }
8379              
8380             # If any m//i is run-time loaded we'll get a "Undefined subroutine utf8::SWASHNEW"
8381             # With -fno-fold we don't insist on loading utf8_heavy and Carp.
8382             # Until it is compile-time required.
8383 0 0 0     0 if (exists($INC{'unicore/To/Title.pl'})
      0        
      0        
      0        
      0        
8384             or exists($INC{'unicore/To/Tc.pl'}) #242
8385             or exists($INC{'unicore/Heavy.pl'}) #242
8386             or ($savINC{'utf8_heavy.pl'} and ($B::C::fold or exists($savINC{'utf8.pm'})))) {
8387 0 0       0 require "utf8.pm" unless $savINC{"utf8.pm"};
8388 0         0 mark_package('utf8');
8389 0         0 load_utf8_heavy();
8390             }
8391             # run-time Carp
8392             # With -fno-warnings we don't insist on initializing warnings::register_categories and Carp.
8393             # Until it is compile-time required.
8394             # 68KB exe size 32-bit
8395 0 0 0     0 if ($] >= 5.013005 and ($B::C::warnings and exists $dumped_package{Carp})) {
      0        
8396 0         0 svref_2object( \&{"warnings\::register_categories"} )->save; # 68Kb 32bit
  0         0  
8397 0         0 add_hashINC("warnings");
8398 0         0 add_hashINC("warnings::register");
8399             }
8400             #196 missing INIT
8401 0 0 0     0 if ($xsub{EV} and $dumped_package{EV} and $EV::VERSION le '4.21') {
      0        
8402 0         0 $init2->add_eval
8403             (
8404             q(EV::default_loop() or )
8405             .q(die 'EV: cannot initialise libev backend. bad $ENV{LIBEV_FLAGS}?';)
8406             );
8407             }
8408 0 0       0 if ($use_xsloader) {
8409 0         0 force_saving_xsloader();
8410 0         0 mark_package('Config', 1); # required by Dynaloader and special cased previously
8411             }
8412             }
8413              
8414             sub inc_cleanup {
8415 0     0 0 0 my $rec_cnt = shift;
8416             # %INC sanity check issue 89:
8417             # omit unused, unsaved packages, so that at least run-time require will pull them in.
8418 0         0 my @deleted_inc;
8419 0 0       0 if ($CPERL51) {
8420 0         0 for (qw(strict coretypes DynaLoader XSLoader)) {
8421 0         0 $dumped_package{$_}++;
8422 0         0 $curINC{$_.".pm"} = $INC{$_.".pm"};
8423             }
8424             }
8425 0         0 for my $package (sort keys %INC) {
8426 0         0 my $pkg = packname_inc($package);
8427 0 0 0     0 if ($package =~ /^(Config_git\.pl|Config_heavy.pl)$/ and !$dumped_package{'Config'}) {
    0 0        
    0 0        
8428 0         0 delete $curINC{$package};
8429             } elsif ($package eq 'utf8_heavy.pl' and !$include_package{'utf8'}) {
8430 0         0 delete $curINC{$package};
8431 0         0 delete_unsaved_hashINC('utf8');
8432             } elsif (!$B::C::walkall and !exists $dumped_package{$pkg}) {
8433 0         0 delete_unsaved_hashINC($pkg);
8434 0         0 push @deleted_inc, $pkg;
8435             }
8436             }
8437             # sync %curINC deletions back to %INC
8438 0         0 for my $p (sort keys %INC) {
8439 0 0       0 if (!exists $curINC{$p}) {
8440 0         0 delete $INC{$p};
8441 0         0 push @deleted_inc, $p;
8442             }
8443             }
8444 0 0 0     0 if ($debug{pkg} and $verbose) {
8445 0         0 warn "\%include_package: ".join(" ",grep{$include_package{$_}} sort keys %include_package)."\n";
  0         0  
8446 0         0 warn "\%dumped_package: ".join(" ",grep{$dumped_package{$_}} sort keys %dumped_package)."\n";
  0         0  
8447             }
8448             # issue 340,350: do only on -fwalkall? do it in the main walker step
8449             # as in branch walkall-early?
8450 0 0       0 if ($B::C::walkall) {
8451 0         0 my $again = dump_rest();
8452 0 0 0     0 inc_cleanup($rec_cnt++) if $again and $rec_cnt < 2; # maximal 3 times
8453             }
8454             # final cleanup
8455 0         0 for my $p (sort keys %INC) {
8456 0         0 my $pkg = packname_inc($p);
8457 0 0       0 delete_unsaved_hashINC($pkg) unless exists $dumped_package{$pkg};
8458             # sync %curINC deletions back to %INC
8459 0 0 0     0 if (!exists $curINC{$p} and exists $INC{$p}) {
8460 0         0 delete $INC{$p};
8461 0         0 push @deleted_inc, $p;
8462             }
8463             }
8464 0 0 0     0 if ($debug{pkg} and $verbose) {
8465 0 0       0 warn "Deleted from \%INC: ".join(" ",@deleted_inc)."\n" if @deleted_inc;
8466 0         0 my @inc = grep !/auto\/.+\.(al|ix)$/, sort keys %INC;
8467 0         0 warn "\%INC: ".join(" ",@inc)."\n";
8468             }
8469             }
8470              
8471             sub dump_rest {
8472 0     0 0 0 my $again;
8473 0 0 0     0 warn "dump_rest:\n" if $verbose or $debug{pkg};
8474             #for my $p (sort keys %INC) {
8475             #}
8476 0         0 for my $p (sort keys %include_package) {
8477 0         0 $p =~ s/^main:://;
8478 0 0 0     0 if ($include_package{$p} and !exists $dumped_package{$p}
      0        
      0        
8479             and !$static_core_pkg{$p}
8480             and $p !~ /^(threads|main|__ANON__|PerlIO)$/
8481             )
8482             {
8483 0 0 0     0 if ($p eq 'warnings::register' and !$B::C::warnings) {
8484 0         0 delete_unsaved_hashINC('warnings::register');
8485 0         0 next;
8486             }
8487 0         0 $again++;
8488 0 0 0     0 warn "$p marked but not saved, save now\n" if $verbose or $debug{pkg};
8489             # mark_package( $p, 1);
8490             #eval {
8491             # require(inc_packname($p)) && add_hashINC( $p );
8492             #} unless $savINC{inc_packname($p)};
8493 0         0 walk_syms( $p );
8494             }
8495             }
8496 0         0 $again;
8497             }
8498              
8499             my @made_c3;
8500              
8501             sub make_c3 {
8502 0 0   0 0 0 my $package = shift or die;
8503              
8504 0 0       0 return if ( grep { $_ eq $package } @made_c3 );
  0         0  
8505 0         0 push @made_c3, $package;
8506              
8507 0         0 mark_package( 'mro', 1 );
8508 0         0 mark_package($package);
8509 0   0     0 my $isa_packages = mro::get_linear_isa($package) || [];
8510 0         0 foreach my $isa (@$isa_packages) {
8511 0         0 mark_package($isa);
8512             }
8513 0 0 0     0 warn "set c3 for $package\n" if $verbose or $debug{pkg};
8514              
8515             ## from setmro.xs:
8516             # classname = ST(0);
8517             # class_stash = gv_stashsv(classname, GV_ADD);
8518             # meta = HvMROMETA(class_stash);
8519             # Perl_mro_set_mro(aTHX_ meta, ST(1));
8520              
8521 0         0 $init2->add( sprintf( 'Perl_mro_set_mro(aTHX_ HvMROMETA(%s), newSVpvs("c3"));',
8522             savestashpv($package) ) );
8523             }
8524              
8525             # global state only, unneeded for modules
8526             sub save_context {
8527             # forbid run-time extends of curpad syms, names and INC
8528 0 0   0 0 0 warn "save context:\n" if $verbose;
8529 0         0 my $warner = $SIG{__WARN__};
8530 0 0       0 save_sig($warner) if $B::C::save_sig;
8531             # honour -w and %^H
8532 0         0 $init->add( "/* honor -w */",
8533             sprintf "PL_dowarn = ( %s ) ? G_WARN_ON : G_WARN_OFF;", $^W );
8534 0 0       0 if ($^{TAINT}) {
8535             $init->add( "/* honor -Tt */",
8536             "PL_tainting = TRUE;",
8537             # -T -1 false, -t 1 true
8538 0 0       0 "PL_taint_warn = ".($^{TAINT} < 0 ? "FALSE" : "TRUE").";");
8539             }
8540              
8541 0 0       0 if ($PERL510) {
8542             # need to mark assign c3 to %main::. no need to assign the default dfs
8543 0 0 0     0 if (is_using_mro() && mro::get_mro("main") eq 'c3') {
8544 0         0 make_c3('main');
8545             }
8546             # Tie::Hash::NamedCapture is added for *+ *-, Errno for *!
8547             #no strict 'refs';
8548             #if ( defined(objsym(svref_2object(\*{'main::+'}))) or defined(objsym(svref_2object(\*{'main::-'}))) ) {
8549             # use strict 'refs';
8550             # if (!$include_package{'Tie::Hash::NamedCapture'}) {
8551             # $init->add("/* force saving of Tie::Hash::NamedCapture */");
8552             # if ($] >= 5.014) {
8553             # mark_package('Config', 1); # DynaLoader needs Config to set the EGV
8554             # walk_syms('Config');
8555             # svref_2object(\&{'Tie::Hash::NamedCapture::bootstrap'})->save;
8556             # }
8557             # mark_package('Tie::Hash::NamedCapture', 1);
8558             # } # else already included
8559             #} else {
8560             # use strict 'refs';
8561             # delete_unsaved_hashINC('Tie::Hash::NamedCapture');
8562             #}
8563 55     55   275 no strict 'refs';
  55         74  
  55         2933  
8564 0 0       0 if ( defined(objsym(svref_2object(\*{'main::!'}))) ) {
  0         0  
8565 55     55   221 use strict 'refs';
  55         69  
  55         3768  
8566 0 0       0 if (!$include_package{'Errno'}) {
8567 0         0 $init->add("/* force saving of Errno */");
8568 0         0 mark_package('Config', 1);
8569 0         0 walk_syms('Config');
8570 0         0 mark_package('Errno', 1);
8571 0         0 svref_2object(\&{'Errno::bootstrap'})->save;
  0         0  
8572             } # else already included
8573             } else {
8574 55     55   205 use strict 'refs';
  55         79  
  55         9878  
8575 0         0 delete_unsaved_hashINC('Errno');
8576             }
8577             }
8578              
8579 0         0 my ($curpad_nam, $curpad_sym);
8580             {
8581             # Record comppad sv's names, may not be static
8582 0         0 local $B::C::const_strings = 0;
  0         0  
8583 0         0 $init->add("/* curpad names */");
8584 0 0       0 warn "curpad names:\n" if $verbose;
8585 0         0 $curpad_nam = ( comppadlist->ARRAY )[0]->save('curpad_name');
8586 0 0       0 warn "curpad syms:\n" if $verbose;
8587 0         0 $init->add("/* curpad syms */");
8588 0         0 $curpad_sym = ( comppadlist->ARRAY )[1]->save('curpad_syms');
8589             }
8590 0         0 my ($inc_hv, $inc_av);
8591             {
8592 0 0       0 local $B::C::const_strings = 1 if $B::C::ro_inc;
  0         0  
8593 0 0       0 warn "\%INC and \@INC:\n" if $verbose;
8594 0         0 $init->add('/* %INC */');
8595 0         0 inc_cleanup(0);
8596 0         0 my $inc_gv = svref_2object( \*main::INC );
8597 0         0 $inc_hv = $inc_gv->HV->save('main::INC');
8598 0         0 $init->add('/* @INC */');
8599 0         0 $inc_av = $inc_gv->AV->save('main::INC');
8600             }
8601             # ensure all included @ISA's are stored (#308), and also assign c3 (#325)
8602 0         0 my @saved_isa;
8603 0         0 for my $p (sort keys %include_package) {
8604 55     55   215 no strict 'refs';
  55         78  
  55         34627  
8605 0 0 0     0 if ($include_package{$p} and exists(${$p.'::'}{ISA}) and ${$p.'::'}{ISA}) {
  0   0     0  
  0         0  
8606 0         0 push @saved_isa, $p;
8607 0         0 svref_2object( \@{$p.'::ISA'} )->save($p.'::ISA');
  0         0  
8608 0 0 0     0 if ($PERL510 and is_using_mro() && mro::get_mro($p) eq 'c3') {
      0        
8609 0         0 make_c3($p);
8610             }
8611             }
8612             }
8613 0 0 0     0 warn "Saved \@ISA for: ".join(" ",@saved_isa)."\n" if @saved_isa and ($verbose or $debug{pkg});
      0        
8614 0         0 $init->add(
8615             "GvHV(PL_incgv) = $inc_hv;",
8616             "GvAV(PL_incgv) = $inc_av;",
8617             "PL_curpad = AvARRAY($curpad_sym);",
8618             "PL_comppad = $curpad_sym;", # fixed "panic: illegal pad"
8619             "PL_stack_sp = PL_stack_base;" # reset stack (was 1++)
8620             );
8621 0 0       0 if ($] < 5.017005) {
    0          
    0          
8622 0         0 $init->add(
8623             "av_store((AV*)CvPADLIST(PL_main_cv), 0, SvREFCNT_inc_simple_NN($curpad_nam)); /* namepad */",
8624             "av_store((AV*)CvPADLIST(PL_main_cv), 1, SvREFCNT_inc_simple_NN($curpad_sym)); /* curpad */");
8625             } elsif ($] < 5.019003) {
8626 0         0 $init->add(
8627             "PadlistARRAY(CvPADLIST(PL_main_cv))[0] = PL_comppad_name = (PAD*)SvREFCNT_inc_simple_NN($curpad_nam); /* namepad */",
8628             "PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)SvREFCNT_inc_simple_NN($curpad_sym); /* curpad */");
8629             } elsif ($] < 5.022) {
8630 0         0 $init->add(
8631             "PadlistARRAY(CvPADLIST(PL_main_cv))[0] = PL_comppad_name = (PAD*)SvREFCNT_inc_simple_NN($curpad_nam); /* namepad */",
8632             "PadnamelistMAXNAMED(PL_comppad_name) = AvFILL($curpad_nam);",
8633             "PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)SvREFCNT_inc_simple_NN($curpad_sym); /* curpad */");
8634             } else {
8635 0         0 $init->add(
8636             "PadlistNAMES(CvPADLIST(PL_main_cv)) = PL_comppad_name = $curpad_nam; /* namepad */",
8637             "PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)$curpad_sym; /* curpad */");
8638             }
8639 0 0       0 if ($] < 5.017) {
8640 0         0 my $amagic_generate = B::amagic_generation();
8641 0 0       0 warn "amagic_generation = $amagic_generate\n" if $verbose;
8642 0         0 $init->add("PL_amagic_generation = $amagic_generate;");
8643             };
8644             }
8645              
8646             sub descend_marked_unused {
8647             #if ($B::C::walkall) {
8648             # for my $pack (keys %all_bc_deps) {
8649             # mark_unused($pack, 0) if !exists $include_package{$pack} and !skip_pkg($pack);
8650             # }
8651             #}
8652 0     0 0 0 foreach my $pack ( sort keys %INC ) {
8653 0         0 my $p = packname_inc($pack);
8654 0 0 0     0 mark_package($p) if !skip_pkg($p) and !$all_bc_deps{$p} and $pack !~ /(autosplit\.ix|\.al)$/;
      0        
8655             }
8656 0 0 0     0 if ($debug{pkg} and $verbose) {
8657 0         0 warn "\%include_package: ".join(" ",grep{$include_package{$_}} sort keys %include_package)."\n";
  0         0  
8658 0         0 warn "\%skip_package: ".join(" ",sort keys %skip_package)."\n";
8659             }
8660 0         0 foreach my $pack ( sort keys %include_package ) {
8661 0 0       0 mark_package($pack) unless skip_pkg($pack);
8662             }
8663             warn "descend_marked_unused: "
8664 0 0       0 .join(" ",sort keys %include_package)."\n" if $debug{pkg};
8665             }
8666              
8667             sub save_main {
8668              
8669 0 0   0 0 0 warn "Starting compile\n" if $verbose;
8670 0 0       0 warn "Walking tree\n" if $verbose;
8671 0         0 %Exporter::Cache = (); # avoid B::C and B symbols being stored
8672 0 0       0 _delete_macros_vendor_undefined() if $PERL512;
8673 0         0 set_curcv B::main_cv;
8674 0         0 seek( STDOUT, 0, 0 ); #exclude print statements in BEGIN{} into output
8675 0 0       0 binmode( STDOUT, ':utf8' ) unless $PERL56;
8676            
8677 0 0       0 $verbose
8678             ? walkoptree_slow( main_root, "save" )
8679             : walkoptree( main_root, "save" );
8680 0         0 save_main_rest();
8681             }
8682              
8683             sub _delete_macros_vendor_undefined {
8684 0     0   0 foreach my $class (qw(POSIX IO Fcntl Socket Exporter Errno)) {
8685 55     55   251 no strict 'refs';
  55         90  
  55         1365  
8686 55     55   190 no strict 'subs';
  55         68  
  55         1329  
8687 55     55   204 no warnings 'uninitialized';
  55         76  
  55         136549  
8688 0         0 my $symtab = $class . '::';
8689 0         0 for my $symbol ( sort keys %$symtab ) {
8690 0 0 0     0 next if $symbol !~ m{^[0-9A-Z_]+$} || $symbol =~ m{(?:^ISA$|^EXPORT|^DESTROY|^TIE|^VERSION|^AUTOLOAD|^BEGIN|^INIT|^__|^DELETE|^CLEAR|^STORE|^NEXTKEY|^FIRSTKEY|^FETCH|^EXISTS)};
8691 0 0       0 next if ref $symtab->{$symbol};
8692 0         0 local $@;
8693 0         0 my $code = "$class\:\:$symbol();";
8694 0         0 eval $code;
8695 0 0       0 if ( $@ =~ m{vendor has not defined} ) {
8696 0         0 delete $symtab->{$symbol};
8697 0         0 next;
8698             }
8699             }
8700             }
8701 0         0 return 1;
8702             }
8703              
8704             sub fixup_ppaddr {
8705             # init op addrs must be the last action, otherwise
8706             # some ops might not be initialized
8707             # but it needs to happen before CALLREGCOMP, as a /i calls a compiled utf8::SWASHNEW
8708 0 0   0 0 0 if ($B::C::optimize_ppaddr) {
8709 0         0 foreach my $i (@op_sections) {
8710 0         0 my $section = $$i;
8711 0         0 my $num = $section->index;
8712 0 0       0 next unless $num >= 0;
8713 0         0 init_op_addr( $section->name, $num + 1 );
8714             }
8715             }
8716             }
8717              
8718             # save %SIG ( in case it was set in a BEGIN block )
8719             sub save_sig {
8720             # local $SIG{__WARN__} = shift;
8721 0     0 0 0 $init->no_split;
8722 0         0 my @save_sig;
8723 0         0 foreach my $k ( sort keys %SIG ) {
8724 0 0       0 next unless ref $SIG{$k};
8725 0         0 my $cvref = svref_2object( \$SIG{$k} );
8726 0 0 0     0 next if ref($cvref) eq 'B::CV' and $cvref->FILE =~ m|B/C\.pm$|; # ignore B::C SIG warn handler
8727 0         0 push @save_sig, [$k, $cvref];
8728             }
8729 0 0       0 unless (@save_sig) {
8730 0 0       0 $init->add( "/* no %SIG in BEGIN block */" ) if $verbose;
8731 0 0       0 warn "no %SIG in BEGIN block\n" if $verbose;
8732 0         0 return;
8733             }
8734 0 0       0 $init->add( "/* save %SIG */" ) if $verbose;
8735 0 0       0 warn "save %SIG\n" if $verbose;
8736 0         0 $init->add( "{", "\tHV* hv = get_hvs(\"main::SIG\", GV_ADD);" );
8737 0         0 foreach my $x ( @save_sig ) {
8738 0         0 my ($k, $cvref) = @$x;
8739 0         0 my $sv = $cvref->save;
8740 0         0 my ($cstring, $cur, $utf8) = strlen_flags($k);
8741 0         0 $init->add( '{', sprintf "\t".'SV* sv = (SV*)%s;', $sv );
8742 0         0 $init->add( sprintf("\thv_store(hv, %s, %u, %s, %d);",
8743             $cstring, $cur, 'sv', 0 ) );
8744 0         0 $init->add( "\t".'mg_set(sv);', '}' );
8745             }
8746 0         0 $init->add('}');
8747 0         0 $init->split;
8748             }
8749              
8750             sub force_saving_xsloader {
8751 0     0 0 0 mark_package("XSLoader", 1);
8752             # mark_package("DynaLoader", 1);
8753 0 0       0 if ($] < 5.015003) {
    0          
8754 0         0 $init->add("/* force saving of XSLoader::load */");
8755 0         0 eval { XSLoader::load; };
  0         0  
8756             # does this really save the whole packages?
8757 0         0 $dumped_package{XSLoader} = 1;
8758 0         0 svref_2object( \&XSLoader::load )->save;
8759             } elsif ($CPERL51) {
8760 0         0 $init->add("/* XSLoader::load_file already builtin into cperl */");
8761 0         0 $dumped_package{XSLoader} = 1;
8762 0         0 $dumped_package{DynaLoader} = 1;
8763 0         0 add_hashINC("XSLoader"); # builtin
8764             } else {
8765 0         0 $init->add("/* custom XSLoader::load_file */");
8766             # does this really save the whole packages?
8767 0         0 $dumped_package{DynaLoader} = 1;
8768 0         0 svref_2object( \&XSLoader::load_file )->save;
8769 0         0 svref_2object( \&DynaLoader::dl_load_flags )->save; # not saved as XSUB constant?
8770             }
8771 0 0       0 add_hashINC("XSLoader") if $] < 5.015003;
8772 0         0 add_hashINC("DynaLoader");
8773 0         0 $use_xsloader = 0; # do not load again
8774             }
8775              
8776             sub save_main_rest {
8777             # this is mainly for the test suite
8778             # local $SIG{__WARN__} = sub { print STDERR @_ } unless $debug{runtime};
8779              
8780             warn "done main optree, walking symtable for extras\n"
8781 0 0 0 0 0 0 if $verbose or $debug{cv};
8782 0         0 $init->add("");
8783 0         0 $init->add("/* done main optree, extra subs which might be unused */");
8784 0         0 save_unused_subs();
8785 0         0 $init->add("/* done extras */");
8786              
8787             # startpoints: XXX TODO push BEGIN/END blocks to modules code.
8788 0 0       0 warn "Writing init_av\n" if $debug{av};
8789 0         0 my $init_av = init_av->save('INIT');
8790 0         0 my $end_av;
8791             {
8792             # >=5.10 need to defer nullifying of all vars in END, not only new ones.
8793 0         0 local ($B::C::pv_copy_on_grow, $B::C::const_strings);
  0         0  
8794 0         0 $in_endav = 1;
8795 0 0       0 warn "Writing end_av\n" if $debug{av};
8796 0         0 $init->add("/* END block */");
8797 0         0 $end_av = end_av->save('END');
8798 0         0 $in_endav = 0;
8799             }
8800 0 0       0 if ( !defined($module) ) {
8801             $init->add(
8802             "/* startpoints */",
8803 0         0 sprintf( "PL_main_root = s\\_%x;", ${ main_root() } ),
8804 0         0 sprintf( "PL_main_start = s\\_%x;", ${ main_start() } ),
  0         0  
8805             );
8806 0 0       0 $init->add(index($init_av,'(AV*)')>=0
8807             ? "PL_initav = $init_av;"
8808             : "PL_initav = (AV*)$init_av;");
8809 0 0       0 $init->add(index($end_av,'(AV*)')>=0
8810             ? "PL_endav = $end_av;"
8811             : "PL_endav = (AV*)$end_av;");
8812             }
8813 0 0       0 save_context() unless defined($module);
8814             # warn "use_xsloader=$use_xsloader\n" if $verbose;
8815             # If XSLoader was forced later, e.g. in curpad, INIT or END block
8816 0 0       0 force_saving_xsloader() if $use_xsloader;
8817              
8818 0 0       0 return if $check;
8819 0 0       0 warn "Writing output\n" if $verbose;
8820 0         0 output_boilerplate();
8821              
8822             # add static modules like " Win32CORE"
8823 0         0 foreach my $stashname ( split /\s+/, $Config{static_ext} ) {
8824 0 0       0 next if $stashname =~ /^\s*$/; # often a leading space
8825 0         0 $static_ext{$stashname}++;
8826 0         0 my $stashxsub = $stashname;
8827 0         0 $stashxsub =~ s/::/__/g;
8828 0         0 print "EXTERN_C void boot_$stashxsub (pTHX_ CV* cv);\n";
8829             }
8830 0         0 print "\n";
8831 0   0     0 output_all($init_name || "perl_init");
8832 0         0 print "\n";
8833 0         0 output_main_rest();
8834              
8835 0 0       0 if ( defined($module) ) {
8836 0 0       0 my $cmodule = $module ? $module : "main";
8837 0         0 $cmodule =~ s/::/__/g;
8838              
8839 0         0 my $start = "op_list[0]";
8840 0 0       0 warn "curpad syms:\n" if $verbose;
8841 0         0 $init->add("/* curpad syms */");
8842 0         0 my $curpad_sym = ( comppadlist->ARRAY )[1]->save;
8843              
8844 0         0 print <<"EOT";
8845              
8846             #include "XSUB.h"
8847             XS(boot_$cmodule)
8848             {
8849             dXSARGS;
8850             perl_init();
8851             ENTER;
8852             SAVETMPS;
8853             SAVEVPTR(PL_curpad);
8854             SAVEVPTR(PL_op);
8855             dl_init(aTHX);
8856             PL_curpad = AvARRAY($curpad_sym);
8857             PL_comppad = $curpad_sym;
8858             PL_op = $start;
8859             perl_run( aTHX ); /* Perl_runops_standard(aTHX); */
8860             FREETMPS;
8861             LEAVE;
8862             ST(0) = &PL_sv_yes;
8863             XSRETURN(1);
8864             }
8865             EOT
8866              
8867             } else {
8868 0         0 output_main();
8869             }
8870             }
8871              
8872             sub init_sections {
8873 0     0 0 0 my @sections = (
8874             decl => \$decl,
8875             init0 => \$init0,
8876             free => \$free,
8877             sym => \$symsect,
8878             hek => \$heksect,
8879             binop => \$binopsect,
8880             condop => \$condopsect,
8881             cop => \$copsect,
8882             padop => \$padopsect,
8883             listop => \$listopsect,
8884             logop => \$logopsect,
8885             loop => \$loopsect,
8886             op => \$opsect,
8887             pmop => \$pmopsect,
8888             pvop => \$pvopsect,
8889             svop => \$svopsect,
8890             unop => \$unopsect,
8891             unopaux => \$unopauxsect,
8892             methop => \$methopsect,
8893             sv => \$svsect,
8894             xpv => \$xpvsect,
8895             xpvav => \$xpvavsect,
8896             xpvhv => \$xpvhvsect,
8897             xpvcv => \$xpvcvsect,
8898             xpviv => \$xpvivsect,
8899             xpvuv => \$xpvuvsect,
8900             xpvnv => \$xpvnvsect,
8901             xpvmg => \$xpvmgsect,
8902             xpvlv => \$xpvlvsect,
8903             xrv => \$xrvsect,
8904             xpvbm => \$xpvbmsect,
8905             xpvio => \$xpviosect,
8906             padlist => \$padlistsect,
8907             padnamelist => \$padnlsect,
8908             padname => \$padnamesect,
8909             );
8910 0 0       0 if ($PERL522) {
8911 0         0 pop @sections;
8912             }
8913 0         0 my ( $name, $sectref );
8914 0         0 while ( ( $name, $sectref ) = splice( @sections, 0, 2 ) ) {
8915 0         0 $$sectref = new B::C::Section $name, \%symtable, 0;
8916             }
8917 0 0       0 if ($PERL522) {
8918 0         0 for my $size (@padnamesect_sizes) {
8919 0         0 my $name = "padname_$size";
8920 0         0 $padnamesect{$size} = new B::C::Section $name, \%symtable, 0;
8921             }
8922             }
8923 0         0 $init = new B::C::InitSection 'init', \%symtable, 0;
8924 0         0 $init1 = new B::C::InitSection 'init1', \%symtable, 0;
8925 0         0 $init2 = new B::C::InitSection 'init2', \%symtable, 0;
8926 0         0 %savINC = %curINC = %INC;
8927             }
8928              
8929             sub mark_unused {
8930 0     0 0 0 my ( $pkg, $val ) = @_;
8931 0         0 $include_package{$pkg} = $val;
8932             }
8933              
8934             sub mark_skip {
8935 15     15 0 50 for (@_) {
8936 225         269 delete_unsaved_hashINC($_);
8937             # $include_package{$_} = 0;
8938 225 50       432 $skip_package{$_} = 1 unless $include_package{$_};
8939             }
8940             }
8941              
8942             sub compile {
8943 0     0 0   my @options = @_;
8944             # Allow debugging in CHECK blocks without Od
8945 0 0         $DB::single = 1 if defined &DB::DB;
8946 0           my ( $option, $opt, $arg );
8947 0           my @eval_at_startup;
8948 0           $B::C::can_delete_pkg = 1;
8949 0           $B::C::save_sig = 1;
8950 0           $B::C::destruct = 1;
8951 0           $B::C::stash = 0;
8952 0           $B::C::cow = 0;
8953 0 0         $B::C::fold = 1 if $] >= 5.013009; # always include utf8::Cased tables
8954 0 0         $B::C::warnings = 1 if $] >= 5.013005; # always include Carp warnings categories and B
8955 0 0 0       $B::C::optimize_warn_sv = 1 if $^O ne 'MSWin32' or $Config{cc} !~ m/^cl/i;
8956 0 0         $B::C::dyn_padlist = 1 if $] >= 5.017; # default is dynamic and safe, disable with -O4
8957 0           $B::C::walkall = 1;
8958              
8959 0           mark_skip qw(B::C B::C::Config B::CC B::Asmdata B::FAKEOP O
8960             B::Pseudoreg B::Shadow B::C::InitSection);
8961             #mark_skip('DB', 'Term::ReadLine') if defined &DB::DB;
8962              
8963             OPTION:
8964 0           while ( $option = shift @options ) {
8965 0 0         if ( $option =~ /^-(.)(.*)/ ) {
8966 0           $opt = $1;
8967 0           $arg = $2;
8968             }
8969             else {
8970 0           unshift @options, $option;
8971 0           last OPTION;
8972             }
8973 0 0 0       if ( $opt eq "-" && $arg eq "-" ) {
8974 0           shift @options;
8975 0           last OPTION;
8976             }
8977 0 0         if ( $opt eq "w" ) {
8978 0           $warn_undefined_syms = 1;
8979             }
8980 0 0 0       if ( $opt eq "c" ) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
8981 0           $check = 1;
8982             }
8983             elsif ( $opt eq "D" ) {
8984 0   0       $arg ||= shift @options;
8985 0 0         if ($arg eq 'full') {
    0          
8986 0           $arg = 'OcAHCMGSPpsWF';
8987 0           $all_bc_deps{'B::Flags'}++;
8988             }
8989             elsif ($arg eq 'ufull') {
8990 0           $arg = 'uOcAHCMGSPpsWF';
8991 0           $all_bc_deps{'B::Flags'}++;
8992             }
8993 0           foreach my $arg ( split( //, $arg ) ) {
8994 0 0         if (exists $debug_map{$arg}) {
    0          
    0          
    0          
8995 0           $debug{ $debug_map{$arg} }++;
8996             }
8997             elsif ( $arg eq "o" ) {
8998 0           $verbose++;
8999 0           B->debug(1);
9000             }
9001             elsif ( $arg eq "F" ) {
9002 0 0 0       $debug{flags}++ if $] > 5.008 and eval "require B::Flags;";
9003 0           $all_bc_deps{'B::Flags'}++;
9004             # $debug{flags}++ if require B::Flags;
9005             }
9006             elsif ( $arg eq "r" ) {
9007 0           $debug{runtime}++;
9008             $SIG{__WARN__} = sub {
9009 0     0     warn @_;
9010 0           my $s = join(" ", @_);
9011 0           chomp $s;
9012 0 0         $init->add("/* ".$s." */") if $init;
9013 0           };
9014             }
9015             else {
9016 0           warn "ignoring unknown debug option: $arg\n";
9017             }
9018             }
9019             }
9020             elsif ( $opt eq "o" ) {
9021 0   0       $arg ||= shift @options;
9022 0           $outfile = $arg;
9023 0 0         if ($check) {
9024 0           warn "Warning: -o argument ignored with -c\n";
9025             } else {
9026 0 0         open( STDOUT, ">", $arg ) or return "$arg: $!\n";
9027             }
9028             }
9029             elsif ( $opt eq "s" and $arg eq "taticxs" ) {
9030 0 0         $outfile = "perlcc" unless $outfile;
9031 0           $staticxs = 1;
9032             }
9033             elsif ( $opt eq "n" ) {
9034 0   0       $arg ||= shift @options;
9035 0           $init_name = $arg;
9036             }
9037             elsif ( $opt eq "m" ) {
9038             # $arg ||= shift @options;
9039 0           $module = $arg;
9040 0           mark_unused( $arg, 1 );
9041             }
9042             elsif ( $opt eq "v" ) {
9043 0           $verbose = 1;
9044             }
9045             elsif ( $opt eq "u" ) {
9046 0   0       $arg ||= shift @options;
9047 0 0         if ($arg =~ /\.p[lm]$/) {
9048 0           eval "require(\"$arg\");"; # path as string
9049             } else {
9050 0           eval "require $arg;"; # package as bareword with ::
9051             }
9052 0           mark_unused( $arg, 1 );
9053             }
9054             elsif ( $opt eq "U" ) {
9055 0   0       $arg ||= shift @options;
9056 0           mark_skip( $arg );
9057             }
9058             elsif ( $opt eq "f" ) {
9059 0   0       $arg ||= shift @options;
9060 0           $arg =~ m/(no-)?(.*)/;
9061 0   0       my $no = defined($1) && $1 eq 'no-';
9062 0 0         $arg = $no ? $2 : $arg;
9063 0 0         if ( exists $option_map{$arg} ) {
9064 0           ${ $option_map{$arg} } = !$no;
  0            
9065             }
9066             else {
9067 0           die "Invalid optimization '$arg'";
9068             }
9069             }
9070             elsif ( $opt eq "O" ) {
9071 0 0         $arg = 1 if $arg eq "";
9072 0           my @opt;
9073 0           foreach my $i ( 1 .. $arg ) {
9074 0           push @opt, @{ $optimization_map{$i} }
9075 0 0         if exists $optimization_map{$i};
9076             }
9077 0           unshift @options, @opt;
9078 0 0         warn "options : ".(join " ",@opt)."\n" if $verbose;
9079             }
9080             elsif ( $opt eq "e" ) {
9081 0           push @eval_at_startup, $arg;
9082             }
9083             elsif ( $opt eq "l" ) {
9084 0           $max_string_len = $arg;
9085             }
9086             }
9087 0 0 0       if (!$B::C::Config::have_independent_comalloc) {
    0          
9088 0 0         if ($B::C::av_init2) {
    0          
9089 0           $B::C::av_init = 1;
9090 0           $B::C::av_init2 = 0;
9091             } elsif ($B::C::av_init) {
9092 0           $B::C::av_init2 = 0;
9093             }
9094             } elsif ($B::C::av_init2 and $B::C::av_init) {
9095 0           $B::C::av_init = 0;
9096             }
9097 0 0 0       $B::C::save_data_fh = 1 if $] >= 5.008 and (($] < 5.009004) or $MULTI);
      0        
9098 0 0 0       $B::C::destruct = 1 if $] < 5.008 or $^O eq 'MSWin32'; # skip -ffast-destruct there
9099              
9100 0           init_sections();
9101 0           foreach my $i (@eval_at_startup) {
9102 0           $init2->add_eval($i);
9103             }
9104 0 0         if (@options) { # modules or main?
9105             return sub {
9106 0     0     my $objname;
9107 0           foreach $objname (@options) {
9108 0           eval "save_object(\\$objname)";
9109             }
9110 0   0       output_all($init_name || "init_module");
9111             }
9112 0           }
9113             else {
9114 0     0     return sub { save_main() };
  0            
9115             }
9116             }
9117              
9118             1;
9119              
9120             __END__