File Coverage

blib/lib/B/C.pm
Criterion Covered Total %
statement 187 4460 4.1
branch 15 3654 0.4
condition 5 1932 0.2
subroutine 56 237 23.6
pod 0 97 0.0
total 263 10380 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   5673658 use strict;
  55         82  
  55         6337  
14              
15             our $VERSION = '1.55_02';
16             our (%debug, $check, %Config);
17             BEGIN {
18 55     55   717 require B::C::Config;
19 55         921 *Config = \%B::C::Config::Config;
20 55 50 33     4022 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       4258 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   199 use strict;
  55         60  
  55         43043  
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   381 use strict;
  55         61  
  55         36897  
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   903 use strict;
  55         740  
  55         1774  
279 55     55   479 use Exporter ();
  55         68  
  55         625  
280 55     55   24183 use Errno (); #needed since 5.14
  55         66787  
  55         5373  
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         24335 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   240 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   211 if ($] >= 5.008) {
321 55         6511 @B::NV::ISA = 'B::IV'; # add IVX to nv. This fixes test 23 for Perl 5.8
322 55         2286 B->import(qw(regex_padav SVp_NOK SVp_IOK CVf_CONST CVf_ANON
323             SVf_FAKE)); # both unsupported for 5.6
324 55         2562 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       211 if ($] >= 5.008001) {
343 55         1137 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       128 if ($] >= 5.010) {
349             #require mro; # mro->import();
350             # not exported:
351 0     0 0 0 sub SVf_OOK { 0x02000000 }
352 55         2286 eval q[sub SVs_GMG() { 0x00200000 }
353             sub SVs_SMG() { 0x00400000 }];
354 55 50       172 if ($] >= 5.018) {
    0          
    0          
355 55         978 B->import(qw(PMf_EVAL RXf_EVAL_SEEN));
356 55         1407 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       173 if ($] > 5.021006) {
365 55         1002 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       127 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         780 B->import(qw(SVf_IsCOW));
388             #if (exists ${B::}{PADNAME::}) {
389 55         498 @B::PADNAME::ISA = qw(B::PV);
390             #}
391             #if (exists ${B::}{PADLIST::}) {
392 55         571 @B::PADLIST::ISA = qw(B::AV);
393             #}
394             #if (exists ${B::}{PADNAMELIST::}) {
395 55 50       211 if ($] > 5.021005) { # 5.22
396 55         262 @B::PADNAME::ISA = ();
397 55         446 @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   21855 use B::Asmdata qw(@specialsv_name);
  55         98  
  55         5211  
407              
408 55     55   22997 use FileHandle;
  55         403892  
  55         248  
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, VALID
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 $PERL5257 = ( $CPERL56 or $] >= 5.025007 ); # VALID/TAIL, sibparent, ...
538             my $PERL524 = ( $] >= 5.023005 ); #xpviv sharing assertion
539             my $PERL522 = ( $] >= 5.021006 ); #PADNAMELIST, IsCOW, padname_with_str, compflags
540             my $PERL518 = ( $] >= 5.017010 );
541             my $PERL514 = ( $] >= 5.013002 );
542             my $PERL512 = ( $] >= 5.011 );
543             my $PERL510 = ( $] >= 5.009005 );
544             my $PERL56 = ( $] < 5.008001 ); # yes. 5.8.0 is a 5.6.x
545             #my $C99 = $Config{d_c99_variadic_macros}; # http://docs.sun.com/source/819-3688/c99.app.html#pgfId-1003962
546             my $MAD = $Config{mad};
547             my $MYMALLOC = $Config{usemymalloc} eq 'define';
548             my $HAVE_DLFCN_DLOPEN = $Config{i_dlfcn} && $Config{d_dlopen};
549             # %Lu is not supported on older 32bit systems
550             my $u32fmt = $Config{ivsize} == 4 ? "%lu" : "%u";
551 0 0   0 0 0 sub IS_MSVC () { $^O eq 'MSWin32' and $Config{cc} eq 'cl' }
552             my $have_sibparent = ($PERL5257 or $Config{ccflags} =~ /-DPERL_OP_PARENT/) ? 1 : 0;
553              
554             my @threadsv_names;
555              
556             BEGIN {
557 55     55   48566 @threadsv_names = threadsv_names();
558             # This the Carp free workaround for DynaLoader::bootstrap
559 55 50   0 0 56350 eval 'sub DynaLoader::croak {die @_}' unless $CPERL51;
  0         0  
560             }
561              
562             # needed for init2 remap and Dynamic annotation
563             sub dl_module_to_sofile {
564 0 0   0 0 0 my $module = shift
565             or die 'dl_module_to_sofile($module, $path) missing module name';
566 0 0       0 my $modlibname = shift
567             or die 'dl_module_to_sofile($module, $path): missing module path for '.$module;
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 "dl_module_to_sofile: empty modlibname" 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 105526 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   304 no strict 'refs';
  55         73  
  55         4008  
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   205 no strict 'refs';
  55         67  
  55         17379  
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   229 no strict 'refs';
  55         63  
  55         44844  
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   292 no strict 'refs';
  55         66  
  55         99942  
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   276 no strict 'refs';
  55         94  
  55         99270  
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 69204     69204   3957774 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   304 no strict 'refs';
  55         79  
  55         139903  
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   303 no strict 'refs';
  55         73  
  55         635864  
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 my $pushre = $PERL5257 ? "split" : "pushre";
2582 0 0 0     0 if ($] < 5.008008 and $ITHREADS and $$op < 256) { # B bug. split->first->pmreplroot = 0x1
      0        
2583 0         0 die "Internal B::walkoptree error: invalid PMOP for pushre\n";
2584 0         0 return;
2585             }
2586 0 0       0 $level = 0 unless $level;
2587 0         0 my $replroot = $op->pmreplroot;
2588 0         0 my $replstart = $op->pmreplstart;
2589 0         0 my $ppaddr = $op->ppaddr;
2590              
2591             # under ithreads, OP_PUSHRE.op_replroot is an integer. multi not.
2592 0 0       0 $replrootfield = sprintf( "s\\_%x", $$replroot ) if ref $replroot;
2593 0 0 0     0 if ( $ITHREADS && $op->name eq $pushre ) {
    0 0        
2594 0 0       0 warn "PMOP::save saving a pp_$pushre as int ${replroot}\n" if $debug{gv};
2595 0         0 $replrootfield = "INT2PTR(OP*,${replroot})";
2596             }
2597             elsif (ref $replroot && $$replroot) {
2598             # OP_PUSHRE (a mutated version of OP_MATCH for the regexp
2599             # argument to a split) stores a GV in op_pmreplroot instead
2600             # of a substitution syntax tree. We don't want to walk that...
2601 0 0       0 if ( $op->name eq $pushre ) {
2602 0 0       0 warn "PMOP::save saving a pp_$pushre with GV $gvsym\n" if $debug{gv};
2603 0         0 $gvsym = $replroot->save;
2604 0         0 $replrootfield = "NULL";
2605 0 0       0 $replstartfield = $replstart->save if $replstart;
2606             }
2607             else {
2608 0 0       0 $replstart->save if $replstart;
2609 0         0 $replstartfield = saveoptree( "*ignore*", $replroot, $replstart );
2610 0         0 $replstartfield =~ s/^hv/(OP*)hv/;
2611             }
2612             }
2613              
2614             # pmnext handling is broken in perl itself, we think. Bad op_pmnext
2615             # fields aren't noticed in perl's runtime (unless you try reset) but we
2616             # segfault when trying to dereference it to find op->op_pmnext->op_type
2617 0 0       0 if ($PERL510) {
    0          
2618 0         0 $pmopsect->comment(
2619             "$opsect_common, first, last, pmoffset, pmflags, pmreplroot, pmreplstart"
2620             );
2621             $pmopsect->add(
2622             sprintf( "%s, s\\_%x, s\\_%x, %u, 0x%x, {%s}, {%s}",
2623 0         0 $op->_save_common, ${ $op->first },
2624 0 0       0 ${ $op->last }, ( $ITHREADS ? $op->pmoffset : 0 ),
  0         0  
2625             $op->pmflags, $replrootfield, $replstartfield
2626             ));
2627 0 0       0 if ($] >= 5.017) {
2628 0         0 my $code_list = $op->code_list;
2629 0 0 0     0 if ($code_list and $$code_list) {
2630             warn sprintf("saving pmop_list[%d] code_list $code_list (?{})\n", $pmopsect->index)
2631 0 0       0 if $debug{gv};
2632 0         0 my $code_op = $code_list->save;
2633 0 0       0 $init->add(sprintf("pmop_list[%d].op_code_list = %s;", # (?{}) code blocks
2634             $pmopsect->index, $code_op)) if $code_op;
2635             warn sprintf("done saving pmop_list[%d] code_list $code_list (?{})\n", $pmopsect->index)
2636 0 0       0 if $debug{gv};
2637             }
2638             }
2639             }
2640             elsif ($PERL56) {
2641             # pmdynflags does not exist as B method. It is only used for PMdf_UTF8 dynamically,
2642             # if static we set this already in pmflags.
2643 0         0 $pmopsect->comment(
2644             "$opsect_common, first, last, pmreplroot, pmreplstart, pmnext, pmregexp, pmflags, pmpermflags, pmdynflags"
2645             );
2646             $pmopsect->add(
2647             sprintf( "%s, s\\_%x, s\\_%x, %s, %s, 0, 0, 0x%x, 0x%x",
2648             $op->_save_common,
2649 0         0 ${ $op->first }, ${ $op->last },
  0         0  
  0         0  
2650             $replrootfield, $replstartfield,
2651             $op->pmflags, $op->pmpermflags, 0 # XXX original 5.6 B::C misses pmdynflags
2652             ));
2653             } else { # perl5.8.x
2654 0         0 $pmopsect->comment(
2655             "$opsect_common, first, last, pmreplroot, pmreplstart, pmoffset, pmflags, pmpermflags, pmdynflags, pmstash"
2656             );
2657             $pmopsect->add(
2658             sprintf( "%s, s\\_%x, s\\_%x, %s, %s, 0, %u, 0x%x, 0x%x, 0x%x, %s",
2659 0         0 $op->_save_common, ${ $op->first },
2660 0 0       0 ${ $op->last }, $replrootfield,
  0 0       0  
2661             $replstartfield, $ITHREADS ? $op->pmoffset : 0,
2662             $op->pmflags, $op->pmpermflags,
2663             $op->pmdynflags, $MULTI ? cstring($op->pmstashpv) : "0"
2664             ));
2665 0 0 0     0 if (!$MULTI and $op->pmstash) {
2666 0         0 my $stash = $op->pmstash->save;
2667 0         0 $init->add( sprintf( "pmop_list[%d].op_pmstash = %s;", $pmopsect->index, $stash ) );
2668             }
2669             }
2670 0 0       0 $pmopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2671 0         0 my $pm = sprintf( "pmop_list[%d]", $pmopsect->index );
2672 0 0       0 $init->add( sprintf( "%s.op_ppaddr = %s;", $pm, $ppaddr ) )
2673             unless $B::C::optimize_ppaddr;
2674 0         0 my $re = $op->precomp;
2675 0 0       0 if ( defined($re) ) {
2676 0         0 my $initpm = $init;
2677 0         0 $Regexp{$$op} = $op;
2678 0 0       0 if ($PERL510) {
    0          
2679             # TODO minor optim: fix savere( $re ) to avoid newSVpvn;
2680             # precomp did not set the utf8 flag (#333, #338), fixed with 1.52_01
2681 0         0 my ($qre, $relen, $utf8) = strlen_flags($re);
2682 0         0 my $pmflags = $op->pmflags;
2683             warn "pregcomp $pm $qre:$relen:$utf8".sprintf(" 0x%x\n",$pmflags)
2684 0 0 0     0 if $debug{pv} or $debug{gv};
2685             # Since 5.13.10 with PMf_FOLD (i) we need to swash_init("utf8::Cased").
2686 0 0 0     0 if ($] >= 5.013009 and $pmflags & 4) {
2687             # Note: in CORE utf8::SWASHNEW is demand-loaded from utf8 with Perl_load_module()
2688 0         0 load_utf8_heavy();
2689 0 0 0     0 if ($PERL518 and !$swash_init and $swash_ToCf) {
      0        
2690 0         0 $init->add("PL_utf8_tofold = $swash_ToCf;");
2691 0         0 $swash_init++;
2692             }
2693             }
2694             # some pm need early init (242), SWASHNEW needs some late GVs (GH#273)
2695             # esp with 5.22 multideref init. i.e. all \p{} \N{}, \U, /i, ...
2696             # But XSLoader and utf8::SWASHNEW itself needs to be early.
2697 0 0 0     0 if (($utf8 and $] >= 5.013009 and ($pmflags & 4 == 4)) # needs SWASHNEW (case fold)
      0        
      0        
2698             or re_does_swash($qre, $pmflags))
2699             {
2700 0         0 $initpm = $init1;
2701 0 0       0 warn sprintf("deferred PMOP %s %s 0x%x\n", $qre, $fullname, $pmflags) if $debug{sv};
2702             } else {
2703 0 0       0 warn sprintf("normal PMOP %s %s 0x%x\n", $qre, $fullname, $pmflags) if $debug{sv};
2704             }
2705 0 0 0     0 if ($PERL518 and $op->reflags & RXf_EVAL_SEEN) { # set HINT_RE_EVAL on
2706 0         0 $pmflags |= PMf_EVAL;
2707 0         0 $initpm->no_split;
2708 0         0 $initpm->add("{",
2709             " U32 hints_sav = PL_hints;",
2710             " PL_hints |= HINT_RE_EVAL;");
2711             }
2712 0 0       0 if ($] > 5.008008) { # can do utf8 qr
2713 0         0 $initpm->add( # XXX Modification of a read-only value attempted. use DateTime - threaded
2714             sprintf("PM_SETRE(&%s, CALLREGCOMP(newSVpvn_flags(%s, %s, SVs_TEMP|$utf8), 0x%x));",
2715             $pm, $qre, $relen, $pmflags),
2716             sprintf("RX_EXTFLAGS(PM_GETRE(&%s)) = 0x%x;", $pm, $op->reflags ));
2717             } else {
2718 0         0 $initpm->add
2719             ("PM_SETRE(&$pm,",
2720             " CALLREGCOMP(newSVpvn($qre, $relen), ".sprintf("0x%x));", $pmflags),
2721             sprintf("RX_EXTFLAGS(PM_GETRE(&%s)) = 0x%x;", $pm, $op->reflags ));
2722 0 0       0 $initpm->add("SvUTF8_on(PM_GETRE(&$pm));") if $utf8;
2723             }
2724 0 0 0     0 if ($] >= 5.018 and $op->reflags & RXf_EVAL_SEEN) { # set HINT_RE_EVAL off
2725 0         0 $initpm->add(" PL_hints = hints_sav;",
2726             "}");
2727 0         0 $initpm->split();
2728             }
2729             # See toke.c:8964
2730             # set in the stash the PERL_MAGIC_symtab PTR to the PMOP: ((PMOP**)mg->mg_ptr) [elements++] = pm;
2731 0 0 0     0 if ($PERL510 and $op->pmflags & PMf_ONCE()) {
2732 0 0       0 my $stash = $MULTI ? $op->pmstashpv
    0          
2733             : ref $op->pmstash eq 'B::HV' ? $op->pmstash->NAME : '__ANON__';
2734 0         0 $Regexp{$$op} = $op; #188: restore PMf_ONCE, set PERL_MAGIC_symtab in $stash
2735             }
2736             }
2737             elsif ($PERL56) {
2738 0         0 my ( $resym, $relen ) = savere( $re, 0 );
2739 0         0 $init->add(
2740             "$pm.op_pmregexp = pregcomp((char*)$resym, (char*)$resym + $relen, &$pm);"
2741             );
2742             }
2743             else { # 5.8
2744 0         0 my ( $resym, $relen ) = savere( $re, 0 );
2745 0         0 $init->add(
2746             "PM_SETRE(&$pm, CALLREGCOMP(aTHX_ (char*)$resym, (char*)$resym + $relen, &$pm));"
2747             );
2748             }
2749             }
2750 0 0       0 if ( $gvsym ) {
2751 0 0       0 if ($PERL510) {
2752             # XXX need that for subst
2753 0         0 $init->add("$pm.op_pmreplrootu.op_pmreplroot = (OP*)$gvsym;");
2754             } else {
2755 0         0 $init->add("$pm.op_pmreplroot = (OP*)$gvsym;");
2756             }
2757             }
2758 0         0 savesym( $op, "(OP*)&$pm" );
2759             }
2760              
2761             sub B::SPECIAL::save {
2762 0     0   0 my ($sv, $fullname) = @_;
2763             # special case: $$sv is not the address but an index into specialsv_list
2764             # warn "SPECIAL::save specialsv $$sv\n"; # debug
2765 0 0       0 @specialsv_name = qw(Nullsv &PL_sv_undef &PL_sv_yes &PL_sv_no pWARN_ALL pWARN_NONE)
2766             unless @specialsv_name; # 5.6.2 Exporter quirks. pWARN_STD was added to B with 5.8.9
2767 0         0 my $sym = $specialsv_name[$$sv];
2768 0 0       0 if ( !defined($sym) ) {
2769 0         0 warn "unknown specialsv index $$sv passed to B::SPECIAL::save";
2770             }
2771 0         0 return $sym;
2772             }
2773              
2774       0     sub B::OBJECT::save { }
2775              
2776             sub B::NULL::save {
2777 0     0   0 my ($sv, $fullname) = @_;
2778 0         0 my $sym = objsym($sv);
2779 0 0       0 return $sym if defined $sym;
2780              
2781             # debug
2782 0 0       0 if ( $$sv == 0 ) {
2783 0 0       0 warn "NULL::save for sv = 0 called from @{[(caller(1))[3]]}\n" if $verbose;
  0         0  
2784 0         0 return savesym( $sv, "(void*)Nullsv" );
2785             }
2786              
2787 0         0 my $i = $svsect->index + 1;
2788 0 0       0 warn "Saving SVt_NULL sv_list[$i]\n" if $debug{sv};
2789 0 0       0 $svsect->add( sprintf( "NULL, $u32fmt, 0x%x".($PERL510?", {0}":''),
2790             $sv->REFCNT, $sv->FLAGS ) );
2791             #$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; # XXX where is this possible?
2792 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        
2793             # $svsect->debug( "ix added to sv_debug_file" );
2794 0         0 $init->add(sprintf(qq(sv_list[%d].sv_debug_file = savesharedpv("NULL sv_list[%d] 0x%x");),
2795             $svsect->index, $svsect->index, $sv->FLAGS));
2796             }
2797 0         0 savesym( $sv, sprintf( "&sv_list[%d]", $svsect->index ) );
2798             }
2799              
2800             sub B::UV::save {
2801 0     0   0 my ($sv, $fullname) = @_;
2802 0         0 my $sym = objsym($sv);
2803 0 0       0 return $sym if defined $sym;
2804 0         0 my $uvuformat = $Config{uvuformat};
2805 0         0 $uvuformat =~ s/["\0]//g; #" poor editor
2806 0         0 $uvuformat =~ s/".$/"/; # cperl bug 5.22.2 #61
2807 0         0 my $uvx = $sv->UVX;
2808 0         0 my $suff = 'U';
2809 0 0       0 $suff .= 'L' if $uvx > 2147483647;
2810 0         0 my $i = $svsect->index + 1;
2811 0 0       0 if ($PERL524) {
    0          
    0          
2812             # since 5.24 we need to point the xpvuv to the head
2813             } elsif ($PERL514) {
2814             # issue 145 warn $sv->UVX, " ", sprintf($u32fmt, $sv->UVX);
2815 0         0 $xpvuvsect->comment( "stash, magic, cur, len, xuv_u" );
2816 0         0 $xpvuvsect->add( sprintf( "Nullhv, {0}, 0, 0, {%".$uvuformat."$suff}", $uvx ) );
2817             } elsif ($PERL510) {
2818 0         0 $xpvuvsect->comment( "stash, magic, cur, len, xuv_u" );
2819 0         0 $xpvuvsect->add( sprintf( "{0}, 0, 0, {%".$uvuformat."$suff}", $uvx ) );
2820             } else {
2821 0         0 $xpvuvsect->comment( "pv, cur, len, uv" );
2822 0         0 $xpvuvsect->add( sprintf( "0, 0, 0, %".$uvuformat.$suff, $uvx ) );
2823             }
2824 0 0       0 if ($PERL524) {
2825 0 0       0 $svsect->add(sprintf( "NULL, $u32fmt, 0x%x".
    0          
2826             ($PERL510?', {'.($C99?".svu_uv=":"").$uvx."$suff}":''),
2827             $sv->REFCNT, $sv->FLAGS));
2828             #32bit - sizeof(void*), 64bit: - 2*ptrsize
2829 0 0 0     0 if ($Config{ptrsize} == 4 and !IS_MSVC) {
2830 0         0 $init->add(sprintf( "sv_list[%d].sv_any = (void*)&sv_list[%d] - sizeof(void*);", $i, $i));
2831             } else {
2832             $init->add(sprintf( "sv_list[%d].sv_any = (char*)&sv_list[%d] - %d;", $i, $i,
2833 0         0 2*$Config{ptrsize}));
2834             }
2835             } else {
2836 0 0       0 $svsect->add(sprintf( "&xpvuv_list[%d], $u32fmt, 0x%x".
    0          
2837             ($PERL510?', {'.($C99?".svu_uv=":"").$uvx."$suff}":''),
2838             $xpvuvsect->index, $sv->REFCNT, $sv->FLAGS));
2839             }
2840 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
2841             warn sprintf( "Saving IV(UV) 0x%x to xpvuv_list[%d], sv_list[%d], called from %s:%s\n",
2842 0         0 $sv->UVX, $xpvuvsect->index, $i, @{[(caller(1))[3]]}, @{[(caller(0))[2]]} )
  0         0  
2843 0 0       0 if $debug{sv};
2844 0         0 savesym( $sv, sprintf( "&sv_list[%d]", $i ) );
2845             }
2846              
2847             sub B::IV::save {
2848 0     0   0 my ($sv, $fullname) = @_;
2849 0         0 my $sym = objsym($sv);
2850 0 0       0 return $sym if defined $sym;
2851             # Since 5.11 the RV is no special SV object anymore, just a IV (test 16)
2852 0         0 my $svflags = $sv->FLAGS;
2853 0 0 0     0 if ($PERL512 and $svflags & SVf_ROK) {
2854 0         0 return $sv->B::RV::save($fullname);
2855             }
2856 0 0       0 if ($svflags & SVf_IVisUV) {
2857 0         0 return $sv->B::UV::save;
2858             }
2859 0         0 my $ivx = ivx($sv->IVX);
2860 0         0 my $i = $svsect->index + 1;
2861 0 0 0     0 if ($svflags & 0xff and !($svflags & (SVf_IOK|SVp_IOK))) { # Not nullified
2862 0 0 0     0 unless (($PERL510 and $svflags & 0x00010000) # PADSTALE - out of scope lexical is !IOK
      0        
      0        
      0        
      0        
2863             or (!$PERL510 and $svflags & 0x00000100) # PADBUSY
2864             or ($] > 5.015002 and $svflags & 0x60002)) { # 5.15.3 changed PAD bits
2865 0         0 warn sprintf("Internal warning: IV !IOK $fullname sv_list[$i] 0x%x\n",$svflags);
2866             }
2867             }
2868 0 0       0 if ($PERL524) {
    0          
    0          
2869             # since 5.24 we need to point the xpviv to the head
2870             } elsif ($PERL514) {
2871 0         0 $xpvivsect->comment( "stash, magic, cur, len, xiv_u" );
2872 0         0 $xpvivsect->add( sprintf( "Nullhv, {0}, 0, 0, {%s}", $ivx ) );
2873             } elsif ($PERL510) {
2874 0         0 $xpvivsect->comment( "stash, magic, cur, len, xiv_u" );
2875 0         0 $xpvivsect->add( sprintf( "{0}, 0, 0, {%s}", $ivx ) );
2876             } else {
2877 0         0 $xpvivsect->comment( "pv, cur, len, iv" );
2878 0         0 $xpvivsect->add( sprintf( "0, 0, 0, %s", $ivx ) );
2879             }
2880 0 0       0 if ($PERL524) {
2881 0 0       0 $svsect->add(sprintf( "NULL, $u32fmt, 0x%x, {".($C99?".svu_iv=":"").$ivx.'}',
2882             $sv->REFCNT, $svflags ));
2883             #32bit - sizeof(void*), 64bit: - 2*ptrsize
2884 0 0 0     0 if ($Config{ptrsize} == 4 and !IS_MSVC) {
2885 0         0 $init->add(sprintf( "sv_list[%d].sv_any = (void*)&sv_list[%d] - sizeof(void*);", $i, $i));
2886             } else {
2887             $init->add(sprintf( "sv_list[%d].sv_any = (char*)&sv_list[%d] - %d;", $i, $i,
2888 0         0 2*$Config{ptrsize}));
2889             }
2890             } else {
2891 0 0       0 $svsect->add(sprintf( "&xpviv_list[%d], $u32fmt, 0x%x".($PERL510?', {'.($C99?".svu_iv=":"").$ivx.'}':''),
    0          
2892             $xpvivsect->index, $sv->REFCNT, $svflags ));
2893             }
2894 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
2895             warn sprintf( "Saving IV 0x%x to xpviv_list[%d], sv_list[%d], called from %s:%s\n",
2896 0         0 $sv->IVX, $xpvivsect->index, $i, @{[(caller(1))[3]]}, @{[(caller(0))[2]]} )
  0         0  
2897 0 0       0 if $debug{sv};
2898 0         0 savesym( $sv, sprintf( "&sv_list[%d]", $i ) );
2899             }
2900              
2901             sub B::NV::save {
2902 0     0   0 my ($sv, $fullname) = @_;
2903 0         0 my $sym = objsym($sv);
2904 0 0       0 return $sym if defined $sym;
2905 0         0 my $nv = nvx($sv->NV);
2906 0 0       0 $nv .= '.00' if $nv =~ /^-?\d+$/;
2907             # IVX is invalid in B.xs and unused
2908 0 0       0 my $iv = $sv->FLAGS & SVf_IOK ? $sv->IVX : 0;
2909 0 0 0     0 $nv = '0.00' if IS_MSVC and !$nv;
2910 0 0       0 if ($PERL514) {
    0          
2911 0         0 $xpvnvsect->comment('STASH, MAGIC, cur, len, IVX, NVX');
2912 0         0 $xpvnvsect->add( sprintf( "Nullhv, {0}, 0, 0, {%ld}, {%s}", $iv, $nv ) );
2913             } elsif ($PERL510) { # not fixed by NV isa IV >= 5.8
2914 0         0 $xpvnvsect->comment('NVX, cur, len, IVX');
2915 0         0 $xpvnvsect->add( sprintf( "{%s}, 0, 0, {%ld}", $nv, $iv ) );
2916             }
2917             else {
2918 0         0 $xpvnvsect->comment('PVX, cur, len, IVX, NVX');
2919 0         0 $xpvnvsect->add( sprintf( "0, 0, 0, %ld, %s", $iv, $nv ) );
2920             }
2921 0 0       0 $svsect->add(
2922             sprintf( "&xpvnv_list[%d], $u32fmt, 0x%x %s",
2923             $xpvnvsect->index, $sv->REFCNT, $sv->FLAGS, $PERL510 ? ', {0}' : '' ));
2924 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
2925             warn sprintf( "Saving NV %s to xpvnv_list[%d], sv_list[%d]\n",
2926             $nv, $xpvnvsect->index, $svsect->index )
2927 0 0       0 if $debug{sv};
2928 0         0 savesym( $sv, sprintf( "&sv_list[%d]", $svsect->index ) );
2929             }
2930              
2931             sub savepvn {
2932 0     0 0 0 my ( $dest, $pv, $sv, $cur ) = @_;
2933 0         0 my @init;
2934              
2935             # work with byte offsets/lengths
2936 0 0       0 $pv = pack "a*", $pv if defined $pv;
2937 0 0 0     0 if ( defined $max_string_len && length($pv) > $max_string_len ) {
2938 0         0 push @init, sprintf( "Newx(%s, %u, char);", $dest, length($pv) + 2 );
2939 0         0 my $offset = 0;
2940 0         0 while ( length $pv ) {
2941 0         0 my $str = substr $pv, 0, $max_string_len, '';
2942 0         0 push @init,
2943             sprintf( "Copy(%s, %s+%d, %u, char);",
2944             cstring($str), $dest, $offset, length($str) );
2945 0         0 $offset += length $str;
2946             }
2947 0         0 push @init, sprintf( "%s[%u] = '\\0';", $dest, $offset );
2948             warn sprintf( "Copying overlong PV %s to %s\n", cstring($pv), $dest )
2949 0 0 0     0 if $debug{sv} or $debug{pv};
2950             }
2951             else {
2952             # If READONLY and FAKE use newSVpvn_share instead. (test 75)
2953             # XXX IsCOW forgotten here. rather use a helper is_shared_hek()
2954 0 0 0     0 if ($PERL510 and $sv and (($sv->FLAGS & 0x09000000) == 0x09000000)) {
      0        
2955 0 0       0 warn sprintf( "Saving shared HEK %s to %s\n", cstring($pv), $dest ) if $debug{sv};
2956 0         0 my $hek = save_hek($pv,'',1);
2957 0 0       0 push @init, sprintf( "%s = HEK_KEY(%s);", $dest, $hek ) unless $hek eq 'NULL';
2958 0 0       0 if ($DEBUGGING) { # we have to bypass a wrong HE->HEK assert in hv.c
2959 0         0 push @B::C::static_free, $dest;
2960             }
2961             } else {
2962 0         0 my $cstr = cstring($pv);
2963 0 0 0     0 if (!$cstr and $cstr == 0) {
2964 0         0 $cstr = '""';
2965             }
2966 0 0 0     0 if ($sv and IsCOW($sv)) { # and ($B::C::cow or IsCOW_hek($sv)))
2967             # This cannot be savepvn allocated. TODO: READONLY COW => static hek?
2968 0 0       0 if ($cstr !~ /\\000\\00\d"$/) {
2969 0         0 $cstr = substr($cstr,0,-1) . '\0\001"';
2970 0         0 $cur += 2;
2971             }
2972 0 0       0 warn sprintf( "Saving COW PV %s to %s\n", $cstr, $dest ) if $debug{sv};
2973 0         0 return (sprintf( "Newx(%s, sizeof(%s)-1, char);", $dest, $cstr ),
2974             sprintf( "Copy(%s, %s, sizeof(%s)-1, char);", $cstr, $dest, $cstr ));
2975             }
2976 0 0       0 warn sprintf( "Saving PV %s to %s\n", $cstr, $dest ) if $debug{sv};
2977 0         0 push @init, sprintf( "%s = Perl_savepvn(aTHX_ STR_WITH_LEN(%s));", $dest, $cstr );
2978             }
2979             }
2980 0         0 return @init;
2981             }
2982              
2983             sub B::PVLV::save {
2984 0     0   0 my ($sv, $fullname) = @_;
2985 0         0 my $sym = objsym($sv);
2986 0 0       0 if (defined $sym) {
2987 0 0       0 if ($in_endav) {
2988 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
2989 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
2990             }
2991 0         0 return $sym;
2992             }
2993 0         0 my ($pvsym, $cur, $len, $pv, $static, $flags) = save_pv_or_rv ($sv, $fullname);
2994 0         0 my ( $lvtarg, $lvtarg_sym ); # XXX missing
2995 0         0 my $tmp_pvsym = $pvsym;
2996 0 0       0 if ($PERL514) {
    0          
2997 0         0 $xpvlvsect->comment('STASH, MAGIC, CUR, LEN, GvNAME, xnv_u, TARGOFF, TARGLEN, TARG, TYPE');
2998 0         0 $xpvlvsect->add(
2999             sprintf("Nullhv, {0}, %u, %d, 0/*GvNAME later*/, %s, %u, %u, Nullsv, %s",
3000             $cur, $len, nvx($sv->NVX),
3001             $sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) ));
3002 0 0 0     0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3003 0         0 $svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x, {(char*)%s}",
3004             $xpvlvsect->index, $sv->REFCNT, $sv->FLAGS, $tmp_pvsym));
3005             } elsif ($PERL510) {
3006 0         0 $xpvlvsect->comment('xnv_u, CUR, LEN, GvNAME, MAGIC, STASH, TARGOFF, TARGLEN, TARG, TYPE');
3007 0         0 $xpvlvsect->add(
3008             sprintf("%s, %u, %d, 0/*GvNAME later*/, 0, Nullhv, %u, %u, Nullsv, %s",
3009             nvx($sv->NVX), $cur, $len,
3010             $sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) ));
3011 0 0       0 $svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x, {%s}",
3012             $xpvlvsect->index, $sv->REFCNT, $flags,
3013             ($C99?".svu_pv = (char*)":"(char*)").$tmp_pvsym));
3014             } else {
3015 0         0 $xpvlvsect->comment('PVX, CUR, LEN, IVX, NVX, TARGOFF, TARGLEN, TARG, TYPE');
3016 0         0 $xpvlvsect->add(
3017             sprintf("(char*)%s, %u, %u, %s, %s, 0, 0, %u, %u, Nullsv, %s",
3018             $pvsym, $cur, $len, ivx($sv->IVX), nvx($sv->NVX),
3019             $sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) ));
3020 0         0 $svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x",
3021             $xpvlvsect->index, $sv->REFCNT, $flags));
3022             }
3023 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3024 0         0 my $s = "sv_list[".$svsect->index."]";
3025 0 0 0     0 if ( !$static ) {
    0          
3026 0 0       0 if ($PERL510) {
3027 0         0 $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3028             }
3029             else {
3030 0         0 $init->add( savepvn( sprintf( "xpvlv_list[%d].xpv_pv", $xpvlvsect->index ), $pv, $cur ) );
3031             }
3032             } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3033 0         0 $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3034             }
3035 0         0 $sv->save_magic($fullname);
3036 0         0 savesym( $sv, "&".$s );
3037             }
3038              
3039             sub B::PVIV::save {
3040 0     0   0 my ($sv, $fullname) = @_;
3041 0         0 my $sym = objsym($sv);
3042 0 0       0 if (defined $sym) {
3043 0 0       0 if ($in_endav) {
3044 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
3045 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
3046             }
3047 0         0 return $sym;
3048             }
3049 0         0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3050 0         0 my $tmp_pvsym = $pvsym;
3051 0 0       0 if ($PERL514) {
    0          
3052 0         0 $xpvivsect->comment('STASH, MAGIC, cur, len, IVX');
3053 0         0 $xpvivsect->add( sprintf( "Nullhv, {0}, %u, %u, {%s}", $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long
3054 0 0 0     0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3055             } elsif ($PERL510) {
3056 0         0 $xpvivsect->comment('xnv_u, cur, len, IVX');
3057 0         0 $xpvivsect->add( sprintf( "{0}, %u, %u, {%s}", $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long
3058             } else {
3059             #$iv = 0 if $sv->FLAGS & (SVf_IOK|SVp_IOK);
3060 0         0 $xpvivsect->comment('PVX, cur, len, IVX');
3061 0         0 $xpvivsect->add( sprintf( "(char*)%s, %u, %u, %s",
3062             $pvsym, $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long
3063             }
3064 0 0       0 $svsect->add(
    0          
3065             sprintf("&xpviv_list[%d], $u32fmt, 0x%x %s",
3066             $xpvivsect->index, $sv->REFCNT, $flags,
3067             $PERL510 ? ", {".($C99?".svu_pv=":"")."(char*)$tmp_pvsym}" : '' ) );
3068 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3069 0         0 my $s = "sv_list[".$svsect->index."]";
3070 0 0       0 if ( defined($pv) ) {
3071 0 0 0     0 if ( !$static ) {
    0          
3072 0 0       0 if ($PERL510) {
3073 0         0 $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3074             } else {
3075 0         0 $init->add( savepvn( sprintf( "xpviv_list[%d].xpv_pv", $xpvivsect->index ), $pv, $cur ) );
3076             }
3077             } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3078 0         0 $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3079             }
3080             }
3081 0         0 savesym( $sv, "&".$s );
3082             }
3083              
3084             sub B::PVNV::save {
3085 0     0   0 my ($sv, $fullname) = @_;
3086 0         0 my $sym = objsym($sv);
3087 0 0       0 if (defined $sym) {
3088 0 0       0 if ($in_endav) {
3089 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
3090 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
3091             }
3092 0         0 return $sym;
3093             }
3094 0         0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3095 0         0 my $tmp_pvsym = $pvsym;
3096 0         0 my $nvx = '0.0';
3097 0         0 my $ivx = ivx($sv->IVX); # here must be IVX!
3098 0 0       0 if ($flags & (SVf_NOK|SVp_NOK)) {
3099             # it could be a double, or it could be 2 ints - union xpad_cop_seq
3100 0         0 $nvx = nvx($sv->NV);
3101             } else {
3102 0 0 0     0 if ($PERL510 and $C99 and !$PERL522) {
    0 0        
3103 0         0 $nvx = sprintf(".xpad_cop_seq.xlow = %s, .xpad_cop_seq.xhigh = %s",
3104             ivx($sv->COP_SEQ_RANGE_LOW), ivx($sv->COP_SEQ_RANGE_HIGH),
3105             );
3106             } elsif (!$PERL522) {
3107 0         0 $nvx = nvx($sv->NVX);
3108             }
3109             }
3110 0 0       0 if ($PERL510) {
3111             # For some time the stringification works of NVX double to two ints worked ok.
3112 0 0       0 if ($PERL514) {
3113 0 0 0     0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3114 0         0 $xpvnvsect->comment('STASH, MAGIC, cur, len, IVX, NVX');
3115 0         0 $xpvnvsect->add(sprintf( "Nullhv, {0}, %u, %u, {%s}, {%s}", $cur, $len, $ivx, $nvx) );
3116             } else {
3117 0         0 $xpvnvsect->comment('NVX, cur, len, IVX');
3118 0         0 $xpvnvsect->add(sprintf( "{%s}, %u, %u, {%s}", $nvx, $cur, $len, $ivx ) );
3119             }
3120 0 0 0     0 if (!($sv->FLAGS & (SVf_NOK|SVp_NOK)) and !$PERL522) {
3121 0 0       0 warn "NV => run-time union xpad_cop_seq init\n" if $debug{sv};
3122 0         0 $init->add(sprintf("xpvnv_list[%d].xnv_u.xpad_cop_seq.xlow = %s;",
3123             $xpvnvsect->index, ivx($sv->COP_SEQ_RANGE_LOW)),
3124             # pad.c: PAD_MAX = I32_MAX (4294967295)
3125             # U suffix <= "warning: this decimal constant is unsigned only in ISO C90"
3126             sprintf("xpvnv_list[%d].xnv_u.xpad_cop_seq.xhigh = %s;",
3127             $xpvnvsect->index, ivx($sv->COP_SEQ_RANGE_HIGH)));
3128             }
3129             }
3130             else {
3131 0         0 $xpvnvsect->comment('PVX, cur, len, IVX, NVX');
3132 0         0 $xpvnvsect->add(sprintf( "(char*)%s, %u, %u, %s, %s", $pvsym, $cur, $len, $ivx, $nvx ) );
3133             }
3134 0 0       0 $svsect->add(
    0          
3135             sprintf("&xpvnv_list[%d], $u32fmt, 0x%x %s",
3136             $xpvnvsect->index, $sv->REFCNT, $flags,
3137             $PERL510 ? ", {".($C99?".svu_pv=":"")."(char*)$tmp_pvsym}" : '' ) );
3138 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3139 0         0 my $s = "sv_list[".$svsect->index."]";
3140 0 0       0 if ( defined($pv) ) {
3141 0 0 0     0 if ( !$static ) {
    0          
3142 0 0       0 if ($PERL510) {
3143 0         0 $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3144             }
3145             else {
3146 0         0 $init->add( savepvn( sprintf( "xpvnv_list[%d].xpv_pv", $xpvnvsect->index ), $pv, $cur ) );
3147             }
3148             } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3149 0         0 $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3150             }
3151             }
3152 0 0 0     0 push @B::C::static_free, "&".$s if $PERL518 and $sv->FLAGS & SVs_OBJECT;
3153 0         0 savesym( $sv, "&".$s );
3154             }
3155              
3156             sub B::BM::save {
3157 0     0   0 my ($sv, $fullname) = @_;
3158 0         0 my $sym = objsym($sv);
3159 0 0 0     0 return $sym if !$PERL510 and defined $sym;
3160 0 0       0 $sv = bless $sv, "B::BM" if $PERL510;
3161 0         0 my $pv = pack "a*", ( $sv->PV . "\0" . $sv->TABLE );
3162 0         0 my $cur = $sv->CUR;
3163 0         0 my $len = $cur + length($sv->TABLE) + 1;
3164 0         0 my $s;
3165 0 0       0 if ($PERL510) {
3166 0 0       0 warn "Saving FBM for GV $sym\n" if $debug{gv};
3167 0         0 $init->add( sprintf( "%s = (GV*)newSV_type(SVt_PVGV);", $sym ),
3168             sprintf( "SvFLAGS(%s) = 0x%x;", $sym, $sv->FLAGS),
3169             sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $sv->REFCNT + 1 ),
3170             sprintf( "SvPVX(%s) = %s;", $sym, cstring($pv) ),
3171             sprintf( "SvCUR_set(%s, %d);", $sym, $cur ),
3172             sprintf( "SvLEN_set(%s, %d);", $sym, $len ),
3173             sprintf( "BmRARE(%s) = %d;", $sym, $sv->RARE ),
3174             sprintf( "BmPREVIOUS(%s) = %d;", $sym, $sv->PREVIOUS ),
3175             sprintf( "BmUSEFUL(%s) = %d;", $sym, $sv->USEFUL )
3176             );
3177             } else {
3178 0         0 my $static;
3179 0         0 $xpvbmsect->comment('pvx,cur,len(+258),IVX,NVX,MAGIC,STASH,USEFUL,PREVIOUS,RARE');
3180 0 0 0     0 $xpvbmsect->add(
3181             sprintf("%s, %u, %u, %s, %s, 0, 0, %d, %u, 0x%x",
3182             defined($pv) && $static ? cstring($pv) : "NULL",
3183             $cur, $len, ivx($sv->IVX), nvx($sv->NVX),
3184             $sv->USEFUL, $sv->PREVIOUS, $sv->RARE
3185             ));
3186 0         0 $svsect->add(sprintf("&xpvbm_list[%d], $u32fmt, 0x%x",
3187             $xpvbmsect->index, $sv->REFCNT, $sv->FLAGS));
3188 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3189 0         0 $s = "sv_list[".$svsect->index."]";
3190 0 0       0 if (!$static) {
3191 0         0 $init->add(savepvn( sprintf( "xpvbm_list[%d].xpv_pv", $xpvbmsect->index ), $pv, 0, $len ) );
3192             } else {
3193 0 0 0     0 push @B::C::static_free, $s if defined($pv) and !$in_endav;
3194             }
3195             }
3196             # Restore possible additional magic. fbm_compile adds just 'B'.
3197 0         0 $sv->save_magic($fullname);
3198              
3199 0 0       0 if ($PERL510) {
3200 0         0 return $sym;
3201             } else {
3202 0 0       0 if ($] == 5.008009) { # XXX 5.8.9 needs more. TODO test 5.8.0 - 5.8.7
3203 0         0 $init->add( sprintf( "fbm_compile(&sv_list[%d], 0);", $svsect->index ) );
3204             }
3205             # cur+len was broken on all B::C versions
3206             #$init->add(sprintf( "xpvbm_list[%d].xpv_cur = %u;", $xpvbmsect->index, $len ) );
3207 0         0 return savesym( $sv, "&".$s );
3208             }
3209             }
3210              
3211             sub B::PV::save {
3212 0     0   0 my ($sv, $fullname) = @_;
3213 0         0 my $sym = objsym($sv);
3214 0 0       0 if (defined $sym) {
3215 0 0       0 if ($in_endav) {
3216 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
3217 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
3218             }
3219 0         0 return $sym;
3220             }
3221             #my $flags = $sv->FLAGS;
3222 0         0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3223 0 0       0 my $shared_hek = $PERL510 ? (($flags & 0x09000000) == 0x09000000) : undef;
3224 0 0 0     0 if (!$shared_hek and (IsCOW_hek($sv) or ($len==0 and $flags & SVf_IsCOW))) {
      0        
3225 0         0 $shared_hek = 1;
3226             }
3227 0         0 my $tmp_pvsym = $pvsym;
3228             # $static = 0 if !($flags & SVf_ROK) and $sv->PV and $sv->PV =~ /::bootstrap$/;
3229 0         0 my $refcnt = $sv->REFCNT;
3230 0         0 my $svix;
3231             # sv_free2 problem with !SvIMMORTAL and del_SV
3232             # repro with -O0 .. -O2 for all testcases
3233 0 0 0     0 if ($PERL518 and $fullname && $fullname eq 'svop const') {
      0        
3234 0 0       0 $refcnt = $DEBUGGING ? 1000 : 0x7fffffff;
3235             }
3236             #if (!$shared_hek and !$B::C::cow and IsCOW($sv)) {
3237             # $flags &= ~SVf_IsCOW;
3238             # warn sprintf("turn off SVf_IsCOW %s %s %s\n", $sym, cstring($pv), $fullname)
3239             # if $debug{pv};
3240             #}
3241 0 0       0 if ($PERL510) {
3242             # static pv, do not destruct. test 13 with pv0 "3".
3243 0 0 0     0 if ($B::C::const_strings and !$shared_hek and $flags & SVf_READONLY and !$len) {
      0        
      0        
3244 0         0 $flags &= ~0x01000000;
3245             warn sprintf("constpv turn off SVf_FAKE %s %s %s\n", $sym, cstring($pv), $fullname)
3246 0 0       0 if $debug{pv};
3247             }
3248 0 0 0     0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3249 0 0       0 $xpvsect->comment( $PERL514 ? "stash, magic, cur, len" : "xnv_u, cur, len");
3250 0 0       0 $xpvsect->add( sprintf( "%s{0}, %u, %u", $PERL514 ? "Nullhv, " : "", $cur, $len ) );
3251 0         0 $svsect->comment( "any, refcnt, flags, sv_u" );
3252 0 0       0 $svsect->add( sprintf( "&xpv_list[%d], $u32fmt, 0x%x, {%s}",
    0          
3253             $xpvsect->index, $refcnt, $flags,
3254             $tmp_pvsym eq 'NULL' ? '0' :
3255             ($C99?".svu_pv=(char*)":"(char*)").$pvsym ));
3256 0         0 $svix = $svsect->index;
3257 0 0 0     0 if ( defined($pv) and !$static ) {
    0 0        
      0        
3258 0 0       0 if ($shared_hek) {
3259 0         0 my $hek = save_hek($pv, $fullname, 1);
3260 0 0       0 $init->add( sprintf( "sv_list[%d].sv_u.svu_pv = HEK_KEY(%s);", $svix, $hek ))
3261             unless $hek eq 'NULL';
3262             } else {
3263 0         0 $init->add( savepvn( sprintf( "sv_list[%d].sv_u.svu_pv", $svix ), $pv, $sv, $cur ) );
3264             }
3265             } elsif ($shared_hek and $static and $pvsym =~ /^hek/) {
3266 0         0 $init->add( sprintf( "sv_list[%d].sv_u.svu_pv = %s.hek_key;", $svix, $pvsym ));
3267             }
3268 0 0 0     0 if ($debug{flags} and (!$ITHREADS or $PERL514) and $DEBUG_LEAKING_SCALARS) { # add sv_debug_file
      0        
      0        
3269 0 0       0 $init->add(sprintf(qq(sv_list[%d].sv_debug_file = %s" sv_list[%d] 0x%x";),
3270             $svix, cstring($pv) eq '0' ? '"NULL"' : cstring($pv),
3271             $svix, $flags));
3272             }
3273             }
3274             else {
3275 0         0 $xpvsect->comment( "pv, cur, len");
3276 0         0 $xpvsect->add(sprintf( "(char*)%s, %u, %u", $pvsym, $cur, $len ) );
3277 0         0 $svsect->comment( "any, refcnt, flags" );
3278 0         0 $svsect->add(sprintf( "&xpv_list[%d], $u32fmt, 0x%x",
3279             $xpvsect->index, $refcnt, $flags));
3280 0         0 $svix = $svsect->index;
3281 0 0 0     0 if ( defined($pv) and !$static ) {
3282 0         0 $init->add( savepvn( sprintf( "xpv_list[%d].xpv_pv", $xpvsect->index ), $pv, 0, $cur ) );
3283             }
3284             }
3285 0         0 my $s = "sv_list[$svix]";
3286 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3287 0 0 0     0 push @B::C::static_free, "&".$s if $PERL518 and $flags & SVs_OBJECT;
3288 0         0 savesym( $sv, "&".$s );
3289             }
3290              
3291             # 5.18-5.20 => PV::save, since 5.22 native using this method
3292             sub B::PADNAME::save {
3293 0     0   0 my ($pn, $fullname) = @_;
3294 0         0 my $sym = objsym($pn);
3295 0 0       0 if (defined $sym) {
3296 0 0       0 if ($in_endav) {
3297 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
3298 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
3299             }
3300 0         0 return $sym;
3301             }
3302 0         0 my $flags = $pn->FLAGS; # U8 + FAKE if OUTER. OUTER,STATE,LVALUE,TYPED,OUR
3303 0         0 $flags = $flags & 0xff;
3304 0         0 my $gen = $pn->GEN;
3305 0         0 my $stash = $pn->OURSTASH;
3306 0         0 my $type = $pn->TYPE;
3307 0         0 my $sn = $stash->save($fullname);
3308 0         0 my $tn = $type->save($fullname);
3309 0         0 my $refcnt = $pn->REFCNT;
3310 0 0       0 $refcnt++ if $refcnt < 1000; # XXX protect from free, but allow SvREFCOUNT_IMMORTAL
3311 0         0 my $str = $pn->PVX;
3312 0         0 my $cstr = cstring($str); # a 5.22 padname is always utf8
3313 0         0 my $len = $pn->LEN;
3314 0         0 my $alignedlen = 8*(int($len / 8)+1); # 5 -> 8, 9 -> 16
3315 0         0 my $struct_name = "my_padname_with_str_".$alignedlen;
3316 0         0 my $pnsect = $padnamesect{$alignedlen};
3317 0 0       0 if (!$pnsect) {
3318 0         0 my $name = "padname_$alignedlen";
3319 0 0       0 warn "dynamically created oversized $name section\n" if $verbose;
3320 0         0 $padnamesect{$alignedlen} = new B::C::Section $name, \%symtable, 0;
3321             }
3322 0         0 my $ix = $pnsect->index + 1;
3323 0         0 my $name = $pnsect->name;
3324 0         0 my $s = "&".$name."_list[$ix]";
3325             # 5.22 needs the buffer to be at the end, and the pv pointing to it.
3326             # We allocate a static buffer of different sizes.
3327 0         0 $pnsect->comment( "pv, ourstash, type, low, high, refcnt, gen, len, flags, str");
3328 0         0 my $pnstr = "((char*)$s)+STRUCT_OFFSET(struct $struct_name, xpadn_str[0])";
3329 0 0       0 if (IS_MSVC) {
3330 0         0 $pnstr = sprintf("((char*)$s)+%d", $Config{ptrsize} * 3 + 5);
3331             }
3332 0 0 0     0 $pnsect->add( sprintf
    0          
    0          
    0          
3333             ( "%s, %s, {%s}, %u, %u, %s, %i, %u, 0x%x, %s",
3334             ($ix or $len) ? $pnstr : 'NULL',
3335             is_constant($sn) ? "(HV*)$sn" : 'Nullhv',
3336             is_constant($tn) ? "(HV*)$tn" : 'Nullhv',
3337             $pn->COP_SEQ_RANGE_LOW,
3338             $pn->COP_SEQ_RANGE_HIGH,
3339             $refcnt >= 1000 ? sprintf("0x%x", $refcnt) : "$refcnt /* +1 */",
3340             $gen, $len, $flags, $cstr));
3341             #if ( $len > 64 ) {
3342             # Houston we have a problem, need to allocate this padname dynamically. Not done yet
3343             # either dynamic or seperate structs per size MyPADNAME(5)
3344             # die "Internal Error: Overlong name of lexical variable $cstr for $fullname [#229]";
3345             #}
3346 0 0       0 $pnsect->debug( $fullname." ".$str, $pn->flagspv ) if $debug{flags};
3347 0 0       0 $init->add("SvOURSTASH_set($s, $sn);") unless is_constant($sn);
3348 0 0       0 $init->add("PadnameTYPE($s) = (HV*)$tn;") unless is_constant($tn);
3349 0         0 push @B::C::static_free, $s;
3350 0         0 savesym( $pn, $s );
3351             }
3352              
3353             sub lexwarnsym {
3354 0     0 0 0 my $pv = shift;
3355 0 0       0 if ($lexwarnsym{$pv}) {
3356 0         0 return @{$lexwarnsym{$pv}};
  0         0  
3357             } else {
3358 0         0 my $sym = sprintf( "lexwarn%d", $pv_index++ );
3359 0         0 my ($cstring, $cur, $utf8) = strlen_flags($pv);
3360 0         0 my $isint = 0;
3361 0 0       0 if ($] < 5.009) { # need a SV->PV
3362 0         0 $decl->add( sprintf( "Static SV* %s;", $sym ));
3363 0         0 $init->add( sprintf( "%s = newSVpvn(%s, %u);", $sym, $cstring, $cur));
3364             } else {
3365             # if 8 use UVSIZE, if 4 use LONGSIZE
3366 0 0       0 my $t = ($Config{longsize} == 8) ? "J" : "L";
3367 0         0 my ($iv) = unpack($t, $pv); # unsigned longsize
3368 0 0 0     0 if ($iv >= 0 and $iv <= 2) { # specialWARN: single STRLEN
3369 0         0 $decl->add( sprintf( "Static const STRLEN* %s = %d;", $sym, $iv ));
3370 0         0 $isint = 1;
3371             } else { # sizeof(STRLEN) + (WARNsize)
3372 0         0 my $packedpv = pack("$t a*",length($pv), $pv);
3373 0         0 $decl->add( sprintf( "Static const char %s[] = %s;", $sym, cstring($packedpv) ));
3374             }
3375             }
3376 0         0 $lexwarnsym{$pv} = [$sym,$isint];
3377 0         0 return ($sym, $isint);
3378             }
3379             }
3380              
3381             # pre vs. post 5.8.9/5.9.4 logic for lexical warnings
3382             @B::LEXWARN::ISA = qw(B::PV B::IV);
3383             sub B::LEXWARN::save {
3384 0     0   0 my ($sv, $fullname) = @_;
3385 0 0       0 my $pv = $] >= 5.008009 ? $sv->PV : $sv->IV;
3386 0         0 return lexwarnsym($pv); # look for shared const int's
3387             }
3388              
3389             # post 5.11: When called from save_rv not from PMOP::save precomp
3390             sub B::REGEXP::save {
3391 0     0   0 my ($sv, $fullname) = @_;
3392 0         0 my $sym = objsym($sv);
3393 0 0       0 return $sym if defined $sym;
3394 0         0 my $pv = $sv->PV;
3395 0         0 my $cur = $sv->CUR;
3396             # construct original PV
3397 0         0 $pv =~ s/^(\(\?\^[adluimsx-]*\:)(.*)\)$/$2/;
3398 0         0 $cur -= length($sv->PV) - length($pv);
3399 0         0 my $cstr = cstring($pv);
3400             # Unfortunately this XPV is needed temp. Later replaced by struct regexp.
3401 0 0       0 $xpvsect->add( sprintf( "%s{0}, %u, %u", $PERL514 ? "Nullhv, " : "", $cur, 0 ) );
3402 0 0       0 $svsect->add(sprintf("&xpv_list[%d], $u32fmt, 0x%x, {%s}",
3403             $xpvsect->index, $sv->REFCNT, $sv->FLAGS, $] > 5.017006 ? "NULL" : $cstr));
3404 0         0 my $ix = $svsect->index;
3405 0 0 0     0 warn "Saving RX $cstr to sv_list[$ix]\n" if $debug{rx} or $debug{sv};
3406 0 0       0 if ($] > 5.011) {
3407 0 0       0 my $pmflags = $PERL522 ? $sv->compflags : $sv->EXTFLAGS;
3408 0 0       0 my $initpm = re_does_swash($cstr, $pmflags) ? $init1 : $init;
3409 0 0 0     0 if ($PERL518 and $sv->EXTFLAGS & RXf_EVAL_SEEN) {
3410 0         0 $initpm->add("PL_hints |= HINT_RE_EVAL;");
3411             }
3412             $initpm->add(# replace sv_any->XPV with struct regexp. need pv and extflags
3413 0         0 sprintf("SvANY(&sv_list[%d]) = SvANY(CALLREGCOMP(newSVpvn(%s, %d), 0x%x));",
3414             $ix, $cstr, $cur, $pmflags));
3415 0 0 0     0 if ($PERL518 and $sv->EXTFLAGS & RXf_EVAL_SEEN) {
3416 0         0 $initpm->add("PL_hints &= ~HINT_RE_EVAL;");
3417             }
3418             }
3419 0 0       0 if ($] < 5.017006) {
3420             # since 5.17.6 the SvLEN stores RX_WRAPPED(rx)
3421 0         0 $init->add(sprintf("SvCUR(&sv_list[%d]) = %d;", $ix, $cur),
3422             "SvLEN(&sv_list[$ix]) = 0;");
3423             } else {
3424 0         0 $init->add("sv_list[$ix].sv_u.svu_rx = (struct regexp*)sv_list[$ix].sv_any;");
3425             }
3426 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3427 0         0 $sym = savesym( $sv, sprintf( "&sv_list[%d]", $ix ) );
3428 0         0 $sv->save_magic($fullname);
3429 0         0 return $sym;
3430             }
3431              
3432             sub save_remap {
3433 0     0 0 0 my ($key, $pkg, $name, $ivx, $mandatory) = @_;
3434 0         0 my $id = $xpvmgsect->index + 1;
3435             #my $svid = $svsect->index + 1;
3436 0 0       0 warn "init remap for $key\: $name $ivx in xpvmg_list[$id]\n" if $verbose;
3437 0         0 my $props = { NAME => $name, ID => $id, MANDATORY => $mandatory };
3438 0 0       0 $init2_remap{$key}{MG} = [] unless $init2_remap{$key}{'MG'};
3439 0         0 push @{$init2_remap{$key}{MG}}, $props;
  0         0  
3440             }
3441              
3442             sub patch_dlsym {
3443 0     0 0 0 my ($sv, $fullname, $ivx) = @_;
3444 0         0 my $pkg = '';
3445 0 0       0 if (ref($sv) eq 'B::PVMG') {
3446 0         0 my $stash = $sv->SvSTASH;
3447 0 0       0 $pkg = $stash->can('NAME') ? $stash->NAME : '';
3448             }
3449 0 0       0 my $name = $sv->FLAGS & SVp_POK ? $sv->PVX : "";
3450 0         0 my $ivx_s = $ivx;
3451 0         0 $ivx_s =~ s/U?L?$//g;
3452 0         0 my $ivxhex = sprintf("0x%x", $ivx_s);
3453             # Encode RT #94221
3454 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          
3455 0         0 $name =~ s/-/_/g;
3456 0 0       0 $pkg = 'Encode' if $pkg eq 'Encode::XS'; # TODO foreign classes
3457 0 0 0     0 mark_package($pkg) if $fullname eq '(unknown)' and $ITHREADS;
3458 0 0       0 warn "$pkg $Encode::VERSION with remap support for $name\n" if $verbose;
3459             }
3460             elsif ($pkg eq 'Encode::XS') {
3461 0         0 $pkg = 'Encode';
3462 0 0       0 if ($fullname eq 'Encode::Encoding{iso-8859-1}') {
    0          
    0          
    0          
3463 0         0 $name = "iso8859_1_encoding";
3464             }
3465             elsif ($fullname eq 'Encode::Encoding{null}') {
3466 0         0 $name = "null_encoding";
3467             }
3468             elsif ($fullname eq 'Encode::Encoding{ascii-ctrl}') {
3469 0         0 $name = "ascii_ctrl_encoding";
3470             }
3471             elsif ($fullname eq 'Encode::Encoding{ascii}') {
3472 0         0 $name = "ascii_encoding";
3473             }
3474              
3475 0 0 0     0 if ($name and $name =~ /^(ascii|ascii_ctrl|iso8859_1|null)/ and $Encode::VERSION gt '2.58') {
      0        
3476 0         0 my $enc = Encode::find_encoding($name);
3477 0 0       0 $name .= "_encoding" unless $name =~ /_encoding$/;
3478 0         0 $name =~ s/-/_/g;
3479 0 0       0 warn "$pkg $Encode::VERSION with remap support for $name (find 1)\n" if $verbose;
3480 0         0 mark_package($pkg);
3481 0 0       0 if ($pkg ne 'Encode') {
3482 0         0 svref_2object( \&{"$pkg\::bootstrap"} )->save;
  0         0  
3483 0         0 mark_package('Encode');
3484             }
3485             }
3486             else {
3487 0         0 for my $n (Encode::encodings()) { # >=5.16 constsub without name
3488 0         0 my $enc = Encode::find_encoding($n);
3489 0 0 0     0 if ($enc and ref($enc) ne 'Encode::XS') { # resolve alias such as Encode::JP::JIS7=HASH(0x292a9d0)
3490 0         0 $pkg = ref($enc);
3491 0         0 $pkg =~ s/^(Encode::\w+)(::.*)/$1/; # collapse to the @dl_module name
3492 0         0 $enc = Encode->find_alias($n);
3493             }
3494 0 0 0     0 if ($enc and ref($enc) eq 'Encode::XS' and $sv->IVX == $$enc) {
      0        
3495 0         0 $name = $n;
3496 0         0 $name =~ s/-/_/g;
3497 0 0       0 $name .= "_encoding" if $name !~ /_encoding$/;
3498 0         0 mark_package($pkg) ;
3499 0 0       0 if ($pkg ne 'Encode') {
3500 0         0 svref_2object( \&{"$pkg\::bootstrap"} )->save;
  0         0  
3501 0         0 mark_package('Encode');
3502             }
3503 0         0 last;
3504             }
3505             }
3506 0 0       0 if ($name) {
3507 0 0       0 warn "$pkg $Encode::VERSION remap found for constant $name\n" if $verbose;
3508             } else {
3509 0         0 warn "Warning: Possible missing remap for compile-time XS symbol in $pkg $fullname $ivxhex [#305]\n";
3510             }
3511             }
3512             }
3513             # Encode-2.59 uses a different name without _encoding
3514             elsif ($Encode::VERSION ge '2.58' and Encode::find_encoding($name)) {
3515 0         0 my $enc = Encode::find_encoding($name);
3516 0 0       0 $pkg = ref($enc) if ref($enc) ne 'Encode::XS';
3517 0         0 $name .= "_encoding";
3518 0         0 $name =~ s/-/_/g;
3519 0 0       0 $pkg = 'Encode' unless $pkg;
3520 0 0       0 warn "$pkg $Encode::VERSION with remap support for $name (find 2)\n" if $verbose;
3521             }
3522             # now that is a weak heuristic, which misses #305
3523             elsif (defined ($Net::DNS::VERSION)
3524             and $Net::DNS::VERSION =~ /^0\.(6[789]|7[1234])/) {
3525 0 0       0 if ($fullname eq 'svop const') {
3526 0         0 $name = "ascii_encoding";
3527 0 0       0 $pkg = 'Encode' unless $pkg;
3528 0         0 warn "Warning: Patch Net::DNS external XS symbol $pkg\::$name $ivxhex [RT #94069]\n";
3529             }
3530             }
3531             elsif ($pkg eq 'Net::LibIDN') {
3532 0         0 $name = "idn_to_ascii"; # ??
3533             }
3534              
3535             # new API (only Encode so far)
3536 0 0 0     0 if ($pkg and $name and $name =~ /^[a-zA-Z_0-9-]+$/) { # valid symbol name
      0        
3537 0 0       0 warn "Remap IOK|POK $pkg with $name\n" if $verbose;
3538 0         0 save_remap($pkg, $pkg, $name, $ivxhex, 0);
3539 0         0 $ivx = "0UL /* $ivxhex => $name */";
3540 0 0       0 mark_package($pkg, 1) if $fullname =~ /^(svop const|padop)/;
3541             }
3542             else {
3543 0         0 warn "Warning: Possible missing remap for compile-time XS symbol in $pkg $fullname $ivxhex [#305]\n";
3544             }
3545 0         0 return $ivx;
3546             }
3547              
3548             sub B::PVMG::save {
3549 0     0   0 my ($sv, $fullname) = @_;
3550 0         0 my $sym = objsym($sv);
3551 0 0       0 if (defined $sym) {
3552 0 0       0 if ($in_endav) {
3553 0 0       0 warn "in_endav: static_free without $sym\n" if $debug{av};
3554 0         0 @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
  0         0  
3555             }
3556 0         0 return $sym;
3557             }
3558 0         0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3559             #warn sprintf( "PVMG %s (0x%x) $pvsym, $len, $cur, $pv\n", $sym, $$sv ) if $debug{mg};
3560              
3561 0         0 my ($ivx,$nvx);
3562             # since 5.11 REGEXP isa PVMG, but has no IVX and NVX methods
3563 0 0 0     0 if ($] >= 5.011 and ref($sv) eq 'B::REGEXP') {
3564 0         0 return B::REGEXP::save($sv, $fullname);
3565             }
3566             else {
3567 0         0 $ivx = ivx($sv->IVX); # XXX How to detect HEK* namehek?
3568 0         0 $nvx = nvx($sv->NVX); # it cannot be xnv_u.xgv_stash ptr (BTW set by GvSTASH later)
3569              
3570             # See #305 Encode::XS: XS objects are often stored as SvIV(SvRV(obj)). The real
3571             # address needs to be patched after the XS object is initialized.
3572             # But how detect them properly?
3573             # Detect ptr to extern symbol in shared library and remap it in init2
3574             # Safe and mandatory currently only Net-DNS-0.67 - 0.74.
3575             # svop const or pad OBJECT,IOK
3576 0 0 0     0 if (((!$ITHREADS
      0        
      0        
3577             and $fullname
3578             and $fullname =~ /^svop const|^padop|^Encode::Encoding| :pad\[1\]/)
3579             or $ITHREADS)
3580             and $sv->IVX > LOWEST_IMAGEBASE # some crazy heuristic for a sharedlibrary ptr in .data (> image_base)
3581             and ref($sv->SvSTASH) ne 'B::SPECIAL')
3582             {
3583 0         0 $ivx = patch_dlsym($sv, $fullname, $ivx);
3584             }
3585             }
3586              
3587 0         0 my $tmp_pvsym = $pvsym;
3588 0 0       0 if ($PERL510) {
3589 0 0       0 if ($sv->FLAGS & SVf_ROK) { # sv => sv->RV cannot be initialized static.
3590 0 0       0 $init->add(sprintf("SvRV_set(&sv_list[%d], (SV*)%s);", $svsect->index+1, $pvsym))
3591             if $pvsym ne '';
3592 0         0 $pvsym = 'NULL';
3593 0         0 $static = 1;
3594             }
3595 0 0       0 if ($PERL514) {
3596 0 0 0     0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3597 0         0 $xpvmgsect->comment("STASH, MAGIC, cur, len, xiv_u, xnv_u");
3598 0         0 $xpvmgsect->add(sprintf("Nullhv, {0}, %u, %u, {%s}, {%s}",
3599             $cur, $len, $ivx, $nvx));
3600             } else {
3601 0         0 $xpvmgsect->comment("xnv_u, cur, len, xiv_u, xmg_u, xmg_stash");
3602 0         0 $xpvmgsect->add(sprintf("{%s}, %u, %u, {%s}, {0}, Nullhv",
3603             $nvx, $cur, $len, $ivx));
3604             }
3605 0 0       0 $svsect->add(sprintf("&xpvmg_list[%d], $u32fmt, 0x%x, {%s}",
    0          
3606             $xpvmgsect->index, $sv->REFCNT, $flags,
3607             $tmp_pvsym eq 'NULL' ? '0' :
3608             ($C99?".svu_pv=(char*)":"(char*)").$tmp_pvsym));
3609             }
3610             else {
3611 0 0 0     0 if ($pvsym =~ /PL_sv_undef/ and $ITHREADS) {
3612 0         0 $pvsym = 'NULL'; # Moose 5.8.9d
3613             }
3614 0         0 $xpvmgsect->add(sprintf("(char*)%s, %u, %u, %s, %s, 0, 0",
3615             $pvsym, $cur, $len, $ivx, $nvx));
3616 0         0 $svsect->add(sprintf("&xpvmg_list[%d], $u32fmt, 0x%x",
3617             $xpvmgsect->index, $sv->REFCNT, $flags));
3618             }
3619 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3620 0         0 my $s = "sv_list[".$svsect->index."]";
3621 0 0 0     0 if ( !$static ) { # do not overwrite RV slot (#273)
    0          
3622             # XXX comppadnames need &PL_sv_undef instead of 0 (?? which testcase?)
3623 0 0       0 if ($PERL510) {
3624 0         0 $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3625             } else {
3626 0         0 $init->add( savepvn( sprintf( "xpvmg_list[%d].xpv_pv", $xpvmgsect->index ),
3627             $pv, $sv, $cur ) );
3628             }
3629             } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3630 0         0 $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3631             }
3632 0         0 $sym = savesym( $sv, "&".$s );
3633 0         0 $sv->save_magic($fullname);
3634 0         0 return $sym;
3635             }
3636              
3637             # mark threads::shared to be xs-loaded
3638             sub mark_threads {
3639 0 0   0 0 0 if ( $INC{'threads.pm'} ) {
3640 0         0 my $stash = 'threads';
3641 0         0 mark_package($stash);
3642 0         0 $use_xsloader = 1;
3643 0         0 $xsub{$stash} = 'Dynamic-' . $INC{'threads.pm'};
3644 0 0       0 warn "mark threads for 'P' magic\n" if $debug{mg};
3645             } else {
3646 0 0       0 warn "ignore to mark threads for 'P' magic\n" if $debug{mg};
3647             }
3648 0 0       0 if ( $INC{'threads/shared.pm'} ) {
3649 0         0 my $stash = 'threads::shared';
3650 0         0 mark_package($stash);
3651             # XXX why is this needed? threads::shared should be initialized automatically
3652 0         0 $use_xsloader = 1; # ensure threads::shared is initialized
3653 0         0 $xsub{$stash} = 'Dynamic-' . $INC{'threads/shared.pm'};
3654 0 0       0 warn "mark threads::shared for 'P' magic\n" if $debug{mg};
3655             } else {
3656 0 0       0 warn "ignore to mark threads::shared for 'P' magic\n" if $debug{mg};
3657             }
3658             }
3659              
3660             sub B::PVMG::save_magic {
3661 0     0   0 my ($sv, $fullname) = @_;
3662 0         0 my $sv_flags = $sv->FLAGS;
3663 0         0 my $pkg;
3664 0 0 0     0 return if $fullname and $fullname eq '%B::C::';
3665 0 0       0 if ($debug{mg}) {
3666 0         0 my $flagspv = "";
3667 0 0       0 $fullname = '' unless $fullname;
3668 0 0 0     0 $flagspv = $sv->flagspv if $debug{flags} and $PERL510 and !$sv->MAGICAL;
      0        
3669             warn sprintf( "saving magic for %s %s (0x%x) flags=0x%x%s - called from %s:%s\n",
3670             B::class($sv), $fullname, $$sv, $sv_flags, $debug{flags} ? "(".$flagspv.")" : "",
3671 0 0       0 @{[(caller(1))[3]]}, @{[(caller(1))[2]]});
  0         0  
  0         0  
3672             }
3673              
3674             # crashes on STASH=0x18 with HV PERL_MAGIC_overload_table stash %version:: flags=0x3280000c
3675             # issue267 GetOpt::Long SVf_AMAGIC|SVs_RMG|SVf_OOK
3676             # crashes with %Class::MOP::Instance:: flags=0x2280000c also
3677 0 0 0     0 if (ref($sv) eq 'B::HV' and $] > 5.018 and $sv->MAGICAL and $fullname =~ /::$/) {
    0 0        
      0        
      0        
      0        
3678 0 0       0 warn sprintf("skip SvSTASH for overloaded HV %s flags=0x%x\n", $fullname, $sv_flags)
3679             if $verbose;
3680             # [cperl #60] not only overloaded, version also
3681             } elsif (ref($sv) eq 'B::HV' and $] > 5.018 and $fullname =~ /(version|File)::$/) {
3682 0 0       0 warn sprintf("skip SvSTASH for %s flags=0x%x\n", $fullname, $sv_flags)
3683             if $verbose;
3684             } else {
3685 0         0 my $pkgsym;
3686 0         0 $pkg = $sv->SvSTASH;
3687 0 0 0     0 if ($pkg and $$pkg) {
3688 0 0       0 my $pkgname = $pkg->can('NAME') ? $pkg->NAME : $pkg->NAME_HEK."::DESTROY";
3689             warn sprintf("stash isa class \"%s\" (%s)\n", $pkgname, ref $pkg)
3690 0 0 0     0 if $debug{mg} or $debug{gv};
3691             # 361 do not force dynaloading IO via IO::Handle upon us
3692             # core already initialized this stash for us
3693 0 0 0     0 unless ($fullname eq 'main::STDOUT' and $] >= 5.018) {
3694 0 0       0 if (ref $pkg eq 'B::HV') {
3695 0 0 0     0 if ($fullname !~ /::$/ or $B::C::stash) {
3696 0         0 $pkgsym = $pkg->save($fullname);
3697             } else {
3698 0         0 $pkgsym = savestashpv($pkgname);
3699             }
3700             } else {
3701 0         0 $pkgsym = 'NULL';
3702             }
3703              
3704             warn sprintf( "xmg_stash = \"%s\" as %s\n", $pkgname, $pkgsym )
3705 0 0 0     0 if $debug{mg} or $debug{gv};
3706             # Q: Who is initializing our stash from XS? ->save is missing that.
3707             # A: We only need to init it when we need a CV
3708             # defer for XS loaded stashes with AMT magic
3709 0 0       0 if (ref $pkg eq 'B::HV') {
3710 0         0 $init->add( sprintf( "SvSTASH_set(s\\_%x, (HV*)s\\_%x);", $$sv, $$pkg ) );
3711 0         0 $init->add( sprintf( "SvREFCNT((SV*)s\\_%x) += 1;", $$pkg ) );
3712 0 0       0 $init->add("++PL_sv_objcount;") unless ref($sv) eq "B::IO";
3713             # XXX
3714             #push_package($pkg->NAME); # correct code, but adds lots of new stashes
3715             }
3716             }
3717             }
3718             }
3719 0 0 0     0 $init->add(sprintf("SvREADONLY_off((SV*)s\\_%x);", $$sv))
3720             if $sv_flags & SVf_READONLY and ref($sv) ne 'B::HV';
3721              
3722             # Protect our SVs against non-magic or SvPAD_OUR. Fixes tests 16 and 14 + 23
3723 0 0 0     0 if ($PERL510 and !($sv->MAGICAL or $sv_flags & SVf_AMAGIC)) {
      0        
3724             warn sprintf("Skipping non-magical PVMG type=%d, flags=0x%x%s\n",
3725             $sv_flags && 0xff, $sv_flags, $debug{flags} ? "(".$sv->flagspv.")" : "")
3726 0 0 0     0 if $debug{mg};
    0          
3727 0         0 return '';
3728             }
3729              
3730             # disabled. testcase: t/testm.sh Path::Class
3731 0         0 if (0 and $PERL518 and $sv_flags & SVf_AMAGIC) {
3732             my $name = $fullname;
3733             $name =~ s/^%(.*)::$/$1/;
3734             $name = $pkg->NAME if $pkg and $$pkg;
3735             warn sprintf("initialize overload cache for %s\n", $fullname )
3736             if $debug{mg} or $debug{gv};
3737             # This is destructive, it removes the magic instead of adding it.
3738             #$init1->add(sprintf("Gv_AMG(%s); /* init overload cache for %s */", savestashpv($name),
3739             # $fullname));
3740             }
3741              
3742 0         0 my @mgchain = $sv->MAGIC;
3743 0         0 my ( $mg, $type, $obj, $ptr, $len, $ptrsv );
3744 0         0 my $magic = '';
3745 0         0 foreach $mg (@mgchain) {
3746 0         0 $type = $mg->TYPE;
3747 0         0 $ptr = $mg->PTR;
3748 0         0 $len = $mg->LENGTH;
3749 0         0 $magic .= $type;
3750 0 0       0 if ( $debug{mg} ) {
3751 0         0 warn sprintf( "%s %s magic 0x%x\n", $fullname, cchar($type), $mg->FLAGS );
3752             #eval {
3753             # warn sprintf( "magic %s (0x%x), obj %s (0x%x), type %s, ptr %s\n",
3754             # B::class($sv), $$sv, B::class($obj), $$obj, cchar($type),
3755             # cstring($ptr) );
3756             #};
3757             }
3758              
3759 0 0       0 unless ( $type =~ /^[rDn]$/ ) { # r - test 23 / D - Getopt::Long
3760             # 5.10: Can't call method "save" on unblessed reference
3761             #warn "Save MG ". $obj . "\n" if $PERL510;
3762             # 5.11 'P' fix in B::IV::save, IV => RV
3763 0         0 $obj = $mg->OBJ;
3764 0 0 0     0 $obj->save($fullname)
3765             unless $PERL510 and ref $obj eq 'SCALAR';
3766 0 0       0 mark_threads if $type eq 'P';
3767             }
3768              
3769 0 0       0 if ( $len == HEf_SVKEY ) {
    0          
    0          
    0          
    0          
    0          
3770             # The pointer is an SV* ('s' sigelem e.g.)
3771             # XXX On 5.6 ptr might be a SCALAR ref to the PV, which was fixed later
3772 0 0 0     0 if (ref($ptr) eq 'SCALAR') {
    0          
3773 0         0 $ptrsv = svref_2object($ptr)->save($fullname);
3774             } elsif ($ptr and ref $ptr) {
3775 0         0 $ptrsv = $ptr->save($fullname);
3776             } else {
3777 0         0 $ptrsv = 'NULL';
3778             }
3779 0 0       0 warn "MG->PTR is an SV*\n" if $debug{mg};
3780 0         0 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, (char *)%s, %d);",
3781             $$sv, $$obj, cchar($type), $ptrsv, $len));
3782 0 0       0 if (!($mg->FLAGS & 2)) {
3783 0         0 mg_RC_off($mg, $sv, $type);
3784             }
3785             }
3786             # coverage $Template::Stash::PRIVATE
3787             elsif ( $type eq 'r' ) { # qr magic, for 5.6 done in C.xs. test 20
3788 0 0       0 my $rx = $PERL56 ? ${$mg->OBJ} : $mg->REGEX;
  0         0  
3789             # stored by some PMOP *pm = cLOGOP->op_other (pp_ctl.c) in C.xs
3790 0         0 my $pmop = $Regexp{$rx};
3791 0 0       0 if (!$pmop) {
3792 0         0 warn "Warning: C.xs PMOP missing for QR\n";
3793             } else {
3794 0         0 my ($resym, $relen);
3795 0 0       0 if ($PERL56) {
3796 0         0 ($resym, $relen) = savere( $pmop->precomp ); # 5.6 has precomp only in PMOP
3797 0 0       0 ($resym, $relen) = savere( $mg->precomp ) unless $relen;
3798             } else {
3799 0         0 ($resym, $relen) = savere( $mg->precomp );
3800             }
3801 0         0 my $pmsym = $pmop->save(0, $fullname);
3802 0 0       0 if ($PERL510) {
3803 0         0 push @B::C::static_free, $resym;
3804 0         0 $init->add( split /\n/,
3805             sprintf <pmflags, $$sv, cchar($type), cstring($ptr), $len );
3806             {
3807             REGEXP* rx = CALLREGCOMP((SV* const)%s, %d);
3808             sv_magic((SV*)s\\_%x, (SV*)rx, %s, %s, %d);
3809             }
3810             CODE1
3811             }
3812             else {
3813 0         0 $pmsym =~ s/\(OP\*\)\&pmop_list/&pmop_list/;
3814 0         0 $init->add( split /\n/,
3815             sprintf <
3816             {
3817             REGEXP* rx = pregcomp((char*)$resym,(char*)($resym + $relen), (PMOP*)$pmsym);
3818             sv_magic((SV*)s\\_%x, (SV*)rx, %s, %s, %d);
3819             }
3820             CODE2
3821             }
3822             }
3823             }
3824             elsif ( $type eq 'D' ) { # XXX regdata AV - coverage? i95, 903
3825             # see Perl_mg_copy() in mg.c
3826 0 0       0 $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
3827             $$sv, $fullname eq 'main::-' ? 0 : $$sv, "'D'", cstring($ptr), $len ));
3828             }
3829             elsif ( $type eq 'n' ) { # shared_scalar is from XS dist/threads-shared
3830             # XXX check if threads is loaded also? otherwise it is only stubbed
3831 0         0 mark_threads;
3832 0         0 $init->add(sprintf("sv_magic((SV*)s\\_%x, Nullsv, %s, %s, %d);",
3833             $$sv, "'n'", cstring($ptr), $len ));
3834             }
3835             elsif ( $type eq 'c' ) { # and !$PERL518
3836 0         0 $init->add(sprintf(
3837             "/* AMT overload table for the stash %s s\\_%x is generated dynamically */",
3838             $fullname, $$sv ));
3839             }
3840             elsif ( $type eq ':' ) { # symtab magic
3841             # search $ptr in list of pmops and replace it. e.g. (char*)&pmop_list[0]
3842 0         0 my $pmop_ptr = unpack("J", $mg->PTR);
3843 0         0 my $pmop;
3844 0 0       0 $pmop = $B::C::Regexp{$pmop_ptr} if defined $pmop_ptr;
3845 0 0       0 my $pmsym = $pmop ? $pmop->save(0, $fullname)
3846             : ''; #sprintf('&pmop_list[%u]', $pmopsect->index);
3847 0 0 0     0 warn sprintf("pmop 0x%x not found in our B::C Regexp hash\n", $pmop_ptr || 'undef')
      0        
3848             if !$pmop and $verbose;
3849 0 0       0 $init->add("{\tU32 elements;", # toke.c: PL_multi_open == '?'
    0          
3850             sprintf("\tMAGIC *mg = sv_magicext((SV*)s\\_%x, 0, ':', 0, 0, 0);", $$sv),
3851             "\telements = mg->mg_len / sizeof(PMOP**);",
3852             "\tRenewc(mg->mg_ptr, elements + 1, PMOP*, char);",
3853             ($pmop
3854             ? (sprintf("\t((OP**)mg->mg_ptr) [elements++] = (OP*)%s;", $pmsym))
3855             : ( defined $pmop_ptr
3856             ? sprintf( "\t((OP**)mg->mg_ptr) [elements++] = (OP*)s\\_%x;", $pmop_ptr ) : '' )),
3857             "\tmg->mg_len = elements * sizeof(PMOP**);", "}");
3858             }
3859             else {
3860 0         0 $init->add(sprintf(
3861             "sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
3862             $$sv, $$obj, cchar($type), cstring($ptr), $len));
3863 0 0       0 if (!($mg->FLAGS & 2)) {
3864 0         0 mg_RC_off($mg, $sv, $type);
3865             }
3866             }
3867             }
3868 0 0 0     0 $init->add(sprintf("SvREADONLY_on((SV*)s\\_%x);", $$sv))
3869             if $sv_flags & SVf_READONLY and ref($sv) ne 'B::HV';
3870 0         0 $magic;
3871             }
3872              
3873             # Since 5.11 also called by IV::save (SV -> IV)
3874             sub B::RV::save {
3875 0     0   0 my ($sv, $fullname) = @_;
3876 0         0 my $sym = objsym($sv);
3877 0 0       0 return $sym if defined $sym;
3878             warn sprintf( "Saving RV %s (0x%x) - called from %s:%s\n",
3879 0         0 B::class($sv), $$sv, @{[(caller(1))[3]]}, @{[(caller(1))[2]]})
  0         0  
3880 0 0       0 if $debug{sv};
3881              
3882 0         0 my $rv = save_rv($sv, $fullname);
3883 0 0       0 return '0' unless $rv;
3884 0 0       0 if ($PERL510) {
3885 0         0 $svsect->comment( "any, refcnt, flags, sv_u" );
3886             # 5.22 has a wrong RV->FLAGS (https://github.com/perl11/cperl/issues/63)
3887 0         0 my $flags = $sv->FLAGS;
3888 0 0 0     0 $flags = 0x801 if $flags & 9 and $PERL522; # not a GV but a ROK IV (21)
3889             # 5.10 has no struct xrv anymore, just sv_u.svu_rv. static or dynamic?
3890             # initializer element is computable at load time
3891 0 0 0     0 $svsect->add( sprintf( "ptr_undef, $u32fmt, 0x%x, {%s}", $sv->REFCNT, $flags,
3892             (($C99 && is_constant($rv)) ? ".svu_rv=$rv" : "0 /*-> $rv */")));
3893 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3894 0         0 my $s = "sv_list[".$svsect->index."]";
3895             # 354 defined needs SvANY
3896 0 0 0     0 $init->add( sprintf("$s.sv_any = (char*)&$s - %d;", $Config{ptrsize}))
3897             if $] > 5.019 or $ITHREADS;
3898 0 0 0     0 unless ($C99 && is_constant($rv)) {
3899 0 0       0 if ( $rv =~ /get_cv/ ) {
3900 0         0 $init2->add( "$s.sv_u.svu_rv = (SV*)$rv;" ) ;
3901             } else {
3902 0         0 $init->add( "$s.sv_u.svu_rv = (SV*)$rv;" ) ;
3903             }
3904             }
3905 0         0 return savesym( $sv, "&".$s );
3906             }
3907             else {
3908             # GVs need to be handled at runtime
3909 0 0 0     0 if ( ref( $sv->RV ) eq 'B::GV' or $rv =~ /^gv_list/) {
    0 0        
    0          
3910 0         0 $xrvsect->add("Nullsv /* $rv */");
3911 0         0 $init->add(
3912             sprintf( "xrv_list[%d].xrv_rv = (SV*)%s;", $xrvsect->index, $rv ) );
3913             }
3914             # and stashes, too
3915             elsif ( $sv->RV->isa('B::HV') && $sv->RV->NAME ) {
3916 0         0 $xrvsect->add("Nullsv /* $rv */");
3917 0         0 $init->add(
3918             sprintf( "xrv_list[%d].xrv_rv = (SV*)%s;", $xrvsect->index, $rv ) );
3919             }
3920             # one more: bootstrapped XS CVs (test Class::MOP, no simple testcase yet)
3921             # dynamic; so we need to inc it
3922             elsif ( $rv =~ /get_cv/ ) {
3923 0         0 $xrvsect->add("Nullsv /* $rv */");
3924 0         0 $init2->add(
3925             sprintf( "xrv_list[%d].xrv_rv = (SV*)SvREFCNT_inc(%s);", $xrvsect->index, $rv ) );
3926             }
3927             else {
3928             #$xrvsect->add($rv); # not static initializable (e.g. cv160 for ExtUtils::Install)
3929 0         0 $xrvsect->add("Nullsv /* $rv */");
3930 0         0 $init->add(
3931             sprintf( "xrv_list[%d].xrv_rv = (SV*)SvREFCNT_inc(%s);", $xrvsect->index, $rv ) );
3932             }
3933 0         0 $svsect->comment( "any, refcnt, flags" );
3934 0         0 $svsect->add(sprintf("&xrv_list[%d], $u32fmt, 0x%x",
3935             $xrvsect->index, $sv->REFCNT, $sv->FLAGS));
3936 0 0       0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3937 0         0 my $s = "sv_list[".$svsect->index."]";
3938 0         0 return savesym( $sv, "&".$s );
3939             }
3940             }
3941              
3942             sub get_isa ($) {
3943 0     0 0 0 my $name = shift;
3944 0 0       0 if ($PERL510) {
3945 0 0       0 if (is_using_mro()) { # mro.xs loaded. c3 or dfs
3946 0         0 return @{mro::get_linear_isa($name)};
  0         0  
3947             } else { # dfs only, without loading mro
3948 0         0 return @{B::C::get_linear_isa($name)};
  0         0  
3949             }
3950             } else {
3951 55     55   429 no strict 'refs';
  55         73  
  55         7474  
3952 0         0 my $s = "$name\::";
3953 0 0       0 if (exists(${$s}{ISA})) {
  0         0  
3954 0 0       0 if (exists(${$s}{ISA}{ARRAY})) {
  0         0  
3955 0         0 return @{ "$s\::ISA" };
  0         0  
3956             }
3957             }
3958             }
3959             }
3960              
3961             # try_isa($pkg,$name) returns the found $pkg for the method $pkg::$name
3962             # If a method can be called (via UNIVERSAL::can) search the ISA's. No AUTOLOAD needed.
3963             # XXX issue 64, empty @ISA if a package has no subs. in Bytecode ok
3964             sub try_isa {
3965 0     0 0 0 my ( $cvstashname, $cvname ) = @_;
3966 0 0 0     0 return 0 unless defined $cvstashname && defined $cvname;
3967 0 0       0 if (my $found = $isa_cache{"$cvstashname\::$cvname"}) {
3968 0         0 return $found;
3969             }
3970 55     55   245 no strict 'refs';
  55         80  
  55         23846  
3971             # XXX theoretically a valid shortcut. In reality it fails when $cvstashname is not loaded.
3972             # return 0 unless $cvstashname->can($cvname);
3973 0         0 my @isa = get_isa($cvstashname);
3974             warn sprintf( "No definition for sub %s::%s. Try \@%s::ISA=(%s)\n",
3975             $cvstashname, $cvname, $cvstashname, join(",",@isa))
3976 0 0       0 if $debug{cv};
3977 0         0 for (@isa) { # global @ISA or in pad
3978 0 0       0 next if $_ eq $cvstashname;
3979 0 0       0 warn sprintf( "Try &%s::%s\n", $_, $cvname ) if $debug{cv};
3980 0 0       0 if (defined(&{$_ .'::'. $cvname})) {
  0         0  
3981 0 0       0 if (exists(${$cvstashname.'::'}{ISA})) {
  0         0  
3982 0         0 svref_2object( \@{$cvstashname . '::ISA'} )->save("$cvstashname\::ISA");
  0         0  
3983             }
3984 0         0 $isa_cache{"$cvstashname\::$cvname"} = $_;
3985 0         0 mark_package($_, 1); # force
3986 0         0 return $_;
3987             } else {
3988 0         0 $isa_cache{"$_\::$cvname"} = 0;
3989 0 0       0 if (get_isa($_)) {
3990 0         0 my $parent = try_isa($_, $cvname);
3991 0 0       0 if ($parent) {
3992 0         0 $isa_cache{"$_\::$cvname"} = $parent;
3993 0         0 $isa_cache{"$cvstashname\::$cvname"} = $parent;
3994 0 0       0 warn sprintf( "Found &%s::%s\n", $parent, $cvname ) if $debug{gv};
3995 0 0       0 if (exists(${$parent.'::'}{ISA})) {
  0         0  
3996 0 0       0 warn "save \@$parent\::ISA\n" if $debug{pkg};
3997 0         0 svref_2object( \@{$parent . '::ISA'} )->save("$parent\::ISA");
  0         0  
3998             }
3999 0 0       0 if (exists(${$_.'::'}{ISA})) {
  0         0  
4000 0 0       0 warn "save \@$_\::ISA\n" if $debug{pkg};
4001 0         0 svref_2object( \@{$_ . '::ISA'} )->save("$_\::ISA");
  0         0  
4002             }
4003 0         0 return $parent;
4004             }
4005             }
4006             }
4007             }
4008 0         0 return 0; # not found
4009             }
4010              
4011             sub load_utf8_heavy {
4012 0 0   0 0 0 return if $savINC{"utf8_heavy.pl"};
4013              
4014 0         0 require 'utf8_heavy.pl';
4015 0         0 mark_package('utf8_heavy.pl');
4016 0         0 $curINC{'utf8_heavy.pl'} = $INC{'utf8_heavy.pl'};
4017 0         0 $savINC{"utf8_heavy.pl"} = 1;
4018 0         0 add_hashINC("utf8");
4019              
4020             # FIXME: we want to use add_hashINC for utf8_heavy, inc_packname should return an array
4021             # add_hashINC("utf8_heavy.pl");
4022              
4023             # In CORE utf8::SWASHNEW is demand-loaded from utf8 with Perl_load_module()
4024             # It adds about 1.6MB exe size 32-bit.
4025 0         0 svref_2object( \&{"utf8\::SWASHNEW"} )->save;
  0         0  
4026              
4027 0         0 return 1;
4028             }
4029              
4030             # If the sub or method is not found:
4031             # 1. try @ISA, mark_package and return.
4032             # 2. try UNIVERSAL::method
4033             # 3. try compile-time expansion of AUTOLOAD to get the goto &sub addresses
4034             sub try_autoload {
4035 0     0 0 0 my ( $cvstashname, $cvname ) = @_;
4036 55     55   263 no strict 'refs';
  55         88  
  55         2397  
4037 0 0 0     0 return unless defined $cvstashname && defined $cvname;
4038 0 0       0 return 1 if try_isa($cvstashname, $cvname);
4039              
4040 55     55   191 no strict 'refs';
  55         89  
  55         57270  
4041 0 0       0 if (defined(*{'UNIVERSAL::'. $cvname}{CODE})) {
  0         0  
4042 0 0       0 warn "Found UNIVERSAL::$cvname\n" if $debug{cv};
4043 0         0 return svref_2object( \&{'UNIVERSAL::'.$cvname} );
  0         0  
4044             }
4045 0         0 my $fullname = $cvstashname . '::' . $cvname;
4046             warn sprintf( "No definition for sub %s. Try %s::AUTOLOAD\n",
4047 0 0       0 $fullname, $cvstashname ) if $debug{cv};
4048 0 0       0 if ($fullname eq 'utf8::SWASHNEW') {
4049             # utf8_heavy was loaded so far, so defer to a demand-loading stub
4050             # always require utf8_heavy, do not care if it s already in
4051 0     0   0 my $stub = sub { require 'utf8_heavy.pl'; goto &utf8::SWASHNEW };
  0         0  
  0         0  
4052 0         0 return svref_2object( $stub );
4053             }
4054              
4055             # Handle AutoLoader classes. Any more general AUTOLOAD
4056             # use should be handled by the class itself.
4057 0         0 my @isa = get_isa($cvstashname);
4058 0 0 0     0 if ( $cvstashname =~ /^POSIX|Storable|DynaLoader|Net::SSLeay|Class::MethodMaker$/
      0        
4059 0         0 or (exists ${$cvstashname.'::'}{AUTOLOAD} and grep( $_ eq "AutoLoader", @isa ) ) )
4060             {
4061             # Tweaked version of AutoLoader::AUTOLOAD
4062 0         0 my $dir = $cvstashname;
4063 0         0 $dir =~ s(::)(/)g;
4064 0 0       0 warn "require \"auto/$dir/$cvname.al\"\n" if $debug{cv};
4065 0 0       0 eval { local $SIG{__DIE__}; require "auto/$dir/$cvname.al" unless $INC{"auto/$dir/$cvname.al"} };
  0         0  
  0         0  
4066 0 0       0 unless ($@) {
4067 0 0       0 warn "Forced load of \"auto/$dir/$cvname.al\"\n" if $verbose;
4068 0 0       0 return svref_2object( \&$fullname )
4069             if defined &$fullname;
4070             }
4071             }
4072              
4073             # XXX Still not found, now it's getting dangerous (until 5.10 only)
4074             # Search and call ::AUTOLOAD (=> ROOT and XSUB) (test 27, 5.8)
4075             # Since 5.10 AUTOLOAD xsubs are already resolved
4076 0 0 0     0 if (exists ${$cvstashname.'::'}{AUTOLOAD} and !$PERL510) {
  0         0  
4077 0         0 my $auto = \&{$cvstashname.'::AUTOLOAD'};
  0         0  
4078             # Tweaked version of __PACKAGE__::AUTOLOAD
4079 0         0 $AutoLoader::AUTOLOAD = ${$cvstashname.'::AUTOLOAD'} = "$cvstashname\::$cvname";
  0         0  
4080              
4081             # Prevent eval from polluting STDOUT,STDERR and our c code.
4082             # With a debugging perl STDERR is written
4083 0         0 local *REALSTDOUT;
4084 0 0       0 local *REALSTDERR unless $DEBUGGING;
4085 0         0 open(REALSTDOUT,">&STDOUT");
4086 0 0       0 open(REALSTDERR,">&STDERR") unless $DEBUGGING;
4087 0         0 open(STDOUT,">","/dev/null");
4088 0 0       0 open(STDERR,">","/dev/null") unless $DEBUGGING;
4089 0 0       0 warn "eval \&$cvstashname\::AUTOLOAD\n" if $debug{cv};
4090 0         0 eval { &$auto };
  0         0  
4091 0         0 open(STDOUT,">&REALSTDOUT");
4092 0 0       0 open(STDERR,">&REALSTDERR") unless $DEBUGGING;
4093              
4094 0 0       0 unless ($@) {
4095             # we need just the empty auto GV, $cvname->ROOT and $cvname->XSUB,
4096             # but not the whole CV optree. XXX This still fails with 5.8
4097 0         0 my $cv = svref_2object( \&{$fullname} );
  0         0  
4098 0         0 return $cv;
4099             }
4100             }
4101              
4102             # XXX TODO Check Selfloader (test 31?)
4103 0         0 svref_2object( \*{$cvstashname.'::AUTOLOAD'} )->save
4104 0 0 0     0 if $cvstashname and exists ${$cvstashname.'::'}{AUTOLOAD};
  0         0  
4105 0         0 svref_2object( \*{$cvstashname.'::CLONE'} )->save
4106 0 0 0     0 if $cvstashname and exists ${$cvstashname.'::'}{CLONE};
  0         0  
4107             }
4108       0 0   sub Dummy_initxs { }
4109              
4110             sub B::CV::is_lexsub {
4111 0     0   0 my ($cv, $gv) = @_;
4112             # logical shortcut perl5 bug since ~ 5.19: testcc.sh 42
4113             # return ($PERL518 and (!$gv or ref($gv) eq 'B::SPECIAL') and $cv->can('NAME_HEK'));
4114 0 0 0     0 return ($PERL518 and (!$gv or ref($gv) eq 'B::SPECIAL') and $cv->can('NAME_HEK')) ? 1 : 0;
4115             }
4116              
4117             sub is_phase_name {
4118 0 0   0 0 0 $_[0] =~ /^(BEGIN|INIT|UNITCHECK|CHECK|END)$/ ? 1 : 0;
4119             }
4120              
4121             sub B::CV::save {
4122 0     0   0 my ($cv, $origname) = @_;
4123 0         0 my $sym = objsym($cv);
4124 0 0       0 if ( defined($sym) ) {
4125 0 0 0     0 warn sprintf( "CV 0x%x already saved as $sym\n", $$cv ) if $$cv and $debug{cv};
4126 0         0 return $sym;
4127             }
4128 0         0 my $gv = $cv->GV;
4129 0         0 my ( $cvname, $cvstashname, $fullname, $isutf8 );
4130 0         0 $fullname = '';
4131 0         0 my $CvFLAGS = $cv->CvFLAGS;
4132 0 0 0     0 if ($gv and $$gv) {
    0          
4133 0         0 $cvstashname = $gv->STASH->NAME;
4134 0         0 $cvname = $gv->NAME;
4135 0   0     0 $isutf8 = ($gv->FLAGS & SVf_UTF8) || ($gv->STASH->FLAGS & SVf_UTF8);
4136 0         0 $fullname = $cvstashname.'::'.$cvname;
4137             # XXX gv->EGV does not really help here
4138 0 0 0     0 if ($PERL522 and $cvname eq '__ANON__') {
4139 0 0       0 if ($origname) {
4140             warn sprintf( "CV with empty PVGV %s -> %s\n",
4141 0 0       0 $fullname, $origname) if $debug{cv};
4142 0         0 $cvname = $fullname = $origname;
4143 0 0       0 $cvname =~ s/^\Q$cvstashname\E::(.*)( :pad\[.*)?$/$1/ if $cvstashname;
4144 0         0 $cvname =~ s/^.*:://;
4145 0 0       0 if ($cvname =~ m/ :pad\[.*$/) {
4146 0         0 $cvname =~ s/ :pad\[.*$//;
4147 0 0       0 $cvname = '__ANON__' if is_phase_name($cvname);
4148 0         0 $fullname = $cvstashname.'::'.$cvname;
4149             }
4150 0 0       0 warn sprintf( "empty -> %s\n", $cvname) if $debug{cv};
4151             } else {
4152 0         0 $cvname = $gv->EGV->NAME;
4153             warn sprintf( "CV with empty PVGV %s -> %s::%s\n",
4154 0 0       0 $fullname, $cvstashname, $cvname) if $debug{cv};
4155 0         0 $fullname = $cvstashname.'::'.$cvname;
4156             }
4157             }
4158             warn sprintf( "CV 0x%x as PVGV 0x%x %s CvFLAGS=0x%x\n",
4159 0 0       0 $$cv, $$gv, $fullname, $CvFLAGS ) if $debug{cv};
4160             # XXX not needed, we already loaded utf8_heavy
4161             #return if $fullname eq 'utf8::AUTOLOAD';
4162 0 0 0     0 return '0' if $all_bc_subs{$fullname} or skip_pkg($cvstashname);
4163 0 0       0 $CvFLAGS &= ~0x400 if $PERL514; # no CVf_CVGV_RC otherwise we cannot set the GV
4164 0 0       0 mark_package($cvstashname, 1) unless $include_package{$cvstashname};
4165             }
4166             elsif ($cv->is_lexsub($gv)) {
4167 0         0 $fullname = $cv->NAME_HEK;
4168 0 0       0 $fullname = '' unless defined $fullname;
4169 0         0 $isutf8 = $cv->FLAGS & SVf_UTF8;
4170 0 0       0 warn sprintf( "CV lexsub NAME_HEK $fullname\n") if $debug{cv};
4171 0 0       0 if ($fullname =~ /^(.*)::(.*?)$/) {
4172 0         0 $cvstashname = $1;
4173 0         0 $cvname = $2;
4174             }
4175             }
4176 0 0       0 $cvstashname = '' unless defined $cvstashname;
4177              
4178             # XXX TODO need to save the gv stash::AUTOLOAD if exists
4179 0         0 my $root = $cv->ROOT;
4180 0         0 my $cvxsub = $cv->XSUB;
4181 0         0 my $isconst;
4182 55     55   270 { no strict 'subs';
  55         76  
  55         21532  
  0         0  
4183 0 0       0 $isconst = $PERL56 ? 0 : $CvFLAGS & CVf_CONST;
4184             }
4185              
4186 0 0 0     0 if ( !$isconst && $cvxsub && ( $cvname ne "INIT" ) ) {
      0        
4187 0         0 my $egv = $gv->EGV;
4188 0         0 my $stashname = $egv->STASH->NAME;
4189 0         0 $fullname = $stashname.'::'.$cvname;
4190 0 0 0     0 if ( $cvname eq "bootstrap" and !$xsub{$stashname} ) {
4191 0         0 my $file = $gv->FILE;
4192 0         0 $decl->add("/* bootstrap $file */");
4193 0 0       0 warn "Bootstrap $stashname $file\n" if $verbose;
4194 0         0 mark_package($stashname);
4195              
4196             # Without DynaLoader we must boot and link static
4197 0 0 0     0 if ( !$Config{usedl} ) {
    0 0        
4198 0         0 $xsub{$stashname} = 'Static';
4199             }
4200             # if it not isa('DynaLoader'), it should hopefully be XSLoaded
4201             # ( attributes being an exception, of course )
4202             elsif ( !UNIVERSAL::isa( $stashname, 'DynaLoader' )
4203             and ($stashname ne 'attributes' || $] >= 5.011))
4204             {
4205 0         0 my $stashfile = $stashname;
4206 0         0 $stashfile =~ s/::/\//g;
4207 0 0       0 if ($file =~ /XSLoader\.pm$/) { # almost always the case
4208 0         0 $file = $INC{$stashfile . ".pm"};
4209             }
4210 0 0       0 unless ($file) { # do the reverse as DynaLoader: soname => pm
4211 0         0 my ($laststash) = $stashname =~ /::([^:]+)$/;
4212 0 0       0 $laststash = $stashname unless $laststash;
4213 0         0 my $sofile = "auto/" . $stashfile . '/' . $laststash . '\.' . $Config{dlext};
4214 0         0 for (@DynaLoader::dl_shared_objects) {
4215 0 0       0 if (m{^(.+/)$sofile$}) {
4216 0         0 $file = $1. $stashfile.".pm"; last;
  0         0  
4217             }
4218             }
4219             }
4220 0         0 $xsub{$stashname} = 'Dynamic-'.$file;
4221 0         0 force_saving_xsloader();
4222             }
4223             else {
4224 0         0 $xsub{$stashname} = 'Dynamic';
4225             # DynaLoader was for sure loaded, before so we execute the branch which
4226             # does walk_syms and add_hashINC
4227 0         0 mark_package('DynaLoader', 1);
4228             }
4229              
4230             # INIT is removed from the symbol table, so this call must come
4231             # from PL_initav->save. Re-bootstrapping will push INIT back in,
4232             # so nullop should be sent.
4233 0 0       0 warn $fullname."\n" if $debug{sub};
4234 0         0 return qq/NULL/;
4235             }
4236             else {
4237             # XSUBs for IO::File, IO::Handle, IO::Socket, IO::Seekable and IO::Poll
4238             # are defined in IO.xs, so let's bootstrap it
4239 0         0 my @IO = qw(IO::File IO::Handle IO::Socket IO::Seekable IO::Poll);
4240 0 0       0 if (grep { $stashname eq $_ } @IO) {
  0         0  
4241             # mark_package('IO', 1);
4242             # $xsub{IO} = 'Dynamic-'. $INC{'IO.pm'}; # XSLoader (issue59)
4243 0         0 svref_2object( \&IO::bootstrap )->save;
4244 0         0 mark_package('IO::Handle', 1);
4245 0         0 mark_package('SelectSaver', 1);
4246             #for (@IO) { # mark all IO packages
4247             # mark_package($_, 1);
4248             #}
4249             }
4250             }
4251 0 0       0 warn $fullname."\n" if $debug{sub};
4252 0 0       0 unless ( in_static_core($stashname, $cvname) ) {
4253 55     55   242 no strict 'refs';
  55         76  
  55         5624  
4254             warn sprintf( "XSUB $fullname CV 0x%x\n", $$cv )
4255 0 0       0 if $debug{cv};
4256 0 0       0 svref_2object( \*{"$stashname\::bootstrap"} )->save
  0         0  
4257             if $stashname;# and defined ${"$stashname\::bootstrap"};
4258             # delsym($cv);
4259 0         0 return get_cv($fullname, 0);
4260             } else { # Those cvs are already booted. Reuse their GP.
4261             # Esp. on windows it is impossible to get at the XS function ptr
4262 0 0       0 warn sprintf( "core XSUB $fullname CV 0x%x\n", $$cv ) if $debug{cv};
4263 0         0 return get_cv($fullname, 0);
4264             }
4265             }
4266 0 0 0     0 if ( !$isconst && $cvxsub && $cvname eq "INIT" ) {
      0        
4267 55     55   211 no strict 'refs';
  55         77  
  55         49480  
4268 0 0       0 warn $fullname."\n" if $debug{sub};
4269 0         0 return svref_2object( \&Dummy_initxs )->save;
4270             }
4271              
4272             # XXX how is ANON with CONST handled? CONST uses XSUBANY [GH #246]
4273 0 0 0     0 if ($isconst and $cvxsub and !is_phase_name($cvname) and
      0        
      0        
      0        
4274             (
4275             (
4276             $PERL522
4277             and !( $CvFLAGS & SVs_PADSTALE )
4278             and !( $CvFLAGS & CVf_WEAKOUTSIDE )
4279             and !( $fullname && $fullname =~ qr{^File::Glob::GLOB}
4280             and ( $CvFLAGS & (CVf_ANONCONST|CVf_CONST) ) )
4281             )
4282             or (!$PERL522 and !($CvFLAGS & CVf_ANON)) )
4283             ) # skip const magic blocks (Attribute::Handlers)
4284             {
4285 0         0 my $stash = $gv->STASH;
4286             #warn sprintf("$cvstashname\::$cvname 0x%x -> XSUBANY", $CvFLAGS) if $debug{cv};
4287 0         0 my $sv = $cv->XSUBANY;
4288             warn sprintf( "CV CONST 0x%x %s::%s -> 0x%x as %s\n", $$gv, $cvstashname, $cvname,
4289 0 0       0 $sv, ref $sv) if $debug{cv};
4290             # warn sprintf( "%s::%s\n", $cvstashname, $cvname) if $debug{sub};
4291 0         0 my $stsym = $stash->save;
4292 0         0 my $name = cstring($cvname);
4293 0 0       0 if ($] >= 5.016) { # need to check 'Encode::XS' constant encodings
4294             # warn "$sv CONSTSUB $name";
4295 0 0 0     0 if ((ref($sv) eq 'B::IV' or ref($sv) eq 'B::PVMG') and $sv->FLAGS & SVf_ROK) {
      0        
4296 0         0 my $rv = $sv->RV;
4297 0 0 0     0 if ($rv->FLAGS & (SVp_POK|SVf_IOK) and $rv->IVX > LOWEST_IMAGEBASE) {
4298 0         0 patch_dlsym($rv, $fullname, $rv->IVX);
4299             }
4300             }
4301             }
4302             # scalarref: t/CORE/v5.22/t/op/const-optree.t at curpad_syms[6]
4303             # main::__ANON__ -> CxPOPSUB_DONE=SCALAR
4304             # TODO Attribute::Handlers #171, test 176
4305 0 0 0     0 if ($sv and ref($sv) and ref($sv) =~ /^(SCALAR|ARRAY|HASH|CODE|REF)$/) {
    0 0        
      0        
4306             # Save XSUBANY, maybe ARRAY or HASH also?
4307 0 0       0 warn "SCALAR const sub $cvstashname::$cvname -> $sv\n" if $debug{cv};
4308 0         0 my $vsym = svref_2object( \$sv )->save;
4309 0         0 my $cvi = "cv".$cv_index++;
4310 0         0 $decl->add("Static CV* $cvi;");
4311 0         0 $init->add("$cvi = newCONSTSUB( $stsym, $name, (SV*)$vsym );");
4312 0         0 return savesym( $cv, $cvi );
4313             }
4314             elsif ($sv and ref($sv) =~ /^B::[ANRPI]/) { # use constant => ()
4315 0         0 my $vsym = $sv->save;
4316 0         0 my $cvi = "cv".$cv_index++;
4317 0         0 $decl->add("Static CV* $cvi;");
4318 0         0 $init->add("$cvi = newCONSTSUB( $stsym, $name, (SV*)$vsym );");
4319 0         0 return savesym( $cv, $cvi );
4320             } else {
4321 0 0       0 warn "Warning: Undefined const sub $cvstashname::$cvname -> $sv\n" if $verbose;
4322             }
4323             }
4324              
4325             # This define is forwarded to the real sv below
4326             # The new method, which saves a SV only works since 5.10 (? Does not work in newer perls)
4327 0         0 my $sv_ix = $svsect->index + 1;
4328 0         0 my $xpvcv_ix;
4329 0         0 my $new_cv_fw = 0;#$PERL510; # XXX this does not work yet
4330 0 0       0 if ($new_cv_fw) {
4331 0         0 $sym = savesym( $cv, "CVIX$sv_ix" );
4332             } else {
4333 0         0 $svsect->add("CVIX$sv_ix");
4334 0 0       0 $svsect->debug( "&".$fullname, $cv->flagspv ) if $debug{flags};
4335 0         0 $xpvcv_ix = $xpvcvsect->index + 1;
4336 0         0 $xpvcvsect->add("XPVCVIX$xpvcv_ix");
4337             # Save symbol now so that GvCV() doesn't recurse back to us via CvGV()
4338 0         0 $sym = savesym( $cv, "&sv_list[$sv_ix]" );
4339             }
4340              
4341             warn sprintf( "saving %s CV 0x%x as %s\n", $fullname, $$cv, $sym )
4342 0 0       0 if $debug{cv};
4343 0 0 0     0 if (!$$root and $] < 5.010) {
4344 0         0 $package_pv = $cvstashname;
4345 0         0 push_package($package_pv);
4346             }
4347 0 0       0 if ($fullname eq 'utf8::SWASHNEW') { # bypass utf8::AUTOLOAD, a new 5.13.9 mess
4348 0         0 load_utf8_heavy();
4349             }
4350              
4351 0 0       0 if ($fullname eq 'IO::Socket::SSL::SSL_Context::new') {
4352 0 0 0     0 if ($IO::Socket::SSL::VERSION ge '1.956' and $IO::Socket::SSL::VERSION lt '1.995') {
4353             # See https://code.google.com/p/perl-compiler/issues/detail?id=317
4354             # https://rt.cpan.org/Ticket/Display.html?id=95452
4355 0         0 warn "Warning: Your IO::Socket::SSL version $IO::Socket::SSL::VERSION is unsupported to create\n".
4356             " a server. You need to upgrade IO::Socket::SSL to at least 1.995 [CPAN #95452]\n";
4357             }
4358             }
4359              
4360 0 0 0     0 if (!$$root && !$cvxsub) {
4361 0         0 my $reloaded;
4362 0 0       0 if ($cvstashname =~ /^(bytes|utf8)$/) { # no autoload, force compile-time
    0          
4363 0         0 force_heavy($cvstashname);
4364 0         0 $cv = svref_2object( \&{"$cvstashname\::$cvname"} );
  0         0  
4365 0         0 $reloaded = 1;
4366             } elsif ($fullname eq 'Coro::State::_jit') { # 293
4367             # need to force reload the jit src
4368 0         0 my ($pl) = grep { m|^Coro/jit-| } keys %INC;
  0         0  
4369 0 0       0 if ($pl) {
4370 0         0 delete $INC{$pl};
4371 0         0 require $pl;
4372 0         0 $cv = svref_2object( \&{$fullname} );
  0         0  
4373 0         0 $reloaded = 1;
4374             }
4375             }
4376 0 0       0 if ($reloaded) {
4377 0         0 $gv = $cv->GV;
4378             warn sprintf( "Redefined CV 0x%x as PVGV 0x%x %s CvFLAGS=0x%x\n",
4379 0 0       0 $$cv, $$gv, $fullname, $CvFLAGS ) if $debug{cv};
4380 0         0 $sym = savesym( $cv, $sym );
4381 0         0 $root = $cv->ROOT;
4382 0         0 $cvxsub = $cv->XSUB;
4383             }
4384             }
4385 0 0 0     0 if ( !$$root && !$cvxsub ) {
4386 0 0       0 if ( my $auto = try_autoload( $cvstashname, $cvname ) ) {
4387 0 0       0 if (ref $auto eq 'B::CV') { # explicit goto or UNIVERSAL
4388 0         0 $root = $auto->ROOT;
4389 0         0 $cvxsub = $auto->XSUB;
4390 0 0       0 if ($$auto) {
4391             # XXX This has now created a wrong GV name!
4392 0         0 my $oldcv = $cv;
4393 0         0 $cv = $auto ; # This is new. i.e. via AUTOLOAD or UNIVERSAL, in another stash
4394 0         0 my $gvnew = $cv->GV;
4395 0 0       0 if ($$gvnew) {
4396 0 0 0     0 if ($cvstashname ne $gvnew->STASH->NAME or $cvname ne $gvnew->NAME) { # UNIVERSAL or AUTOLOAD
4397 0         0 my $newname = $gvnew->STASH->NAME."::".$gvnew->NAME;
4398 0 0       0 warn " New $newname autoloaded. remove old cv\n" if $debug{sub}; # and wrong GV?
4399 0 0       0 unless ($new_cv_fw) {
4400 0         0 $svsect->remove;
4401 0         0 $xpvcvsect->remove;
4402             }
4403 0         0 delsym($oldcv);
4404 0 0       0 return $cv->save($newname) if !$PERL510;
4405              
4406 55     55   268 no strict 'refs';
  55         70  
  55         271721  
4407 0         0 my $newsym = svref_2object( \*{$newname} )->save;
  0         0  
4408 0 0       0 my $cvsym = defined objsym($cv) ? objsym($cv) : $cv->save($newname);
4409 0 0       0 if (my $oldsym = objsym($gv)) {
4410 0 0       0 warn "Alias polluted $oldsym to $newsym\n" if $debug{gv};
4411 0         0 $init->add("$oldsym = $newsym;");
4412 0         0 delsym($gv);
4413             }# else {
4414             #$init->add("GvCV_set(gv_fetchpv(\"$fullname\", GV_ADD, SVt_PV), (CV*)NULL);");
4415             #}
4416 0         0 return $cvsym;
4417             }
4418             }
4419 0         0 $sym = savesym( $cv, "&sv_list[$sv_ix]" ); # GOTO
4420 0 0       0 warn "$fullname GOTO\n" if $verbose;
4421             }
4422             } else {
4423             # Recalculated root and xsub
4424 0         0 $root = $cv->ROOT;
4425 0         0 $cvxsub = $cv->XSUB;
4426 0         0 my $gv = $cv->GV;
4427 0 0       0 if ($$gv) {
4428 0 0 0     0 if ($cvstashname ne $gv->STASH->NAME or $cvname ne $gv->NAME) { # UNIVERSAL or AUTOLOAD
4429 0         0 my $newname = $gv->STASH->NAME."::".$gv->NAME;
4430 0 0       0 warn "Recalculated root and xsub $newname. remove old cv\n" if $verbose;
4431 0         0 $svsect->remove;
4432 0         0 $xpvcvsect->remove;
4433 0         0 delsym($cv);
4434 0         0 return $cv->save($newname);
4435             }
4436             }
4437             }
4438 0 0 0     0 if ( $$root || $cvxsub ) {
4439 0 0 0     0 warn "Successful forced autoload\n" if $verbose and $debug{cv};
4440             }
4441             }
4442             }
4443 0 0       0 if (!$$root) {
4444 0 0 0     0 if ($fullname ne 'threads::tid'
      0        
      0        
4445             and $fullname ne 'main::main::'
4446 0         0 and ($PERL510 and !defined(&{"$cvstashname\::AUTOLOAD"})))
4447             {
4448             # XXX What was here?
4449             }
4450 0 0       0 if (exists &$fullname) {
    0          
4451 0 0       0 warn "Warning: Empty &".$fullname."\n" if $debug{sub};
4452 0 0 0     0 $init->add( "/* empty CV $fullname */" ) if $verbose or $debug{sub};
4453             } elsif ($cv->is_lexsub($gv)) {
4454             # need to find the attached lexical sub (#130 + #341) at run-time
4455             # in the PadNAMES array. So keep the empty PVCV
4456 0 0       0 warn "lexsub &".$fullname." saved as empty $sym\n" if $debug{sub};
4457             } else {
4458 0 0       0 warn "Warning: &".$fullname." not found\n" if $debug{sub};
4459 0 0 0     0 $init->add( "/* CV $fullname not found */" ) if $verbose or $debug{sub};
4460             # This block broke test 15, disabled
4461 0 0 0     0 if ($sv_ix == $svsect->index and !$new_cv_fw) { # can delete, is the last SV
4462             warn "No definition for sub $fullname (unable to autoload), skip CV[$sv_ix]\n"
4463 0 0       0 if $debug{cv};
4464 0         0 $svsect->remove;
4465 0         0 $xpvcvsect->remove;
4466 0         0 delsym( $cv );
4467             # Empty CV (methods) must be skipped not to disturb method resolution
4468             # (e.g. t/testm.sh POSIX)
4469 0         0 return '0';
4470             } else {
4471             # interim &AUTOLOAD saved, cannot delete. e.g. Fcntl, POSIX
4472             warn "No definition for sub $fullname (unable to autoload), stub CV[$sv_ix]\n"
4473 0 0 0     0 if $debug{cv} or $verbose;
4474             # continue, must save the 2 symbols from above
4475             }
4476             }
4477             }
4478              
4479 0         0 my $startfield = 0;
4480 0         0 my $padlist = $cv->PADLIST;
4481 0         0 set_curcv $cv;
4482 0         0 my $padlistsym = 'NULL';
4483 0         0 my $pv = $cv->PV;
4484 0         0 my $xsub = 0;
4485 0         0 my $xsubany = "{0}";
4486 0 0       0 if ($$root) {
    0          
    0          
4487             warn sprintf( "saving op tree for CV 0x%x, root=0x%x\n",
4488             $$cv, $$root )
4489 0 0 0     0 if $debug{cv} and $debug{gv};
4490 0         0 my $ppname = "";
4491 0 0 0     0 if ($cv->is_lexsub($gv)) {
    0          
4492 0 0       0 my $name = $cv->can('NAME_HEK') ? $cv->NAME_HEK : "anonlex";
4493 0         0 $ppname = "pp_lexsub_".$name;
4494 0         0 $fullname = "".$name;
4495             }
4496             elsif ($gv and $$gv) {
4497 0         0 my ($stashname, $gvname);
4498 0         0 $stashname = $gv->STASH->NAME;
4499 0         0 $gvname = $gv->NAME;
4500 0         0 $fullname = $stashname.'::'.$gvname;
4501 0 0       0 $ppname = ( ${ $gv->FORM } == $$cv ) ? "pp_form_" : "pp_sub_";
  0         0  
4502 0 0       0 if ( $gvname ne "__ANON__" ) {
4503 0 0       0 $ppname .= ( $stashname eq "main" ) ? $gvname : "$stashname\::$gvname";
4504 0         0 $ppname =~ s/::/__/g;
4505 0         0 $ppname =~ s/(\W)/sprintf("0x%x", ord($1))/ge;
  0         0  
4506 0 0       0 if ( $gvname eq "INIT" ) {
4507 0         0 $ppname .= "_$initsub_index";
4508 0         0 $initsub_index++;
4509             }
4510             }
4511             }
4512 0 0       0 if ( !$ppname ) {
4513 0         0 $ppname = "pp_anonsub_$anonsub_index";
4514 0         0 $anonsub_index++;
4515             }
4516 0         0 $startfield = saveoptree( $ppname, $root, $cv->START, $padlist->ARRAY ); # XXX padlist is ignored
4517             #warn sprintf( "done saving op tree for CV 0x%x, flags (%s), name %s, root=0x%x => start=%s\n",
4518             # $$cv, $debug{flags}?$cv->flagspv:sprintf("0x%x",$cv->FLAGS), $ppname, $$root, $startfield )
4519             # if $debug{cv};
4520             # XXX missing cv_start for AUTOLOAD on 5.8
4521 0 0       0 $startfield = objsym($root->next) unless $startfield; # 5.8 autoload has only root
4522 0 0       0 $startfield = "0" unless $startfield; # XXX either CONST ANON or empty body
4523 0 0       0 if ($$padlist) {
4524             # XXX readonly comppad names and symbols invalid
4525             #local $B::C::pv_copy_on_grow = 1 if $B::C::ro_inc;
4526             warn sprintf( "saving PADLIST 0x%x for CV 0x%x\n", $$padlist, $$cv )
4527 0 0 0     0 if $debug{cv} and $debug{gv};
4528             # XXX avlen 2
4529 0         0 $padlistsym = $padlist->save($fullname.' :pad', $cv);
4530             warn sprintf( "done saving %s 0x%x for CV 0x%x\n",
4531             $padlistsym, $$padlist, $$cv )
4532 0 0 0     0 if $debug{cv} and $debug{gv};
4533             # do not record a forward for the pad only
4534              
4535             # issue 298: dynamic CvPADLIST(&END) since 5.18 - END{} blocks
4536             # and #169 and #304 Attribute::Handlers
4537 0 0 0     0 if ($] > 5.017 and
      0        
4538             ($B::C::dyn_padlist or $fullname =~ /^(main::END|main::INIT|Attribute::Handlers)/))
4539             {
4540 0         0 $init->add("{ /* &$fullname needs a dynamic padlist */",
4541             " PADLIST *pad;",
4542             " Newxz(pad, sizeof(PADLIST), PADLIST);",
4543             " Copy($padlistsym, pad, sizeof(PADLIST), char);",
4544             " CvPADLIST($sym) = pad;",
4545             "}");
4546             } else {
4547 0         0 $init->add( "CvPADLIST($sym) = $padlistsym;" );
4548             }
4549             }
4550 0 0       0 warn $fullname."\n" if $debug{sub};
4551             }
4552             elsif ($cv->is_lexsub($gv)) {
4553             ;
4554             }
4555             elsif (!exists &$fullname) {
4556 0 0       0 warn $fullname." not found\n" if $debug{sub};
4557             warn "No definition for sub $fullname (unable to autoload)\n"
4558 0 0       0 if $debug{cv};
4559 0 0 0     0 $init->add( "/* $fullname not found */" ) if $verbose or $debug{sub};
4560             # XXX empty CV should not be saved. #159, #235
4561             # $svsect->remove( $sv_ix );
4562             # $xpvcvsect->remove( $xpvcv_ix );
4563             # delsym( $cv );
4564 0 0       0 if (!$new_cv_fw) {
4565 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t0");
4566             }
4567 0 0       0 $CvFLAGS &= ~0x1000 if $PERL514; # CVf_DYNFILE
4568 0 0 0     0 $CvFLAGS &= ~0x400 if $gv and $$gv and $PERL514; #CVf_CVGV_RC
      0        
4569 0 0       0 $symsect->add(sprintf(
4570             "CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x".($PERL510?", {0}":''),
4571             $sv_ix, $xpvcv_ix, $cv->REFCNT, $CvFLAGS));
4572 0         0 return get_cv($fullname, 0);
4573             }
4574              
4575             # Now it is time to record the CV
4576 0 0       0 if ($new_cv_fw) {
4577 0         0 $sv_ix = $svsect->index + 1;
4578 0 0       0 if (!$cvforward{$sym}) { # avoid duplicates
4579 0         0 $symsect->add(sprintf("%s\t&sv_list[%d]", $sym, $sv_ix )); # forward the old CVIX to the new CV
4580 0         0 $cvforward{$sym}++;
4581             }
4582 0         0 $sym = savesym( $cv, "&sv_list[$sv_ix]" );
4583             }
4584              
4585             # $pv = '' unless defined $pv; # Avoid use of undef warnings
4586             #warn sprintf( "CV prototype %s for CV 0x%x\n", cstring($pv), $$cv )
4587             # if $pv and $debug{cv};
4588 0 0       0 my $proto = defined $pv ? cstring($pv) : 'NULL';
4589 0         0 my $pvsym = 'NULL';
4590 0 0       0 my $cur = defined $pv ? $cv->CUR : 0;
4591 0         0 my $len = $cur + 1;
4592 0 0 0     0 $len++ if IsCOW($cv) and !$B::C::cow;
4593 0 0       0 $len = 0 if $B::C::const_strings;
4594             # need to survive cv_undef as there is no protection against static CVs
4595 0 0       0 my $refcnt = $cv->REFCNT + ($PERL510 ? 1 : 0);
4596             # GV cannot be initialized statically
4597 0         0 my $xcv_outside = ${ $cv->OUTSIDE };
  0         0  
4598 0 0 0     0 if ($xcv_outside == ${ main_cv() } and !$MULTI) {
  0 0       0  
4599             # Provide a temp. debugging hack for CvOUTSIDE. The address of the symbol &PL_main_cv
4600             # is known to the linker, the address of the value PL_main_cv not. This is set later
4601             # (below) at run-time.
4602 0         0 $xcv_outside = '&PL_main_cv';
4603             } elsif (ref($cv->OUTSIDE) eq 'B::CV') {
4604 0         0 $xcv_outside = 0; # just a placeholder for a run-time GV
4605             }
4606 0 0       0 if ($PERL510) {
    0          
4607 0         0 $pvsym = save_hek($pv,$fullname,1);
4608             # XXX issue 84: we need to check the cv->PV ptr not the value.
4609             # "" is different to NULL for prototypes
4610 0 0       0 $len = $cur ? $cur+1 : 0;
4611             # TODO:
4612             # my $ourstash = "0"; # TODO stash name to bless it (test 16: "main::")
4613 0 0       0 if ($PERL522) {
    0          
4614 0         0 $CvFLAGS &= ~0x1000; # CVf_DYNFILE off
4615 0 0       0 $CvFLAGS |= 0x200000 if $CPERL52; # CVf_STATIC on
4616 0         0 my $xpvc = sprintf
4617             # stash magic cur {len} cvstash {start} {root} {cvgv} cvfile {cvpadlist} outside outside_seq cvflags cvdepth
4618             ("Nullhv, {0}, %u, {%u}, %s, {%s}, {s\\_%x}, {%s}, %s, {%s}, (CV*)%s, %s, 0x%x, %d",
4619             $cur, $len, "Nullhv",#CvSTASH later
4620             $startfield, $$root,
4621             "0", #GV later
4622             "NULL", #cvfile later (now a HEK)
4623             $padlistsym,
4624             $xcv_outside, #if main_cv set later
4625             ivx($cv->OUTSIDE_SEQ),
4626             $CvFLAGS,
4627             $cv->DEPTH);
4628             # repro only with 5.15.* threaded -q (70c0620) Encode::Alias::define_alias
4629 0 0       0 warn "lexwarnsym in XPVCV OUTSIDE: $xpvc" if $xpvc =~ /, \(CV\*\)iv\d/; # t/testc.sh -q -O3 227
4630 0 0       0 if (!$new_cv_fw) {
4631 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4632             #$symsect->add
4633             # (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}"),
4634             # $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4635             # ));
4636             } else {
4637 0         0 $xpvcvsect->comment('STASH mg_u cur len CV_STASH START_U ROOT_U GV file PADLIST OUTSIDE outside_seq flags depth');
4638 0         0 $xpvcvsect->add($xpvc);
4639 0 0       0 $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {%s}",
4640             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS,
4641             $CPERL52 ? $proto : "0"));
4642 0 0       0 $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4643             }
4644             } elsif ($PERL514) {
4645             # cv_undef wants to free it when CvDYNFILE(cv) is true.
4646             # E.g. DateTime: boot_POSIX. newXS reuses cv if autoloaded. So turn it off globally.
4647 0         0 $CvFLAGS &= ~0x1000; # CVf_DYNFILE off
4648 0         0 my $xpvc = sprintf
4649             # stash magic cur len cvstash start root cvgv cvfile cvpadlist outside outside_seq cvflags cvdepth
4650             ("Nullhv, {0}, %u, %u, %s, {%s}, {s\\_%x}, %s, %s, %s, (CV*)%s, %s, 0x%x, %d",
4651             $cur, $len, "Nullhv",#CvSTASH later
4652             $startfield, $$root,
4653             "0", #GV later
4654             "NULL", #cvfile later (now a HEK)
4655             $padlistsym,
4656             $xcv_outside, #if main_cv set later
4657             ivx($cv->OUTSIDE_SEQ),
4658             $CvFLAGS,
4659             $cv->DEPTH);
4660             #warn "lexwarnsym in XPVCV OUTSIDE: $xpvc" if $xpvc =~ /, \(CV\*\)iv\d/; # t/testc.sh -q -O3 227
4661 0 0       0 if (!$new_cv_fw) {
4662 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4663             #$symsect->add
4664             # (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}"),
4665             # $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4666             # ));
4667             } else {
4668 0         0 $xpvcvsect->comment('STASH mg_u cur len CV_STASH START_U ROOT_U GV file PADLIST OUTSIDE outside_seq flags depth');
4669 0         0 $xpvcvsect->add($xpvc);
4670 0         0 $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {0}",
4671             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS));
4672 0 0       0 $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4673             }
4674             } else { # 5.10-5.13
4675             # Note: GvFORM ends also here. #149 (B::FM), t/testc.sh -O3 -DGCF,-v 149
4676 0 0       0 my $depth = ref($cv) eq 'B::CV' ? $cv->DEPTH : 0;
4677 0 0       0 my $outside_seq = ref($cv) eq 'B::CV' ? $cv->OUTSIDE_SEQ : '0'; # XXX? #238
4678 0         0 my $xpvc = sprintf
4679             ("{%d}, %u, %u, {%s}, {%s}, %s,"
4680             ." %s, {%s}, {s\\_%x}, %s, %s, %s,"
4681             ." (CV*)%s, %s, 0x%x",
4682             0, # GvSTASH later. test 29 or Test::Harness
4683             $cur, $len,
4684             $depth,
4685             "NULL", "Nullhv", #MAGIC + STASH later
4686             "Nullhv",#CvSTASH later
4687             $startfield,
4688             $$root,
4689             "0", #GV later
4690             "NULL", #cv_file later (now a HEK)
4691             $padlistsym,
4692             $xcv_outside, #if main_cv set later
4693             $outside_seq,
4694             $CvFLAGS
4695             );
4696 0 0       0 if (!$new_cv_fw) {
4697 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4698             #$symsect->add
4699             # (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}",
4700             # $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4701             # ));
4702             } else {
4703 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');
4704 0         0 $xpvcvsect->add($xpvc);
4705 0         0 $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {0}",
4706             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS));
4707 0 0       0 $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4708             }
4709             }
4710 0 0       0 if ($$cv) {
4711 0 0 0     0 if ($PERL518 and (!$gv or ref($gv) eq 'B::SPECIAL')) {
      0        
4712 0 0       0 my $lexsub = $cv->can('NAME_HEK') ? $cv->NAME_HEK : "_anonlex_";
4713 0 0       0 $lexsub = '' unless defined $lexsub;
4714 0 0       0 warn "lexsub name $lexsub" if $debug{gv};
4715 0         0 my ($cstring, $cur, $utf8) = strlen_flags($lexsub);
4716 0 0 0     0 if (!$PERL56 and $utf8) {
4717 0         0 $cur = -$cur;
4718             }
4719 0         0 $init->add( "{ /* need a dynamic name hek */",
4720             sprintf(" HEK *lexhek = share_hek(savepvn(%s, %d), %d);",
4721             $cstring, abs($cur), $cur),
4722             sprintf(" CvNAME_HEK_set(s\\_%x, lexhek);", $$cv),
4723             "}");
4724             } else {
4725 0         0 my $gvstash = $gv->STASH;
4726             # defer GvSTASH because with DEBUGGING it checks for GP but
4727             # there's no GP yet.
4728             # But with -fstash the gvstash is set later
4729 0 0 0     0 $init->add( sprintf( "GvXPVGV(s\\_%x)->xnv_u.xgv_stash = s\\_%x;",
4730             $$cv, $$gvstash ) ) if $gvstash and !$B::C::stash;
4731             warn sprintf( "done saving GvSTASH 0x%x for CV 0x%x\n", $$gvstash, $$cv )
4732 0 0 0     0 if $gvstash and $debug{cv} and $debug{gv};
      0        
4733             }
4734             }
4735 0 0       0 if ( $cv->OUTSIDE_SEQ ) {
4736 0         0 my $cop = $symtable{ sprintf( "s\\_%x", $cv->OUTSIDE_SEQ ) };
4737 0 0       0 $init->add( sprintf( "CvOUTSIDE_SEQ(%s) = %s;", $sym, $cop ) ) if $cop;
4738             }
4739             }
4740             elsif ($PERL56) {
4741 0         0 my $xpvc = sprintf("%s, %u, %u, %s, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub, "
4742             ."$xsubany, Nullgv, \"\", %d, s\\_%x, (CV*)%s, 0x%x",
4743             $proto, $cur, $len, ivx($cv->IVX),
4744             nvx($cv->NVX), $startfield, $$root, $cv->DEPTH,
4745             $$padlist, $xcv_outside, $cv->CvFLAGS
4746             );
4747 0 0       0 if ($new_cv_fw) {
4748 0         0 $xpvcvsect->comment('pv cur len off nv magic mg_stash cv_stash start root xsub '
4749             .'xsubany cv_gv cv_file cv_depth cv_padlist cv_outside cv_flags');
4750 0         0 $xpvcvsect->add($xpvc);
4751 0         0 $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x"),
4752             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS);
4753 0 0       0 $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4754             } else {
4755 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4756             }
4757             }
4758             else { #5.8
4759 0         0 my $xpvc = sprintf("%s, %u, %u, %s, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub,"
4760             ." $xsubany, Nullgv, \"\", %d, s\\_%x, (CV*)s\\_%x, 0x%x, 0x%x",
4761             $proto, $cur, $len, ivx($cv->IVX),
4762             nvx($cv->NVX), $startfield, $$root, $cv->DEPTH,
4763             $$padlist, $xcv_outside, $cv->CvFLAGS, $cv->OUTSIDE_SEQ
4764             );
4765 0 0       0 if ($new_cv_fw) {
4766 0         0 $xpvcvsect->comment('pv cur len off nv magic mg_stash cv_stash '
4767             .'start root xsub xsubany cv_gv cv_file cv_depth cv_padlist '
4768             .'cv_outside cv_flags outside_seq');
4769 0         0 $xpvcvsect->add($xpvc);
4770 0         0 $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x"),
4771             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS);
4772 0 0       0 $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4773             } else {
4774 0         0 $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4775             }
4776             }
4777              
4778 0 0 0     0 if ($CPERL52 and $Config{uselongdouble}) {
4779             # some very odd static struct init bug: CvOUTSIDE is pointing to CvROOT, CvROOT is corrupt.
4780             # CvPADLIST also pointing somewhere else. with gcc-5 and 4.8.
4781 0         0 $init->add(sprintf("xpvcv_list[$xpvcv_ix].xcv_root_u.xcv_root = s\\_%x;", $$root));
4782 0         0 $init->add("xpvcv_list[$xpvcv_ix].xcv_padlist_u.xcv_padlist = $padlistsym;");
4783             }
4784              
4785 0         0 $xcv_outside = ${ $cv->OUTSIDE };
  0         0  
4786 0 0 0     0 if ($xcv_outside == ${ main_cv() } or ref($cv->OUTSIDE) eq 'B::CV') {
  0 0 0     0  
      0        
4787             # patch CvOUTSIDE at run-time
4788 0 0       0 if ( $xcv_outside == ${ main_cv() } ) {
  0         0  
4789 0         0 $init->add( "CvOUTSIDE($sym) = PL_main_cv;",
4790             "SvREFCNT_inc(PL_main_cv);" );
4791 0 0       0 if ($$padlist) {
4792 0 0       0 if ($PERL522) {
    0          
4793 0         0 $init->add( "CvPADLIST($sym)->xpadl_outid = CvPADLIST(PL_main_cv)->xpadl_id;");
4794             } elsif ($] >= 5.017005) {
4795 0         0 $init->add( "CvPADLIST($sym)->xpadl_outid = PadlistNAMES(CvPADLIST(PL_main_cv));");
4796             }
4797             }
4798             } else {
4799 0         0 $init->add( sprintf("CvOUTSIDE(%s) = (CV*)s\\_%x;", $sym, $xcv_outside) );
4800             #if ($PERL522) {
4801             # $init->add( sprintf("CvPADLIST(%s)->xpadl_outid = CvPADLIST(s\\_%x)->xpadl_id;",
4802             # $sym, $xcv_outside));
4803             #}
4804             }
4805             }
4806             elsif ($] >= 5.017005 and $xcv_outside and $$padlist) {
4807 0         0 my $padl = $cv->OUTSIDE->PADLIST->save;
4808 0 0       0 if ($PERL522) {
4809 0         0 $init->add( sprintf("CvPADLIST(%s)->xpadl_outid = CvPADLIST(s\\_%x)->xpadl_id;",
4810             $sym, $xcv_outside));
4811             } else {
4812             # Make sure that the outer padlist is allocated before PadlistNAMES is accessed.
4813             # This needs to be postponed (test 227)
4814 0         0 $init1->add( sprintf( "CvPADLIST(%s)->xpadl_outid = PadlistNAMES(%s);", $sym, $padl) );
4815             }
4816             }
4817 0 0 0     0 if ($gv and $$gv) {
4818             #test 16: Can't call method "FETCH" on unblessed reference. gdb > b S_method_common
4819 0 0 0     0 warn sprintf( "Saving GV 0x%x for CV 0x%x\n", $$gv, $$cv ) if $debug{cv} and $debug{gv};
4820 0         0 $gv->save;
4821 0 0       0 if ($PERL514) { # FIXME 5.18.0 with lexsubs
4822             # XXX gvcv might be PVMG
4823 0         0 $init->add( sprintf( "CvGV_set((CV*)%s, (GV*)%s);", $sym, objsym($gv)) );
4824             # Since 5.13.3 and CvGV_set there are checks that the CV is not RC (refcounted).
4825             # Assertion "!CvCVGV_RC(cv)" failed: file "gv.c", line 219, function: Perl_cvgv_set
4826             # We init with CvFLAGS = 0 and set it later, as successfully done in the Bytecode compiler
4827 0 0       0 if ($CvFLAGS & 0x0400) { # CVf_CVGV_RC
4828             warn sprintf( "CvCVGV_RC turned off. CV flags=0x%x %s CvFLAGS=0x%x \n",
4829             $cv->FLAGS, $debug{flags}?$cv->flagspv:"", $CvFLAGS & ~0x400)
4830 0 0       0 if $debug{cv};
    0          
4831             $init->add( sprintf( "CvFLAGS((CV*)%s) = 0x%x; %s", $sym, $CvFLAGS,
4832 0 0       0 $debug{flags}?"/* ".$cv->flagspv." */":"" ) );
4833             }
4834 0         0 $init->add("CvSTART($sym) = $startfield;"); # XXX TODO someone is overwriting CvSTART also
4835             } else {
4836 0         0 $init->add( sprintf( "CvGV(%s) = %s;", $sym, objsym($gv) ) );
4837             }
4838             warn sprintf("done saving GV 0x%x for CV 0x%x\n",
4839 0 0 0     0 $$gv, $$cv) if $debug{cv} and $debug{gv};
4840             }
4841 0 0       0 unless ($optimize_cop) {
4842 0         0 my $file = $cv->FILE();
4843 0 0 0     0 if ($MULTI) {
    0          
4844 0         0 $init->add( savepvn( "CvFILE($sym)", $file ) );
4845             } elsif ($B::C::const_strings && length $file) {
4846 0         0 $init->add( sprintf( "CvFILE(%s) = (char *) %s;", $sym, constpv( $file ) ) );
4847             } else {
4848 0         0 $init->add( sprintf( "CvFILE(%s) = %s;", $sym, cstring( $file ) ) );
4849             }
4850             }
4851 0         0 my $stash = $cv->STASH;
4852 0 0 0     0 if ($$stash and ref($stash)) {
4853             # $init->add("/* saving STASH $fullname */\n" if $debug{cv};
4854 0         0 $stash->save($fullname);
4855             # $sym fixed test 27
4856 0         0 $init->add( sprintf( "CvSTASH_set((CV*)%s, s\\_%x);", $sym, $$stash ) );
4857             # 5.18 bless does not inc sv_objcount anymore. broken by ddf23d4a1ae (#208)
4858             # We workaround this 5.18 de-optimization by adding it if at least a DESTROY
4859             # method exists.
4860 0 0 0     0 $init->add("++PL_sv_objcount;") if $cvname eq 'DESTROY' and $] >= 5.017011;
4861             warn sprintf( "done saving STASH 0x%x for CV 0x%x\n", $$stash, $$cv )
4862 0 0 0     0 if $debug{cv} and $debug{gv};
4863             }
4864 0         0 my $magic = $cv->MAGIC;
4865 0 0 0     0 if ($magic and $$magic) {
4866 0         0 $cv->save_magic($fullname); # XXX will this work?
4867             }
4868 0 0       0 if (!$new_cv_fw) {
4869 0 0       0 $symsect->add(sprintf(
4870             "CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x".($PERL510?", {0}":''),
4871             $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4872             )
4873             );
4874             }
4875 0 0       0 if ($cur) {
4876 0 0       0 warn sprintf( "Saving CV proto %s for CV $sym 0x%x\n", cstring($pv), $$cv ) if $debug{cv};
4877             }
4878             # issue 84: empty prototypes sub xx(){} vs sub xx{}
4879 0 0       0 if (defined $pv) {
4880 0 0 0     0 if ($PERL510 and $cur) {
    0          
4881 0         0 $init->add( sprintf("SvPVX(&sv_list[%d]) = HEK_KEY(%s);", $sv_ix, $pvsym));
4882             } elsif (!$B::C::const_strings) { # not static, they are freed when redefined
4883 0         0 $init->add( sprintf("SvPVX(&sv_list[%d]) = savepvn(%s, %u);",
4884             $sv_ix, $proto, $cur));
4885             } else {
4886 0         0 $init->add( sprintf("SvPVX(&sv_list[%d]) = %s;",
4887             $sv_ix, $proto));
4888             }
4889             }
4890 0 0       0 $cv->OUTSIDE->save if $xcv_outside;
4891 0         0 return $sym;
4892             }
4893              
4894             package B::C;
4895             my @_v = Internals::V() if $] >= 5.011;
4896 0     0   0 sub __ANON__::_V { @_v };
4897              
4898             sub B::GV::save {
4899 0     0   0 my ($gv, $filter) = @_;
4900 0         0 my $sym = objsym($gv);
4901 0 0       0 if ( defined($sym) ) {
4902 0 0       0 warn sprintf( "GV 0x%x already saved as $sym\n", $$gv ) if $debug{gv};
4903 0         0 return $sym;
4904             }
4905             else {
4906 0         0 my $ix = $gv_index++;
4907 0         0 $sym = savesym( $gv, "gv_list[$ix]" );
4908 0 0       0 warn sprintf( "Saving GV 0x%x as $sym\n", $$gv ) if $debug{gv};
4909             }
4910             warn sprintf( " GV %s $sym type=%d, flags=0x%x %s\n", $gv->NAME,
4911             # B::SV::SvTYPE not with 5.6
4912 0 0 0     0 B::SV::SvTYPE($gv), $gv->FLAGS) if $debug{gv} and !$PERL56;
4913 0 0 0     0 if ($PERL510 and !$PERL5257 and $gv->FLAGS & 0x40000000) { # SVpbm_VALID
      0        
4914 0 0       0 warn sprintf( " GV $sym isa FBM\n") if $debug{gv};
4915 0         0 return B::BM::save($gv);
4916             }
4917             # since 5.25.7 VALID is just a B magic at a gv->SV->PVMG. See below.
4918              
4919 0         0 my $gvname = $gv->NAME;
4920 0         0 my $package;
4921 0 0       0 if (ref($gv->STASH) eq 'B::SPECIAL') {
4922 0         0 $package = '__ANON__';
4923 0 0       0 warn sprintf( "GV STASH = SPECIAL $gvname\n") if $debug{gv};
4924             } else {
4925 0         0 $package = $gv->STASH->NAME;
4926             }
4927 0 0       0 return q/(SV*)&PL_sv_undef/ if skip_pkg($package);
4928              
4929 0         0 my $fullname = $package . "::" . $gvname;
4930 0         0 my $fancyname;
4931             sub Save_HV() { 1 }
4932             sub Save_AV() { 2 }
4933             sub Save_SV() { 4 }
4934             sub Save_CV() { 8 }
4935             sub Save_FORM() { 16 }
4936             sub Save_IO() { 32 }
4937 0 0 0     0 if ( $filter and $filter =~ m/ :pad/ ) {
4938 0         0 $fancyname = cstring($filter);
4939 0         0 $filter = 0;
4940             } else {
4941 0         0 $fancyname = cstring($fullname);
4942             }
4943             # checked for defined'ness in Carp. So the GV must exist, the CV not
4944 0 0 0     0 if ($fullname =~ /^threads::(tid|AUTOLOAD)$/ and !$ITHREADS) {
4945 0         0 $filter = Save_CV;
4946             }
4947             # no need to assign any SV/AV/HV to them (172)
4948 0 0 0     0 if ($PERL518 and $fullname =~ /^DynaLoader::dl_(
4949             require_symbols|
4950             modules|
4951             shared_objects|
4952             resolve_using|
4953             librefs)/x)
4954             {
4955 0         0 $filter = Save_SV + Save_AV + Save_HV;
4956             }
4957             # skip static %Encode::Encoding since 5.20. GH #200.
4958             # Let it be initialized by boot_Encode/Encode_XSEncoding
4959             #if ($] >= 5.020 and $fullname eq 'Encode::Encoding') {
4960             # warn "skip %Encode::Encoding - XS initialized\n" if $debug{gv};
4961             # $filter = Save_HV;
4962             #}
4963              
4964 0         0 my $is_empty = $gv->is_empty;
4965 0 0 0     0 if (!defined $gvname and $is_empty) { # 5.8 curpad name
4966 0         0 return q/(SV*)&PL_sv_undef/;
4967             }
4968 0 0       0 my $name = $package eq 'main' ? $gvname : $fullname;
4969 0         0 my $cname = cstring($name);
4970 0 0 0     0 my $notqual = ($] >= 5.008009 and $package eq 'main') ? 'GV_NOTQUAL' : '0';
4971 0 0       0 warn " GV name is $fancyname\n" if $debug{gv};
4972 0         0 my $egvsym;
4973 0         0 my $is_special = ref($gv) eq 'B::SPECIAL';
4974              
4975             # If we come across a stash, we therefore have code using this symbol.
4976             # But this does not mean that we need to save the package then.
4977             # if (defined %Exporter::) should not import Exporter, it should return undef.
4978             #if ( $gvname =~ m/::$/ ) {
4979             # my $package = $gvname;
4980             # $package =~ s/::$//;
4981             # mark_package($package); #wrong
4982             #}
4983 0 0       0 if ($fullname =~ /^(bytes|utf8)::AUTOLOAD$/) {
4984 0         0 $gv = force_heavy($package); # defer to run-time autoload, or compile it in?
4985 0         0 $sym = savesym( $gv, $sym ); # override new gv ptr to sym
4986             }
4987 0 0       0 if ( !$is_empty ) {
4988 0         0 my $egv = $gv->EGV;
4989 0 0 0     0 unless (ref($egv) eq 'B::SPECIAL' or ref($egv->STASH) eq 'B::SPECIAL') {
4990 0         0 my $estash = $egv->STASH->NAME;
4991 0 0       0 if ( $$gv != $$egv ) {
4992             warn(sprintf( "EGV name is %s, saving it now\n",
4993             $estash . "::" . $egv->NAME )
4994 0 0       0 ) if $debug{gv};
4995 0         0 $egvsym = $egv->save;
4996             }
4997             }
4998             }
4999             #if ($fullname eq 'threads::tid' and !$ITHREADS) { # checked for defined'ness in Carp
5000             # $init->add(qq[$sym = (GV*)&PL_sv_undef;]);
5001             # return $sym;
5002             #}
5003 0 0 0     0 if ($fullname =~ /^main::STDOUT$/i and $PERL56) {
5004 0         0 return 'Nullgv'; # perl.c: setdefout(Nullgv)
5005             }
5006 0         0 my $core_syms = {ENV => 'PL_envgv',
5007             ARGV => 'PL_argvgv',
5008             INC => 'PL_incgv',
5009             STDIN => 'PL_stdingv',
5010             STDERR => 'PL_stderrgv',
5011             "\010" => 'PL_hintgv', # ^H
5012             "_" => 'PL_defgv',
5013             "@" => 'PL_errgv',
5014             "\022" => 'PL_replgv', # ^R
5015             };
5016 0         0 my $is_coresym;
5017             # those are already initialized in init_predump_symbols()
5018             # and init_main_stash()
5019 0         0 for my $s (sort keys %$core_syms) {
5020 0 0       0 if ($fullname eq 'main::'.$s) {
5021 0         0 $sym = savesym( $gv, $core_syms->{$s} );
5022             # $init->add( sprintf( "SvREFCNT($sym) = $u32fmt;", $gv->REFCNT ) );
5023             # return $sym;
5024 0         0 $is_coresym++;
5025             }
5026             }
5027 0 0 0     0 if ($fullname =~ /^main::std(in|out|err)$/) { # same as uppercase above
    0          
    0          
5028 0         0 $init->add(qq[$sym = gv_fetchpv($cname, $notqual, SVt_PVGV);]);
5029 0         0 $init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) );
5030 0         0 return $sym;
5031             }
5032             elsif ($fullname eq 'main::0') { # dollar_0 already handled before, so don't overwrite it
5033 0         0 $init->add(qq[$sym = gv_fetchpv($cname, $notqual, SVt_PV);]);
5034 0         0 $init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) );
5035 0         0 return $sym;
5036             }
5037             elsif ($B::C::ro_inc and $fullname =~ /^main::([0-9])$/) { # ignore PV regexp captures with -O2
5038 0         0 $filter = Save_SV;
5039             }
5040             # gv_fetchpv loads Errno resp. Tie::Hash::NamedCapture, but needs *INC #90
5041             #elsif ( $fullname eq 'main::!' or $fullname eq 'main::+' or $fullname eq 'main::-') {
5042             # $init1->add(qq[$sym = gv_fetchpv($name, TRUE, SVt_PVGV);]); # defer until INC is setup
5043             # $init1->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) );
5044             # return $sym;
5045             #}
5046 0         0 my $svflags = $gv->FLAGS;
5047 0         0 my $savefields = 0;
5048              
5049 0         0 my $gp;
5050 0 0       0 my $gvadd = $notqual ? "$notqual|GV_ADD" : "GV_ADD";
5051 0 0 0     0 if ( $PERL510 and $gv->isGV_with_GP and !$is_coresym) {
    0 0        
5052 0         0 $gp = $gv->GP; # B limitation
5053             # warn "XXX EGV='$egvsym' for IMPORTED_HV" if $gv->GvFLAGS & 0x40;
5054 0 0 0     0 if ( defined($egvsym) && $egvsym !~ m/Null/ ) {
    0 0        
    0 0        
    0 0        
      0        
5055             warn(sprintf("Shared GV alias for *$fullname 0x%x%s %s to $egvsym\n",
5056             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5057 0 0       0 )) if $debug{gv};
    0          
5058             # Shared glob *foo = *bar
5059 0 0       0 $init->add("$sym = ".gv_fetchpvn($package eq 'main' ? $gvname : $fullname,
5060             "$gvadd|GV_ADDMULTI", "SVt_PVGV").";");
5061 0         0 $init->add( "GvGP_set($sym, GvGP($egvsym));" );
5062 0         0 $is_empty = 1;
5063             }
5064             elsif ( $gp and exists $gptable{0+$gp} ) {
5065             warn(sprintf("Shared GvGP for *$fullname 0x%x%s %s GP:0x%x\n",
5066             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5067             $gv->FILE, $gp
5068 0 0       0 )) if $debug{gv};
    0          
5069 0         0 $init->add("$sym = ".gv_fetchpvn($name, $notqual, "SVt_PVGV").";");
5070 0         0 $init->add( sprintf("GvGP_set(%s, %s);", $sym, $gptable{0+$gp}) );
5071 0         0 $is_empty = 1;
5072             }
5073             elsif ( $gp and !$is_empty and $gvname =~ /::$/) {
5074             warn(sprintf("Shared GvGP for stash %$fullname 0x%x%s %s GP:0x%x\n",
5075             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5076             $gv->FILE, $gp
5077 0 0       0 )) if $debug{gv};
    0          
5078 0         0 $init->add("$sym = ".gv_fetchpvn($name, "GV_ADD", "SVt_PVHV").";");
5079 0 0       0 $gptable{0+$gp} = "GvGP($sym)" if 0+$gp;
5080             }
5081             elsif ( $gp and !$is_empty ) {
5082             warn(sprintf("New GV for *$fullname 0x%x%s %s GP:0x%x\n",
5083             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5084             $gv->FILE, $gp
5085 0 0       0 )) if $debug{gv};
    0          
5086             # XXX !PERL510 and OPf_COP_TEMP we need to fake PL_curcop for gp_file hackery
5087 0         0 $init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PV").";");
5088             #$init->add(qq[$sym = gv_fetchpv($name, $gvadd, SVt_PV);]);
5089 0         0 $savefields = Save_HV | Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO;
5090 0         0 $gptable{0+$gp} = "GvGP($sym)";
5091             }
5092             else {
5093 0         0 $init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PVGV").";");
5094             # $init->add(qq[$sym = gv_fetchpv($name, $gvadd, SVt_PVGV);]);
5095             }
5096             } elsif (!$is_coresym) {
5097 0         0 $init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PV").";");
5098             # $init->add(qq[$sym = gv_fetchpv($name, $gvadd, SVt_PV);]);
5099             }
5100 0         0 my $gvflags = $gv->GvFLAGS;
5101 0 0 0     0 if ($gvflags > 256 and !$PERL510) { # $gv->GvFLAGS as U8 single byte only
5102 0         0 $gvflags = $gvflags & 255;
5103             }
5104             $init->add( sprintf( "SvFLAGS(%s) = 0x%x;%s", $sym, $svflags,
5105             $debug{flags}?" /* ".$gv->flagspv." */":"" ),
5106             sprintf( "GvFLAGS(%s) = 0x%x; %s", $sym, $gvflags,
5107 0 0       0 $debug{flags}?"/* ".$gv->flagspv(SVt_PVGV)." */":"" ));
    0          
5108 0 0       0 $init->add( sprintf( "GvLINE(%s) = %d;", $sym,
    0          
5109             ($gv->LINE > 2147483647 # S32 INT_MAX
5110             ? 4294967294 - $gv->LINE
5111             : $gv->LINE )))
5112             unless $is_empty;
5113              
5114             # XXX hack for when Perl accesses PVX of GVs, only if SvPOK
5115             #if (!($svflags && 0x400)) { # defer to run-time (0x400 -> SvPOK) for convenience
5116             # XXX also empty "main::" destruction accesses a PVX, so do not check if_empty
5117 0 0       0 if ( !$PERL510 ) {
5118 0         0 $init->add("if (SvPOK($sym) && !SvPVX($sym)) SvPVX($sym) = (char*)emptystring;");
5119             }
5120              
5121             # walksymtable creates an extra reference to the GV (#197)
5122 0 0       0 if ( $gv->REFCNT > 1 ) {
5123 0         0 $init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT) );
5124             }
5125 0 0       0 return $sym if $is_empty;
5126              
5127 0         0 my $gvrefcnt = $gv->GvREFCNT;
5128 0 0       0 if ( $gvrefcnt > 1 ) {
5129 0         0 $init->add( sprintf( "GvREFCNT(%s) += $u32fmt;", $sym, $gvrefcnt - 1) );
5130             }
5131              
5132 0 0       0 warn "check which savefields for \"$gvname\"\n" if $debug{gv};
5133             # some non-alphabetic globs require some parts to be saved
5134             # ( ex. %!, but not $! )
5135 0 0 0     0 if ( $gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/ ) {
    0          
    0          
    0          
    0          
5136 0         0 $savefields = Save_HV | Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO;
5137             }
5138             elsif ( $fullname eq 'main::!' ) { #Errno
5139 0         0 $savefields = Save_HV | Save_SV | Save_CV;
5140             }
5141             elsif ( $fullname eq 'main::ENV' or $fullname eq 'main::SIG' ) {
5142 0         0 $savefields = Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO;
5143             }
5144             elsif ( $fullname eq 'main::ARGV' ) {
5145 0         0 $savefields = Save_HV | Save_SV | Save_CV | Save_FORM | Save_IO;
5146             }
5147             elsif ( $fullname =~ /^main::STD(IN|OUT|ERR)$/ ) {
5148 0         0 $savefields = Save_FORM | Save_IO;
5149             }
5150 0 0 0     0 $savefields &= ~$filter if ($filter and $filter !~ m/ :pad/
      0        
      0        
      0        
5151             and $filter =~ m/^\d+$/ and $filter > 0 and $filter < 64);
5152             # issue 79: Only save stashes for stashes.
5153             # But not other values to avoid recursion into unneeded territory.
5154             # We walk via savecv, not via stashes.
5155 0 0 0     0 if (ref($gv) eq 'B::STASHGV' and $gvname !~ /::$/) {
5156 0         0 return $sym;
5157             }
5158              
5159             # attributes::bootstrap is created in perl_parse.
5160             # Saving it would overwrite it, because perl_init() is
5161             # called after perl_parse(). But we need to xsload it.
5162 0 0       0 if ($fullname eq 'attributes::bootstrap') {
5163 0 0       0 unless ( defined( &{ $package . '::bootstrap' } ) ) {
  0         0  
5164 0 0       0 warn "Forcing bootstrap of $package\n" if $verbose;
5165 0         0 eval { $package->bootstrap };
  0         0  
5166             }
5167 0         0 mark_package('attributes', 1);
5168 0 0       0 if ($] >= 5.011) {
5169 0         0 $savefields &= ~Save_CV;
5170 0         0 $xsub{attributes} = 'Dynamic-'. $INC{'attributes.pm'}; # XSLoader
5171 0         0 $use_xsloader = 1;
5172             } else {
5173 0         0 $xsub{attributes} = 'Static';
5174             }
5175             }
5176              
5177             # avoid overly dynamic POSIX redefinition warnings: GH #335, #345
5178 0 0 0     0 if ($PERL522 and $fullname =~ /^POSIX::M/) {
5179 0         0 $savefields &= ~Save_CV;
5180             }
5181 0         0 my $gvsv;
5182 0 0       0 if ($savefields) {
5183             # Don't save subfields of special GVs (*_, *1, *# and so on)
5184 0 0       0 warn "GV::save saving subfields $savefields\n" if $debug{gv};
5185 0         0 $gvsv = $gv->SV;
5186 0 0 0     0 if ( $$gvsv && $savefields & Save_SV ) {
5187 0 0       0 warn "GV::save \$".$sym." $gvsv\n" if $debug{gv};
5188 0         0 my $core_svs = { # special SV syms to assign to the right GvSV
5189             "\\" => 'PL_ors_sv',
5190             "/" => 'PL_rs',
5191             "@" => 'PL_errors',
5192             };
5193 0         0 for my $s (sort keys %$core_svs) {
5194 0 0       0 if ($fullname eq 'main::'.$s) {
5195 0         0 savesym( $gvsv, $core_svs->{$s} ); # TODO: This could bypass BEGIN settings (->save is ignored)
5196             }
5197             }
5198 0 0 0     0 if ($PERL5257 and $gvsv->MAGICAL) {
5199 0         0 my @magic = $gvsv->MAGIC;
5200 0         0 foreach my $mg (@magic) {
5201 0 0       0 if ($mg->TYPE eq 'B') {
5202 0 0       0 warn sprintf( " GvSV $sym isa FBM\n") if $debug{gv};
5203 0         0 savesym($gvsv, B::BM::save($gvsv));
5204             }
5205             }
5206             }
5207 0 0 0     0 if ($gvname eq 'VERSION' and $xsub{$package} and $gvsv->FLAGS & SVf_ROK and !$PERL56) {
      0        
      0        
5208 0 0       0 warn "Strip overload from $package\::VERSION, fails to xs boot (issue 91)\n" if $debug{gv};
5209 0         0 my $rv = $gvsv->object_2svref();
5210 0         0 my $origsv = $$rv;
5211 55     55   343 no strict 'refs';
  55         86  
  55         29939  
5212 0         0 ${$fullname} = "$origsv";
  0         0  
5213 0         0 svref_2object(\${$fullname})->save($fullname);
  0         0  
5214 0         0 $init->add( sprintf( "GvSVn(%s) = (SV*)s\\_%x;", $sym, $$gvsv ) );
5215             } else {
5216 0         0 $gvsv->save($fullname); #even NULL save it, because of gp_free nonsense
5217             # we need sv magic for the core_svs (PL_rs -> gv) (#314)
5218 0 0       0 if (exists $core_svs->{$gvname}) {
5219 0 0       0 if ($gvname eq "\\") { # ORS special case #318 (initially NULL)
5220 0         0 return $sym;
5221             } else {
5222 0 0       0 $gvsv->save_magic($fullname) if ref($gvsv) eq 'B::PVMG';
5223 0         0 $init->add( sprintf( "SvREFCNT(s\\_%x) += 1;", $$gvsv ) );
5224             }
5225             }
5226 0         0 $init->add( sprintf( "GvSVn(%s) = (SV*)s\\_%x;", $sym, $$gvsv ) );
5227             }
5228 0 0       0 if ($fullname eq 'main::$') { # $$ = PerlProc_getpid() issue #108
5229 0 0       0 warn sprintf( " GV $sym \$\$ perlpid\n") if $debug{gv};
5230 0         0 $init->add( "sv_setiv(GvSV($sym), (IV)PerlProc_getpid());" );
5231             }
5232 0 0       0 warn "GV::save \$$fullname\n" if $debug{gv};
5233             }
5234 0         0 my $gvav = $gv->AV;
5235 0 0 0     0 if ( $$gvav && $savefields & Save_AV ) {
5236 0 0       0 warn "GV::save \@$fullname\n" if $debug{gv};
5237 0         0 $gvav->save($fullname);
5238 0         0 $init->add( sprintf( "GvAV(%s) = s\\_%x;", $sym, $$gvav ) );
5239 0 0       0 if ($fullname eq 'main::-') {
5240 0         0 $init->add( sprintf("AvFILLp(s\\_%x) = -1;", $$gvav),
5241             sprintf("AvMAX(s\\_%x) = -1;", $$gvav));
5242             }
5243             }
5244 0         0 my $gvhv = $gv->HV;
5245 0 0 0     0 if ( $$gvhv && $savefields & Save_HV ) {
5246 0 0       0 if ($fullname ne 'main::ENV') {
5247 0 0       0 warn "GV::save \%$fullname\n" if $debug{gv};
5248 0 0 0     0 if ($fullname eq 'main::!') { # force loading Errno
    0          
5249 0         0 $init->add("/* \%! force saving of Errno */");
5250 0         0 mark_package('Config', 1); # Errno needs Config to set the EGV
5251 0         0 walk_syms('Config');
5252 0         0 mark_package('Errno', 1); # B::C needs Errno but does not import $!
5253             } elsif ($fullname eq 'main::+' or $fullname eq 'main::-') {
5254 0         0 $init->add("/* \%$gvname force saving of Tie::Hash::NamedCapture */");
5255 0 0       0 if ($PERL514) {
5256 0         0 mark_package('Config', 1); # DynaLoader needs Config to set the EGV
5257 0         0 walk_syms('Config');
5258 0         0 svref_2object(\&{'Tie::Hash::NamedCapture::bootstrap'})->save;
  0         0  
5259             }
5260 0         0 mark_package('Tie::Hash::NamedCapture', 1);
5261             }
5262             # skip static %Encode::Encoding since 5.20. GH #200. sv_upgrade cannot upgrade itself.
5263             # Let it be initialized by boot_Encode/Encode_XSEncodingm with exceptions.
5264             # GH #200 and t/testc.sh 75
5265 0 0 0     0 if ($] >= 5.020 and $fullname eq 'Encode::Encoding') {
    0          
5266 0 0       0 warn "skip some %Encode::Encoding - XS initialized\n" if $debug{gv};
5267 0         0 my %tmp_Encode_Encoding = %Encode::Encoding;
5268 0         0 %Encode::Encoding = (); # but we need some non-XS encoding keys
5269 0         0 for my $k (qw(utf8 utf-8-strict Unicode Internal Guess)) {
5270 0 0       0 $Encode::Encoding{$k} = $tmp_Encode_Encoding{$k} if exists $tmp_Encode_Encoding{$k};
5271             }
5272 0         0 $gvhv->save($fullname);
5273 0         0 $init->add( "/* deferred some XS enc pointers for \%Encode::Encoding */",
5274             sprintf("GvHV(%s) = s\\_%x;", $sym, $$gvhv ) );
5275 0         0 %Encode::Encoding = %tmp_Encode_Encoding;
5276             }
5277             # XXX TODO 49: crash at BEGIN { %warnings::Bits = ... }
5278             elsif ($fullname ne 'main::INC') {
5279 0         0 $gvhv->save($fullname);
5280 0         0 $init->add( sprintf( "GvHV(%s) = s\\_%x;", $sym, $$gvhv ) );
5281             }
5282             }
5283             }
5284 0         0 my $gvcv = $gv->CV;
5285 0 0 0     0 if ( !$$gvcv and $savefields & Save_CV ) {
5286 0 0       0 warn "Empty CV $fullname, AUTOLOAD and try again\n" if $debug{gv};
5287 55     55   259 no strict 'refs';
  55         106  
  55         9816  
5288             # Fix test 31, catch unreferenced AUTOLOAD. The downside:
5289             # It stores the whole optree and all its children.
5290             # Similar with test 39: re::is_regexp
5291 0         0 svref_2object( \*{"$package\::AUTOLOAD"} )->save
5292 0 0 0     0 if $package and exists ${"$package\::"}{AUTOLOAD};
  0         0  
5293 0         0 svref_2object( \*{"$package\::CLONE"} )->save
5294 0 0 0     0 if $package and exists ${"$package\::"}{CLONE};
  0         0  
5295 0         0 $gvcv = $gv->CV; # try again
5296             }
5297 0 0 0     0 if ( $$gvcv and $savefields & Save_CV
      0        
      0        
      0        
5298             and ref($gvcv) eq 'B::CV'
5299             and ref($gvcv->GV->EGV) ne 'B::SPECIAL'
5300             and !skip_pkg($package) )
5301             {
5302 0         0 my $package = $gvcv->GV->EGV->STASH->NAME;
5303 0         0 my $oname = $gvcv->GV->EGV->NAME;
5304 0         0 my $origname = $package . "::" . $oname;
5305 0         0 my $cvsym;
5306 0 0 0     0 if ( $gvcv->XSUB and $oname ne '__ANON__' and $fullname ne $origname ) { #XSUB CONSTSUB alias
    0 0        
      0        
5307             warn "Boot $package, XS CONSTSUB alias of $fullname to $origname\n"
5308 0 0       0 if $debug{pkg};
5309 0         0 mark_package($package, 1);
5310             {
5311 55     55   226 no strict 'refs';
  55         74  
  55         63733  
  0         0  
5312 0         0 svref_2object( \&{"$package\::bootstrap"} )->save
5313 0 0 0     0 if $package and defined &{"$package\::bootstrap"};
  0         0  
5314             }
5315             # XXX issue 57: incomplete xs dependency detection
5316 0         0 my %hack_xs_detect =
5317             ('Scalar::Util' => 'List::Util',
5318             'Sub::Exporter' => 'Params::Util',
5319             );
5320 0 0       0 if (my $dep = $hack_xs_detect{$package}) {
5321 0         0 svref_2object( \&{"$dep\::bootstrap"} )->save;
  0         0  
5322             }
5323             # must save as a 'stub' so newXS() has a CV to populate
5324 0 0       0 warn "save stub CvGV for $sym GP assignments $origname\n" if $debug{gv};
5325 0         0 $init2->add(
5326             sprintf("if ((sv = (SV*)%s))", get_cv($origname, "GV_ADD")),
5327             sprintf(" GvCV_set(%s, (CV*)SvREFCNT_inc_simple_NN(sv));", $sym));
5328             # TODO: add evtl. to SvRV also.
5329             }
5330             elsif (!$PERL510 or $gp) {
5331 0 0       0 if ($fullname eq 'Internals::V') { # local_patches if $] >= 5.011
5332 0         0 $gvcv = svref_2object( \&__ANON__::_V );
5333             }
5334             # TODO: may need fix CvGEN if >0 to re-validate the CV methods
5335             # on PERL510 (>0 +
5336 0 0       0 warn "GV::save &$fullname...\n" if $debug{gv};
5337 0         0 $cvsym = $gvcv->save($fullname);
5338             # backpatch "$sym = gv_fetchpv($name, GV_ADD, SVt_PV)" to SVt_PVCV
5339 0 0       0 if ($cvsym =~ /get_cv/) {
    0          
5340 0 0 0     0 if (!$xsub{$package} and in_static_core($package, $gvname)) {
    0          
5341 0         0 my $in_gv;
5342 0         0 for (@{ $init->[-1]{current} }) {
  0         0  
5343 0 0       0 if ($in_gv) {
5344 0         0 s/^.*\Q$sym\E.*=.*;//;
5345 0         0 s/GvGP_set\(\Q$sym\E.*;//;
5346             }
5347 0         0 my $gv_get = gv_fetchpvn($name, "GV_ADD", "SVt_PV");
5348 0         0 my $new_gv_get = gv_fetchpvn($name, "GV_ADD", "SVt_PVCV");
5349 0 0       0 if (/^\Q$sym = $gv_get;\E/) {
5350 0         0 s/^\Q$sym = $gv_get;\E/$sym = $new_gv_get;/;
5351 0         0 $in_gv++;
5352 0 0       0 warn "removed $sym GP assignments $origname (core CV)\n" if $debug{gv};
5353             }
5354             }
5355 0         0 $init->add( sprintf( "GvCV_set(%s, (CV*)SvREFCNT_inc(%s));", $sym, $cvsym ));
5356             }
5357             elsif ($xsub{$package}) {
5358             # must save as a 'stub' so newXS() has a CV to populate later in dl_init()
5359 0 0       0 warn "save stub CvGV for $sym GP assignments $origname (XS CV)\n" if $debug{gv};
5360 0 0       0 my $get_cv = get_cv($oname ne "__ANON__" ? $origname : $fullname, "GV_ADD");
5361 0         0 $init2->add(sprintf("if ((sv = (SV*)%s))", $get_cv),
5362             sprintf(" GvCV_set(%s, (CV*)SvREFCNT_inc_simple_NN(sv));", $sym));
5363             }
5364             else {
5365 0         0 $init->add( sprintf( "GvCV_set(%s, (CV*)(%s));", $sym, $cvsym ));
5366             }
5367 0 0       0 if ($gvcv->XSUBANY) {
5368             # some XSUB's set this field. but which part?
5369 0         0 my $xsubany = $gvcv->XSUBANY;
5370 0 0       0 if ($package =~ /^DBI::(common|db|dr|st)/) {
    0          
5371             # DBI uses the any_ptr for dbi_ima_t *ima, and all dr,st,db,fd,xx handles
5372             # for which several ptrs need to be patched. #359
5373             # the ima is internal only
5374 0         0 my $dr = $1;
5375             warn sprintf("eval_pv: DBI->_install_method(%s-) (XSUBANY=0x%x)\n",
5376 0 0 0     0 $fullname, $xsubany) if $verbose and $debug{cv};
5377 0         0 $init2->add_eval(sprintf("DBI->_install_method('%s', 'DBI.pm', \$DBI::DBI_methods{%s}{%s})",
5378             $fullname, $dr, $fullname));
5379             } elsif ($package eq 'Tie::Hash::NamedCapture') {
5380             # pretty high _ALIAS CvXSUBANY.any_i32 values
5381             } else {
5382             # try if it points to an already registered symbol
5383 0         0 my $anyptr = $symtable{ sprintf( "s\\_%x", $xsubany ) };
5384 0 0 0     0 if ($anyptr and $xsubany > 1000) { # not a XsubAliases
    0 0        
    0 0        
5385 0         0 $init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_ptr = &%s;", $sym, $anyptr ));
5386             } # some heuristics TODO. long or ptr? TODO 32bit
5387             elsif ($xsubany > 0x100000
5388             and ($xsubany < 0xffffff00 or $xsubany > 0xffffffff))
5389             {
5390 0 0 0     0 if ($package eq 'POSIX' and $gvname =~ /^is/) {
    0 0        
5391             # need valid XSANY.any_dptr
5392 0         0 $init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_dptr = (void*)&%s;", $sym, $gvname));
5393             } elsif ($package eq 'List::MoreUtils' and $gvname =~ /_iterator$/) {
5394             # should be only the 2 iterators
5395 0         0 $init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_ptr = (void*)&%s;", $sym,
5396             "XS_List__MoreUtils__".$gvname));
5397             } else {
5398 0 0       0 warn sprintf("TODO: Skipping %s->XSUBANY = 0x%x\n", $fullname, $xsubany ) if $verbose;
5399 0         0 $init2->add( sprintf( "/* TODO CvXSUBANY(GvCV(%s)).any_ptr = 0x%lx; */", $sym, $xsubany ));
5400             }
5401             } elsif ($package eq 'Fcntl') {
5402             # S_ macro values
5403             } else {
5404             # most likely any_i32 values for the XsubAliases provided by xsubpp
5405 0         0 $init2->add( sprintf( "/* CvXSUBANY(GvCV(%s)).any_i32 = 0x%x; XSUB Alias */", $sym, $xsubany ));
5406             }
5407             }
5408             }
5409             }
5410             elsif ($cvsym =~ /^(cv|&sv_list)/) {
5411 0         0 $init->add( sprintf( "GvCV_set(%s, (CV*)(%s));", $sym, $cvsym ));
5412             }
5413             else {
5414 0 0 0     0 warn "wrong CvGV for $sym $origname: $cvsym\n" if $debug{gv} or $verbose;
5415             }
5416             }
5417             # special handling for backref magic
5418 0 0 0     0 if ($PERL514 and $cvsym and $cvsym !~ /(get_cv|NULL|lexwarn)/ and $gv->MAGICAL) {
      0        
      0        
5419 0         0 my @magic = $gv->MAGIC;
5420 0         0 foreach my $mg (@magic) {
5421 0 0       0 if ($mg->TYPE eq '<') {
5422 0         0 $init->add( "sv_magic((SV*)$sym, (SV*)$cvsym, '<', 0, 0);",
5423             "CvCVGV_RC_off($cvsym);");
5424 0 0       0 if (!($mg->FLAGS & 2)) {
5425 0         0 mg_RC_off($mg, $sym, '<'); # 390
5426             }
5427             }
5428             }
5429             }
5430             }
5431 0 0 0     0 if (!$PERL510 or $gp) {
5432 0 0       0 if ( $] > 5.009 ) {
5433             # TODO implement heksect to place all heks at the beginning
5434             #$heksect->add($gv->FILE);
5435             #$init->add(sprintf("GvFILE_HEK($sym) = hek_list[%d];", $heksect->index));
5436              
5437             # XXX Maybe better leave it NULL or asis, than fighting broken
5438 0 0 0     0 if ($B::C::stash and $fullname =~ /::$/) {
5439             # ignore stash hek asserts when adding the stash
5440             # he->shared_he_he.hent_hek == hek assertions (#46 with IO::Poll::)
5441             } else {
5442 0         0 my $file = save_hek($gv->FILE,$fullname,1);
5443 0 0 0     0 $init->add(sprintf("GvFILE_HEK(%s) = %s;", $sym, $file))
5444             if $file ne 'NULL' and !$optimize_cop;
5445             }
5446             # $init->add(sprintf("GvNAME_HEK($sym) = %s;", save_hek($gv->NAME))) if $gv->NAME;
5447             } else {
5448             # XXX ifdef USE_ITHREADS and PL_curcop->op_flags & OPf_COP_TEMP
5449             # GvFILE is at gp+1
5450 0 0       0 $init->add( sprintf( "GvFILE(%s) = %s;", $sym, cstring( $gv->FILE ) ))
5451             unless $optimize_cop;
5452             warn "GV::save GvFILE(*$fullname) " . cstring( $gv->FILE ) . "\n"
5453 0 0 0     0 if $debug{gv} and !$ITHREADS;
5454             }
5455 0         0 my $gvform = $gv->FORM;
5456 0 0 0     0 if ( $$gvform && $savefields & Save_FORM ) {
5457 0 0       0 warn "GV::save GvFORM(*$fullname) ...\n" if $debug{gv};
5458 0         0 $gvform->save($fullname);
5459 0         0 $init->add( sprintf( "GvFORM(%s) = (CV*)s\\_%x;", $sym, $$gvform ));
5460             # glob_assign_glob analog to CV
5461 0 0       0 $init->add( sprintf( "SvREFCNT_inc(s\\_%x);", $$gvform )) if $PERL510;
5462 0 0       0 warn "GV::save GvFORM(*$fullname) done\n" if $debug{gv};
5463             }
5464 0         0 my $gvio = $gv->IO;
5465 0 0 0     0 if ( $$gvio && $savefields & Save_IO ) {
5466 0 0       0 warn "GV::save GvIO(*$fullname)...\n" if $debug{gv};
5467 0 0 0     0 if ( $fullname =~ m/::DATA$/ &&
    0 0        
      0        
5468             ( $fullname eq 'main::DATA' or $B::C::save_data_fh) ) # -O2 or 5.8
5469             {
5470 55     55   289 no strict 'refs';
  55         74  
  55         2243  
5471 0         0 my $fh = *{$fullname}{IO};
  0         0  
5472 55     55   206 use strict 'refs';
  55         110  
  55         485211  
5473 0 0       0 warn "GV::save_data $sym, $fullname ...\n" if $debug{gv};
5474 0         0 $gvio->save($fullname, 'is_DATA');
5475 0         0 $init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) );
5476 0 0       0 $gvio->save_data( $sym, $fullname, <$fh> ) if $fh->opened;
5477             } elsif ( $fullname =~ m/::DATA$/ && !$B::C::save_data_fh ) {
5478 0         0 $gvio->save($fullname, 'is_DATA');
5479 0         0 $init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) );
5480 0         0 warn "Warning: __DATA__ handle $fullname not stored. Need -O2 or -fsave-data.\n";
5481             } else {
5482 0         0 $gvio->save($fullname);
5483 0         0 $init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) );
5484             }
5485 0 0       0 warn "GV::save GvIO(*$fullname) done\n" if $debug{gv};
5486             }
5487 0         0 $init->add("");
5488             }
5489             }
5490             # Shouldn't need to do save_magic since gv_fetchpv handles that. Esp. < and IO not
5491             # $gv->save_magic($fullname) if $PERL510;
5492 0 0       0 warn "GV::save *$fullname done\n" if $debug{gv};
5493 0         0 return $sym;
5494             }
5495              
5496             sub B::AV::save {
5497 0     0   0 my ($av, $fullname, $cv) = @_;
5498 0         0 my $sym = objsym($av);
5499 0 0       0 return $sym if defined $sym;
5500              
5501 0 0       0 $fullname = '' unless $fullname;
5502 0         0 my ($fill, $avreal, $max, $static_av, $av_cow, $av_cog);
5503 0         0 my $ispadlist = ref($av) eq 'B::PADLIST';
5504 0         0 my $ispadnamelist = ref($av) eq 'B::PADNAMELIST';
5505 0 0 0     0 if ($ispadnamelist or $ispadlist) {
5506 0         0 $fill = $av->MAX;
5507             } else {
5508             # cornercase: tied array without FETCHSIZE
5509 0         0 eval { $fill = $av->FILL; };
  0         0  
5510 0 0       0 $fill = -1 if $@; # catch error in tie magic
5511             }
5512 0         0 $max = $fill;
5513 0 0       0 my $svpcast = $ispadlist ? "(PAD*)" : "(SV*)";
5514 0 0       0 $svpcast = "(PADNAME*)" if $ispadnamelist;
5515              
5516 0 0 0     0 if ($PERL522 and $ispadnamelist) {
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
      0        
      0        
5517 0         0 $padnlsect->comment("xpadnl_fill, xpadnl_alloc, xpadnl_max, xpadnl_max_named, xpadnl_refcnt");
5518             # TODO: max_named walk all names and look for non-empty names
5519 0         0 my $refcnt = $av->REFCNT + 1; # XXX defer free to global destruction: 28
5520 0         0 my $maxnamed = $av->MAXNAMED;
5521 0         0 $padnlsect->add("$fill, NULL, $fill, $maxnamed, $refcnt /* +1 */");
5522 0         0 $padnl_index = $padnlsect->index;
5523 0         0 $sym = savesym( $av, "&padnamelist_list[$padnl_index]" );
5524 0         0 push @B::C::static_free, $sym;
5525             }
5526             elsif ($ispadlist and $] >= 5.021008) { # id+outid as U32 (PL_padlist_generation++)
5527 0         0 $padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_id, xpadl_outid");
5528 0         0 my ($id, $outid) = ($av->ID, $av->OUTID);
5529 0         0 $padlistsect->add("$fill, NULL, $id, $outid");
5530 0         0 $padlist_index = $padlistsect->index;
5531 0         0 $sym = savesym( $av, "&padlist_list[$padlist_index]" );
5532             }
5533             elsif ($ispadlist and $] >= 5.017006 and $] < 5.021008) { # id added again with b4db586814
5534 0         0 $padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_outid");
5535 0         0 $padlistsect->add("$fill, NULL, NULL"); # Perl_pad_new(0)
5536 0         0 $padlist_index = $padlistsect->index;
5537 0         0 $sym = savesym( $av, "&padlist_list[$padlist_index]" );
5538 0 0 0     0 if ($cv and $cv->OUTSIDE and ref($cv->OUTSIDE) ne 'B::SPECIAL' and $cv->OUTSIDE->PADLIST) {
      0        
      0        
5539 0         0 my $outid = $cv->OUTSIDE->PADLIST->save();
5540 0 0       0 $init->add("($sym)->xpadl_outid = (PADNAMELIST*)$outid;") if $outid;
5541             }
5542             }
5543             elsif ($ispadlist and $] >= 5.017004) {
5544 0         0 $padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_id, xpadl_outid");
5545 0         0 $padlistsect->add("$fill, NULL, 0, 0"); # Perl_pad_new(0)
5546 0         0 $padlist_index = $padlistsect->index;
5547 0         0 $sym = savesym( $av, "&padlist_list[$padlist_index]" );
5548 0 0 0     0 if ($cv and $cv->OUTSIDE and ref($cv->OUTSIDE) ne 'B::SPECIAL' and $cv->OUTSIDE->PADLIST) {
      0        
      0        
5549 0         0 my $outid = $cv->OUTSIDE->PADLIST->save();
5550 0 0       0 $init->add("($sym)->xpadl_outid = (PADNAMELIST*)$outid;") if $outid;
5551             }
5552             }
5553             # we set it static, not perl. (c)perl only observes it.
5554             # decide if to store the array static (with run-time cow overhead) or dynamic
5555             elsif ($CPERL52 and $B::C::av_init and $fill > -1
5556             and (isAvSTATIC($av) or canAvSTATIC($av, $fullname)))
5557             {
5558 0         0 $xpvavsect->comment( "stash, magic, fill, max, static alloc" );
5559 0         0 my $alloc = "";
5560 0         0 my $count = 0;
5561 0         0 my $flags = $av->FLAGS;
5562             # decide upon cow (const array, SVf_READONLY) or just cog (forbid av_extend)
5563 0 0 0     0 my $av_cow = ($flags & SVf_READONLY or $fullname =~ /(::ISA|::INC|curpad_name)$/) ? 1 : 0;
5564 0         0 my $magic = ''; # need to skip ->ARRAY with 'D' magic, test 90
5565 0         0 foreach my $mg ($av->MAGIC) {
5566 0         0 $magic = $mg->TYPE;
5567 0 0       0 if ($magic eq 'D') {
5568 0         0 last;
5569             }
5570             }
5571 0 0       0 my @array = $magic eq 'D' ? () : $av->ARRAY;
5572 0         0 my $n = scalar @array;
5573 0 0       0 my $name = ($av_cow ? "avcow_" : "avcog_") . $n;
5574 0         0 my $avstaticsect;
5575 0 0       0 if ($av_cow) {
5576 0 0       0 $avcowsect{ $n } = new B::C::Section($name, \%symtable, 0) unless exists $avcowsect{ $n };
5577 0         0 $avstaticsect = $avcowsect{ $n };
5578             } else {
5579 0 0       0 $avcogsect{ $n } = new B::C::Section($name, \%symtable, 0) unless exists $avcogsect{ $n };
5580 0         0 $avstaticsect = $avcogsect{ $n };
5581             }
5582 0         0 my $sect = sprintf("&%s_list[%u]", $name, $avstaticsect->index + 1);
5583             # protect against duplicates
5584 0         0 $sym = savesym( $av, sprintf("(AV*)&sv_list[%u]", $svsect->index + 1));
5585              
5586             # $B::C::const_strings = 0 if $flags & 0x40008000 == 0x40008000; # SVp_SCREAM|SVpbm_VALID
5587 0 0       0 my @values = map { $_->save($fullname."[".$count++."]") || () } @array;
  0         0  
5588 0         0 for (my $i=0; $i <= $#array; $i++) {
5589             # if any value is non-static (GV), fall back to dynamic AV::save
5590 0 0       0 if (!is_constant($values[$i])) {
5591 0         0 $alloc = '';
5592 0         0 last;
5593             }
5594 0         0 $alloc .= $values[$i].", ";
5595             }
5596 0 0 0     0 if ($alloc and $n) {
5597 0         0 $static_av = 1;
5598             warn sprintf("turn on %s %s\n", $av_cow ? "AvIsCOW" : "AvSTATIC", $sym, $fullname)
5599 0 0       0 if $debug{av};
    0          
5600 0         0 $flags |= SVf_IsCOW; # turn on AvSTATIC
5601             # $flags |= SVf_READONLY if $av_cow; # and turn on COW
5602 0         0 $alloc = substr($alloc,0,-2);
5603 0         0 $avstaticsect->add( $alloc );
5604 0         0 $xpvavsect->add("Nullhv, {0}, $fill, $max, (SV**)$sect");
5605 0 0       0 $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}",
5606             $xpvavsect->index, $av->REFCNT, $flags,
5607             ($C99?".svu_array=(SV**)":"(char*)").$sect));
5608 0         0 $sym = savesym( $av, sprintf("(AV*)&sv_list[%u]", $svsect->index));
5609             } else {
5610             warn sprintf("turn off AvSTATIC %s %s\n", $sym, $fullname)
5611 0 0       0 if $debug{av};
5612 0         0 $flags &= ~SVf_IsCOW; # turn off AvSTATIC
5613 0         0 my $line = "Nullhv, {0}, -1, -1, 0";
5614 0 0 0     0 $line = "Nullhv, {0}, $fill, $max, 0" if $B::C::av_init or $B::C::av_init2;
5615 0         0 $xpvavsect->add($line);
5616 0         0 $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {0}",
5617             $xpvavsect->index, $av->REFCNT, $flags));
5618             }
5619             }
5620             elsif ($PERL514) {
5621 0         0 $xpvavsect->comment( "stash, magic, fill, max, alloc" );
5622             # 5.13.3: STASH, MAGIC, fill max ALLOC
5623 0         0 my $line = "Nullhv, {0}, -1, -1, 0";
5624 0 0 0     0 $line = "Nullhv, {0}, $fill, $max, 0" if $B::C::av_init or $B::C::av_init2;
5625 0         0 $xpvavsect->add($line);
5626 0         0 $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}",
5627             $xpvavsect->index, $av->REFCNT, $av->FLAGS,
5628             '0'));
5629             #$avreal = $av->FLAGS & 0x40000000; # SVpav_REAL (unused)
5630             }
5631             elsif ($PERL510) {
5632 0         0 $xpvavsect->comment( "xnv_u, fill, max, xiv_u, magic, stash" );
5633             # 5.9.4+: nvu fill max iv MG STASH
5634 0         0 my $line = "{0}, -1, -1, {0}, {0}, Nullhv";
5635 0 0 0     0 $line = "{0}, $fill, $max, {0}, {0}, Nullhv" if $B::C::av_init or $B::C::av_init2;
5636 0 0       0 $line = "Nullhv, {0}, $fill, $max, NULL" if $PERL514;
5637 0         0 $xpvavsect->add($line);
5638 0         0 $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}",
5639             $xpvavsect->index, $av->REFCNT, $av->FLAGS,
5640             '0'));
5641             #$avreal = $av->FLAGS & 0x40000000; # SVpav_REAL (unused)
5642             }
5643             else {
5644 0         0 $xpvavsect->comment( "array, fill, max, off, nv, magic, stash, alloc, arylen, flags" );
5645             # 5.8: ARRAY fill max off nv MG STASH ALLOC arylen flags
5646 0         0 my $line = "0, -1, -1, 0, 0.0, 0, Nullhv, 0, 0";
5647 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;
5648 0 0       0 $line .= sprintf( ", 0x%x", $av->AvFLAGS ) if $] < 5.009;
5649             #$avreal = $av->AvFLAGS & 1; # AVf_REAL
5650 0         0 $xpvavsect->add($line);
5651 0         0 $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x",
5652             $xpvavsect->index, $av->REFCNT, $av->FLAGS));
5653             }
5654              
5655 0         0 my ($magic, $av_index) = ('');
5656 0 0       0 $svsect->debug($fullname, $av->flagspv) if $debug{flags};
5657 0 0 0     0 if (!$ispadlist and !$ispadnamelist) {
5658 0         0 my $sv_ix = $svsect->index;
5659 0         0 $av_index = $xpvavsect->index;
5660             # protect against recursive self-references (Getopt::Long)
5661 0         0 $sym = savesym( $av, "(AV*)&sv_list[$sv_ix]" );
5662 0         0 $magic = $av->save_magic($fullname);
5663 0 0 0     0 push @B::C::static_free, $sym if $PERL518 and $av->FLAGS & SVs_OBJECT;
5664             }
5665              
5666 0 0       0 if ( $debug{av} ) {
5667 0         0 my $line = sprintf( "saving AV %s 0x%x [%s] FILL=%d", $fullname, $$av, B::class($av), $fill);
5668 0 0       0 $line .= sprintf( " AvFLAGS=0x%x", $av->AvFLAGS ) if $] < 5.009;
5669 0         0 warn "$line\n";
5670             }
5671              
5672             # XXX AVf_REAL is wrong test: need to save comppadlist but not stack
5673 0 0 0     0 if ($fill > -1 and $magic !~ /D/ and !$static_av) {
      0        
5674 0         0 my @array = $av->ARRAY; # crashes with D magic (Getopt::Long)
5675 0 0       0 if ( $debug{av} ) {
5676 0         0 my $i = 0;
5677 0         0 foreach my $el (@array) {
5678 0         0 my $val = '';
5679             # if SvIOK print iv, POK pv
5680 0 0       0 if ($el->can('FLAGS')) {
5681 0 0       0 $val = $el->IVX if $el->FLAGS & SVf_IOK;
5682 0 0       0 $val = cstring($el->PV) if $el->FLAGS & SVf_POK;
5683             }
5684 0         0 warn sprintf( "AV $av \[%d] = %s $val\n", $i++, B::class($el) );
5685             }
5686             }
5687              
5688             # my @names = map($_->save, @array);
5689             # XXX Better ways to write loop?
5690             # Perhaps svp[0] = ...; svp[1] = ...; svp[2] = ...;
5691             # Perhaps I32 i = 0; svp[i++] = ...; svp[i++] = ...; svp[i++] = ...;
5692              
5693             # micro optimization: op/pat.t ( and other code probably )
5694             # has very large pads ( 20k/30k elements ) passing them to
5695             # ->add is a performance bottleneck: passing them as a
5696             # single string cuts runtime from 6min20sec to 40sec
5697              
5698             # you want to keep this out of the no_split/split
5699             # map("\t*svp++ = (SV*)$_;", @names),
5700 0         0 my $acc = '';
5701             # Init optimization by Nick Koston
5702             # The idea is to create loops so there is less C code. In the real world this seems
5703             # to reduce the memory usage ~ 3% and speed up startup time by about 8%.
5704 0         0 my ($count, @values);
5705             {
5706 0         0 local $B::C::const_strings = $B::C::const_strings;
  0         0  
5707 0 0 0     0 if ($PERL510 and !$ispadlist) { # force dynamic PADNAME strings
5708 0 0       0 if ($] < 5.016) { $B::C::const_strings = 0 if $av->FLAGS & 0x40000000; } # SVpad_NAME
  0 0       0  
5709 0 0       0 else { $B::C::const_strings = 0 if ($av->FLAGS & 0x40008000 == 0x40008000); } # SVp_SCREAM|SVpbm_VALID
5710             }
5711 0 0       0 @values = map { $_->save($fullname."[".$count++."]") || () } @array;
  0         0  
5712             }
5713 0         0 $count = 0;
5714 0         0 for (my $i=0; $i <= $#array; $i++) {
5715 0 0 0     0 if ($fullname =~ m/^(INIT|END)$/ and $values[$i] and ref $array[$i] eq 'B::CV') {
      0        
5716 0 0       0 if ($array[$i]->XSUB) {
5717 0         0 $values[$i] =~ s/, 0\)/, GV_ADD\)/; # GvCV filled in later
5718             }
5719 0         0 $values[$i] = sprintf("SvREFCNT_inc(%s);", $values[$i]);
5720             }
5721 0 0 0     0 if ( $use_svpop_speedup
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
5722             && defined $values[$i]
5723             && defined $values[$i+1]
5724             && defined $values[$i+2]
5725             && $values[$i] =~ /^\&sv_list\[(\d+)\]/
5726             && $values[$i+1] eq "&sv_list[" . ($1+1) . "]"
5727             && $values[$i+2] eq "&sv_list[" . ($1+2) . "]" )
5728             {
5729 0         0 $count=0;
5730 0   0     0 while (defined($values[$i+$count+1]) and $values[$i+$count+1] eq "&sv_list[" . ($1+$count+1) . "]") {
5731 0         0 $count++;
5732             }
5733 0         0 $acc .= "\tfor (gcount=" . $1 . "; gcount<" . ($1+$count+1) . "; gcount++) {"
5734             ." *svp++ = $svpcast&sv_list[gcount]; };\n\t";
5735 0         0 $i += $count;
5736             } elsif ($use_av_undef_speedup
5737             && defined $values[$i]
5738             && defined $values[$i+1]
5739             && defined $values[$i+2]
5740             && $values[$i] =~ /^ptr_undef|&PL_sv_undef$/
5741             && $values[$i+1] =~ /^ptr_undef|&PL_sv_undef$/
5742             && $values[$i+2] =~ /^ptr_undef|&PL_sv_undef$/)
5743             {
5744 0         0 $count=0;
5745 0   0     0 while (defined $values[$i+$count+1] and $values[$i+$count+1] =~ /^ptr_undef|&PL_sv_undef$/) {
5746 0         0 $count++;
5747             }
5748 0         0 $acc .= "\tfor (gcount=0; gcount<" . ($count+1) . "; gcount++) {"
5749             ." *svp++ = $svpcast&PL_sv_undef; };\n\t";
5750 0         0 $i += $count;
5751             } else { # XXX 5.8.9d Test::NoWarnings has empty values
5752 0 0       0 $acc .= "\t*svp++ = $svpcast" . ($values[$i] ? $values[$i] : '&PL_sv_undef') . ";\n\t";
5753             }
5754             }
5755 0         0 $init->no_split;
5756              
5757 0 0       0 if ($ispadnamelist) {
    0          
    0          
    0          
5758 0         0 my $fill1 = $fill+1;
5759 0         0 $init->add("{", "\tPADNAME **svp;");
5760 0 0       0 $init->add("\tregister int gcount;") if $count;
5761 0         0 $init->add(
5762             "\tPADNAMELIST *padnl = $sym;",
5763             sprintf("\tNewxz(svp, %d, PADNAME *);", $fill+1),
5764             "\tPadnamelistARRAY(padnl) = svp;",
5765             );
5766 0         0 $init->add( substr( $acc, 0, -2 ) );
5767 0         0 $init->add("}");
5768             }
5769             elsif ($ispadlist) {
5770 0         0 my $fill1 = $fill+1;
5771 0         0 $init->add("{", "\tPAD **svp;");
5772 0 0       0 $init->add("\tregister int gcount;") if $count;
5773 0         0 $init->add(
5774             "\tPADLIST *padl = $sym;",
5775             sprintf("\tNewxz(svp, %d, PAD *);", $fill+1),
5776             "\tPadlistARRAY(padl) = svp;",
5777             );
5778 0         0 $init->add( substr( $acc, 0, -2 ) );
5779 0         0 $init->add("}");
5780             }
5781             # With -fav-init2 use independent_comalloc()
5782             elsif ($B::C::av_init2) {
5783 0         0 my $i = $av_index;
5784 0         0 $xpvav_sizes[$i] = $fill;
5785 0         0 my $init_add = "{ SV **svp = avchunks[$i]; AV *av = $sym;\n";
5786 0 0       0 $init_add .= "\tregister int gcount;\n" if $count;
5787 0 0       0 if ($fill > -1) {
5788 0 0       0 if ($PERL510) {
5789 0         0 $init_add .= "\tAvALLOC(av) = svp;\n".
5790             "\tAvARRAY(av) = svp;\n";
5791             } else {
5792 0         0 $init_add .= "\tAvALLOC(av) = svp;\n" .
5793             # XXX Dirty hack from av.c:Perl_av_extend()
5794             "\tSvPVX(av) = (char*)svp;";
5795             }
5796             }
5797 0         0 $init_add .= substr( $acc, 0, -2 );
5798 0         0 $init->add( $init_add . "}" );
5799             }
5800             # With -fav-init faster initialize the array as the initial av_extend()
5801             # is very expensive.
5802             # The problem was calloc, not av_extend.
5803             # Since we are always initializing every single element we don't need
5804             # calloc, only malloc. wmemset'ting the pointer to PL_sv_undef
5805             # might be faster also.
5806             elsif ($B::C::av_init) {
5807 0         0 $init->add(
5808             "{", "\tSV **svp;",
5809             "\tAV *av = $sym;");
5810 0 0       0 $init->add("\tregister int gcount;") if $count;
5811 0 0       0 my $fill1 = $fill < 3 ? 3 : $fill+1;
5812 0 0       0 if ($fill > -1) {
5813 0 0       0 $fill1 = $fill+1 if $fullname eq 'END';
5814             # Perl_safesysmalloc (= calloc => malloc) or Perl_malloc (= mymalloc)?
5815 0 0       0 if ($MYMALLOC) {
5816 0         0 $init->add(sprintf("\tNewx(svp, %d, SV*);", $fill1),
5817             "\tAvALLOC(av) = svp;");
5818             } else {
5819             # Bypassing Perl_safesysmalloc on darwin fails with "free from wrong pool", test 25.
5820             # So with DEBUGGING perls we have to track memory and use calloc.
5821 0         0 $init->add("#ifdef PERL_TRACK_MEMPOOL",
5822             sprintf("\tsvp = (SV**)Perl_safesysmalloc(%d * sizeof(SV*));", $fill1),
5823             "#else",
5824             sprintf("\tsvp = (SV**)malloc(%d * sizeof(SV*));", $fill1),
5825             "#endif",
5826             "\tAvALLOC(av) = svp;");
5827             }
5828 0 0       0 if ($PERL510) {
5829 0         0 $init->add("\tAvARRAY(av) = svp;");
5830             } else { # read-only AvARRAY macro
5831             # XXX Dirty hack from av.c:Perl_av_extend()
5832 0         0 $init->add("\tSvPVX(av) = (char*)svp;");
5833             }
5834             }
5835 0         0 $init->add( substr( $acc, 0, -2 ) ); # AvFILLp already in XPVAV
5836 0         0 $init->add( "}" );
5837             }
5838             else { # unoptimized with the full av_extend()
5839 0 0       0 my $fill1 = $fill < 3 ? 3 : $fill+1;
5840 0         0 $init->add("{", "\tSV **svp;");
5841 0 0       0 $init->add("\tregister int gcount;") if $count;
5842 0         0 $init->add("\tAV *av = $sym;\t/* $fullname */",
5843             "\tav_extend(av, $fill1);",
5844             "\tsvp = AvARRAY(av);");
5845 0         0 $init->add( substr( $acc, 0, -2 ) );
5846 0         0 $init->add( "\tAvFILLp(av) = $fill;" );
5847 0         0 $init->add( "}" );
5848             }
5849 0         0 $init->split;
5850              
5851             # we really added a lot of lines ( B::C::InitSection->add
5852             # should really scan for \n, but that would slow
5853             # it down
5854 0         0 $init->inc_count($#array);
5855             }
5856             else {
5857 0         0 my $max = $av->MAX;
5858 0 0 0     0 $init->add("av_extend($sym, $max);")
5859             if $max > -1 and !$static_av;
5860             }
5861 0 0       0 $init->add("SvREADONLY_on($sym);") if $av_cow;
5862 0         0 return $sym;
5863             }
5864              
5865             sub B::HV::save {
5866 0     0   0 my ($hv, $fullname) = @_;
5867 0 0       0 $fullname = '' unless $fullname;
5868 0         0 my $sym = objsym($hv);
5869 0 0       0 return $sym if defined $sym;
5870 0         0 my $name = $hv->NAME;
5871 0         0 my $is_stash = $name;
5872 0         0 my $magic;
5873 0 0       0 if ($name) {
5874             # It's a stash. See issue 79 + test 46
5875             warn sprintf( "Saving stash HV \"%s\" from \"$fullname\" 0x%x MAX=%d\n",
5876 0 0       0 $name, $$hv, $hv->MAX ) if $debug{hv};
5877              
5878             # A perl bug means HvPMROOT isn't altered when a PMOP is freed. Usually
5879             # the only symptom is that sv_reset tries to reset the PMf_USED flag of
5880             # a trashed op but we look at the trashed op_type and segfault.
5881             #my $adpmroot = ${$hv->PMROOT}; # XXX When was this fixed?
5882 0         0 my $adpmroot = 0;
5883 0         0 $sym = savestashpv($name);
5884 0         0 savesym( $hv, $sym );
5885 0 0       0 if ($adpmroot) {
5886 0         0 $init->add(sprintf( "HvPMROOT(hv%d) = (PMOP*)s\\_%x;",
5887             $hv_index, $adpmroot ) );
5888             }
5889 0 0 0     0 if ($PERL518 and $hv->FLAGS & SVf_AMAGIC and length($name)) {
      0        
5890             # fix overload stringify
5891 0 0       0 if ($hv->Gv_AMG) { # potentially removes the AMG flag
5892 0         0 $init2->add( sprintf("mro_isa_changed_in(%s); /* %s */", $sym, $name));
5893             }
5894             }
5895             # Add aliases if namecount > 1 (GH #331)
5896             # There was no B API for the count or multiple enames, so I added one.
5897 0 0       0 my @enames = ($PERL514 ? $hv->ENAMES : ());
5898 0 0       0 if (@enames > 1) {
5899 0 0       0 warn "Saving for $name multiple enames: ", join(" ",@enames), "\n" if $debug{hv};
5900 0         0 my $name_count = $hv->name_count;
5901             # If the stash name is empty xhv_name_count is negative, and names[0] should
5902             # be already set. but we rather write it.
5903 0         0 $init->no_split;
5904 0         0 my $hv_max = $hv->MAX + 1;
5905             # unshift @enames, $name if $name_count < 0; # stashpv has already set names[0]
5906 0         0 $init->add( "if (!SvOOK($sym)) {", # hv_auxinit is not exported
5907             " HE **a;",
5908             "#ifdef PERL_USE_LARGE_HV_ALLOC",
5909             sprintf( " Newxz(a, PERL_HV_ARRAY_ALLOC_BYTES(%d) + sizeof(struct xpvhv_aux), HE*);",
5910             $hv_max),
5911             "#else",
5912             sprintf( " Newxz(a, %d + sizeof(struct xpvhv_aux), HE*);", $hv_max),
5913             "#endif",
5914             " SvOOK_on($sym);",
5915             "}",
5916             "{",
5917             " struct xpvhv_aux *aux = HvAUX($sym);",
5918             sprintf( " Newx(aux->xhv_name_u.xhvnameu_names, %d, HEK*);", scalar @enames),
5919             sprintf( " aux->xhv_name_count = %d;", $name_count));
5920 0         0 my $i = 0;
5921 0         0 while (@enames) {
5922 0         0 my ($cstring, $cur, $utf8) = strlen_flags(shift @enames);
5923 0 0       0 $init->add(
5924             sprintf( " aux->xhv_name_u.xhvnameu_names[%u] = share_hek(%s, %d);",
5925             $i++, $cstring, $utf8 ? -$cur : $cur));
5926             }
5927 0         0 $init->add( "}" );
5928 0         0 $init->split;
5929             }
5930              
5931             # issue 79, test 46: save stashes to check for packages.
5932             # and via B::STASHGV we only save stashes for stashes.
5933             # For efficiency we skip most stash symbols unless -fstash.
5934             # However it should be now safe to save all stash symbols.
5935             # $fullname !~ /::$/ or
5936 0 0       0 if (!$B::C::stash) { # -fno-stash: do not save stashes
5937 0         0 $magic = $hv->save_magic('%'.$name.'::'); #symtab magic set in PMOP #188 (#267)
5938 0 0 0     0 if ($PERL510 and is_using_mro() && mro::get_mro($name) eq 'c3') {
      0        
5939 0         0 B::C::make_c3($name);
5940             }
5941 0 0 0     0 if ($magic and $magic =~ /c/) {
5942 0 0       0 warn "defer AMT magic of $name\n" if $debug{mg};
5943             # defer AMT magic of XS loaded hashes. #305 Encode::XS with tiehash magic
5944             # $init1->add(qq[$sym = gv_stashpvn($cname, $len, GV_ADDWARN|GV_ADDMULTI);]);
5945             }
5946 0         0 return $sym;
5947             }
5948 0 0 0     0 return $sym if skip_pkg($name) or $name eq 'main';
5949 0         0 $init->add( "SvREFCNT_inc($sym);" );
5950 0 0       0 warn "Saving stash keys for HV \"$name\" from \"$fullname\"\n" if $debug{hv};
5951             }
5952              
5953             # Ordinary HV or Stash
5954             # KEYS = 0, inc. dynamically below with hv_store. TODO: HvSTATIC readonly tables,
5955             # without hv_store
5956 0 0       0 if ($PERL510) {
5957 0         0 my $flags = $hv->FLAGS & ~SVf_READONLY;
5958 0 0       0 $flags &= ~SVf_PROTECT if $PERL522;
5959 0 0       0 if ($PERL514) { # fill removed with 5.13.1
5960 0         0 $xpvhvsect->comment( "stash mgu max keys" );
5961 0         0 $xpvhvsect->add(sprintf( "Nullhv, {0}, %d, %d",
5962             $hv->MAX, 0 ));
5963             } else {
5964 0         0 $xpvhvsect->comment( "GVSTASH fill max keys MG STASH" );
5965 0         0 $xpvhvsect->add(sprintf( "{0}, %d, %d, {%d}, {0}, Nullhv",
5966             0, $hv->MAX, 0 ));
5967             }
5968 0         0 $svsect->add(sprintf("&xpvhv_list[%d], $u32fmt, 0x%x, {0}",
5969             $xpvhvsect->index, $hv->REFCNT, $flags));
5970             # XXX failed at 16 (tied magic) for %main::
5971 0 0 0     0 if (!$is_stash and ($] >= 5.010 and $hv->FLAGS & SVf_OOK)) {
      0        
5972 0         0 $sym = sprintf("&sv_list[%d]", $svsect->index);
5973 0         0 my $hv_max = $hv->MAX + 1;
5974             # riter required, new _aux struct at the end of the HvARRAY. allocate ARRAY also.
5975 0         0 $init->add("{\tHE **a;",
5976             "#ifdef PERL_USE_LARGE_HV_ALLOC",
5977             sprintf("\tNewxz(a, PERL_HV_ARRAY_ALLOC_BYTES(%d) + sizeof(struct xpvhv_aux), HE*);",
5978             $hv_max),
5979             "#else",
5980             sprintf("\tNewxz(a, %d + sizeof(struct xpvhv_aux), HE*);", $hv_max),
5981             "#endif",
5982             "\tHvARRAY($sym) = a;",
5983             sprintf("\tHvRITER_set($sym, %d);", $hv->RITER),"}");
5984             }
5985             } # !5.10
5986             else {
5987 0         0 $xpvhvsect->comment( "array fill max keys nv mg stash riter eiter pmroot name" );
5988 0         0 $xpvhvsect->add(sprintf( "0, 0, %d, 0, 0.0, 0, Nullhv, %d, 0, 0, 0",
5989             $hv->MAX, $hv->RITER));
5990 0         0 $svsect->add(sprintf( "&xpvhv_list[%d], $u32fmt, 0x%x",
5991             $xpvhvsect->index, $hv->REFCNT, $hv->FLAGS));
5992             }
5993 0 0       0 $svsect->debug($fullname, $hv->flagspv) if $debug{flags};
5994 0         0 my $sv_list_index = $svsect->index;
5995             warn sprintf( "saving HV %s &sv_list[%d] 0x%x MAX=%d KEYS=%d\n",
5996 0 0       0 "%".$fullname, $sv_list_index, $$hv, $hv->MAX, $hv->KEYS ) if $debug{hv};
5997             # XXX B does not keep the UTF8 flag [RT 120535] #200
5998             # shared heks only since 5.10, our fixed C.xs variant
5999 0 0 0     0 my @contents = ($PERL510 && $hv->can('ARRAY_utf8')) ? $hv->ARRAY_utf8 : $hv->ARRAY;
6000             # protect against recursive self-reference
6001             # i.e. with use Moose at stash Class::MOP::Class::Immutable::Trait
6002             # value => rv => cv => ... => rv => same hash
6003 0 0       0 $sym = savesym( $hv, "(HV*)&sv_list[$sv_list_index]" ) unless $is_stash;
6004 0 0 0     0 push @B::C::static_free, $sym if $PERL518 and $hv->FLAGS & SVs_OBJECT;
6005              
6006 0 0       0 if (@contents) {
    0          
6007 0         0 local $B::C::const_strings = $B::C::const_strings;
6008 0         0 my ($i, $length);
6009 0         0 $length = scalar(@contents);
6010 0         0 for ( $i = 1 ; $i < @contents ; $i += 2 ) {
6011 0         0 my $key = $contents[$i - 1]; # string only
6012 0         0 my $sv = $contents[$i];
6013             warn sprintf("HV recursion? with $fullname\{$key\} -> %s\n", $sv->RV)
6014             if ref($sv) eq 'B::RV'
6015             #and $sv->RV->isa('B::CV')
6016             and defined objsym($sv)
6017 0 0 0     0 and $debug{hv};
      0        
6018 0 0       0 if ($is_stash) {
6019 0 0 0     0 if (ref($sv) eq "B::GV" and $sv->NAME =~ /::$/) {
6020 0         0 $sv = bless $sv, "B::STASHGV"; # do not expand stash GV's only other stashes
6021 0 0       0 warn "saving STASH $fullname".'{'.$key."}\n" if $debug{hv};
6022 0         0 $contents[$i] = $sv->save($fullname.'{'.$key.'}');
6023             } else {
6024 0 0       0 warn "skip STASH symbol *",$fullname.$key,"\n" if $debug{hv};
6025 0         0 $contents[$i] = undef;
6026 0         0 $length -= 2;
6027             # warn "(length=$length)\n" if $debug{hv};
6028             }
6029             } else {
6030 0 0       0 warn "saving HV \$".$fullname.'{'.$key."} $sv\n" if $debug{hv};
6031 0         0 $contents[$i] = $sv->save($fullname.'{'.$key.'}');
6032             #if ($key eq "" and $] >= 5.010) {
6033             # warn " turn off HvSHAREKEYS with empty keysv\n" if $debug{hv};
6034             # $init->add("HvSHAREKEYS_off(&sv_list[$sv_list_index]);");
6035             #}
6036             }
6037             }
6038 0 0       0 if ($length) { # there may be skipped STASH symbols
6039 0         0 $init->no_split;
6040 0 0       0 $init->add( "{",
6041             sprintf("\tHV *hv = %s%s;", $sym=~/^hv|\(HV/ ? '' : '(HV*)', $sym ));
6042 0         0 while (@contents) {
6043 0         0 my ( $key, $value ) = splice( @contents, 0, 2 );
6044 0 0       0 if ($value) {
6045 0 0 0     0 $value = "(SV*)$value" if $value !~ /^&sv_list/ or ($PERL510 and $] < 5.012);
      0        
6046 0         0 my ($cstring, $cur, $utf8) = strlen_flags($key);
6047             # issue 272: if SvIsCOW(sv) && SvLEN(sv) == 0 => sharedhek (key == "")
6048             # >= 5.10: SvSHARED_HASH: PV offset to hek_hash
6049 0 0       0 $cur = -$cur if $utf8;
6050 0         0 $init->add(sprintf( "\thv_store(hv, %s, %d, %s, 0);",
6051             $cstring, $cur, $value )); # !! randomized hash keys
6052 0 0       0 warn sprintf( " HV key \"%s\" = %s\n", $key, $value) if $debug{hv};
6053 0 0 0     0 if (!$swash_ToCf and $fullname =~ /^utf8::SWASHNEW/
      0        
      0        
6054             and $cstring eq '"utf8\034unicore/To/Cf.pl\0340"' and $cur == 23)
6055             {
6056 0         0 $swash_ToCf = $value;
6057 0 0       0 warn sprintf( "Found PL_utf8_tofold ToCf swash $value\n") if $verbose;
6058             }
6059             }
6060             }
6061 0         0 $init->add("}");
6062 0         0 $init->split;
6063 0 0       0 $init->add( sprintf("HvTOTALKEYS(%s) = %d;", $sym, $length / 2)) if !$PERL56;
6064             }
6065             } elsif ($PERL514) { # empty contents still needs to set keys=0
6066             # test 36, 140
6067 0         0 $init->add( "HvTOTALKEYS($sym) = 0;");
6068             }
6069 0         0 $magic = $hv->save_magic($fullname);
6070 0 0       0 $init->add( "SvREADONLY_on($sym);") if $hv->FLAGS & SVf_READONLY;
6071 0 0       0 if ($magic =~ /c/) {
6072             # defer AMT magic of XS loaded stashes
6073 0         0 my ($cname, $len, $utf8) = strlen_flags($name);
6074 0         0 $init2->add(qq[$sym = gv_stashpvn($cname, $len, GV_ADDWARN|GV_ADDMULTI|$utf8);]);
6075             }
6076 0 0 0     0 if ($PERL510 and $name and is_using_mro() and mro::get_mro($name) eq 'c3') {
      0        
      0        
6077 0         0 B::C::make_c3($name);
6078             }
6079 0         0 return $sym;
6080             }
6081              
6082             sub B::IO::save_data {
6083 0     0   0 my ( $io, $sym, $globname, @data ) = @_;
6084 0         0 my $data = join '', @data;
6085             # XXX using $DATA might clobber it!
6086 0         0 my $ref = svref_2object( \\$data )->save;
6087 0 0       0 $init->add("/* save $globname in RV ($ref) */") if $verbose;
6088 0         0 $init->add( "GvSVn( $sym ) = (SV*)$ref;");
6089              
6090 0 0       0 if ($PERL56) {
6091             # Pseudo FileHandle
6092 0         0 $init2->add_eval( sprintf 'open(%s, \'<\', $%s);', $globname, $globname );
6093             } else { # force inclusion of PerlIO::scalar as it was loaded in BEGIN.
6094 0         0 $init2->add_eval( sprintf 'open(%s, \'<:scalar\', $%s);', $globname, $globname );
6095             # => eval_pv("open(main::DATA, '<:scalar', $main::DATA);",1); DATA being a ref to $data
6096 0         0 $init->pre_destruct( sprintf 'eval_pv("close %s;", 1);', $globname );
6097 0         0 $use_xsloader = 1; # layers are not detected as XSUB CV, so force it
6098 0 0       0 require PerlIO unless $savINC{'PerlIO.pm'};
6099 0 0       0 require PerlIO::scalar unless $savINC{'PerlIO/scalar.pm'};
6100 0         0 mark_package("PerlIO", 1);
6101 0         0 $curINC{'PerlIO.pm'} = $INC{'PerlIO.pm'}; # as it was loaded from BEGIN
6102 0         0 mark_package("PerlIO::scalar", 1);
6103 0         0 $curINC{'PerlIO/scalar.pm'} = $INC{'PerlIO/scalar.pm'};
6104 0         0 $xsub{'PerlIO::scalar'} = 'Dynamic-'.$INC{'PerlIO/scalar.pm'}; # force dl_init boot
6105             }
6106             }
6107              
6108             sub B::IO::save {
6109 0     0   0 my ($io, $fullname, $is_DATA) = @_;
6110 0         0 my $sym = objsym($io);
6111 0 0       0 return $sym if defined $sym;
6112 0         0 my $pv = $io->PV;
6113 0 0       0 $pv = '' unless defined $pv;
6114 0         0 my ( $pvsym, $len, $cur );
6115 0 0       0 if ($pv) {
6116 0         0 $pvsym = savepv($pv);
6117 0         0 $cur = $io->CUR;
6118             } else {
6119 0         0 $pvsym = 'NULL';
6120 0         0 $cur = 0;
6121             }
6122 0 0       0 if ($cur) {
6123 0         0 $len = $cur + 1;
6124 0 0 0     0 $len++ if IsCOW($io) and !$B::C::cow;
6125             } else {
6126 0         0 $len = 0;
6127             }
6128             warn sprintf( "IO $fullname sv_list[%d] 0x%x (%s) = '%s'\n", $svsect->index+1, $$io, $io->SvTYPE, $pv )
6129 0 0 0     0 if $debug{sv} and $] > 5.008; # no method "SvTYPE" via package "B::IO"
6130 0 0       0 if ($PERL514) {
    0          
    0          
6131             # IFP in sv.sv_u.svu_fp
6132 0         0 $xpviosect->comment("STASH, xmg_u, cur, len, xiv_u, xio_ofp, xio_dirpu, page, page_len, ..., type, flags");
6133 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*/";
6134 0 0       0 $tmpl =~ s{ /\*.+?\*/\n\t}{}g unless $verbose;
6135 0 0       0 $tmpl =~ s{ /\*flags\*/$}{} unless $verbose;
6136 0         0 $xpviosect->add(
6137             sprintf($tmpl,
6138             $cur, $len,
6139             $io->LINES, # moved to IVX with 5.11.1
6140             $io->PAGE, $io->PAGE_LEN,
6141             $io->LINES_LEFT, "NULL",
6142             "NULL", "NULL",
6143             cchar( $io->IoTYPE ), $io->IoFLAGS
6144             )
6145             );
6146 0 0       0 $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}",
6147             $xpviosect->index, $io->REFCNT, $io->FLAGS,
6148             $B::C::pv_copy_on_grow ? $pvsym : 0));
6149             }
6150             elsif ($] > 5.011000) {
6151 0         0 $xpviosect->comment("xnv_u, cur, len, lines, xmg_u, xmg_stash, xio_ifp, xio_ofp, xio_dirpu, ..., type, flags");
6152 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*/";
6153 0 0       0 $tmpl =~ s{ /\*.+?\*/\n\t}{}g unless $verbose;
6154 0 0       0 $tmpl =~ s{ /\*flags\*/$}{} unless $verbose;
6155 0         0 $xpviosect->add(
6156             sprintf($tmpl,
6157             $cur, $len,
6158             $io->LINES, # moved to IVX with 5.11.1
6159             $io->PAGE, $io->PAGE_LEN,
6160             $io->LINES_LEFT, "NULL",
6161             "NULL", "NULL",
6162             cchar( $io->IoTYPE ), $io->IoFLAGS
6163             )
6164             );
6165 0 0       0 $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}",
6166             $xpviosect->index, $io->REFCNT, $io->FLAGS,
6167             $B::C::pv_copy_on_grow ? $pvsym : 0));
6168             }
6169             elsif ($PERL510) {
6170 0         0 $xpviosect->comment("xnv_u, cur, len, xiv_u, xmg_u, xmg_stash, xio_ifp, xio_ofp, xio_dirpu, lines, ..., type, flags");
6171 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*/";
6172 0 0       0 $tmpl =~ s{ /\*[^\*]+?\*/\n\t}{}g unless $verbose;
6173 0 0       0 $tmpl =~ s{ /\*flags\*/$}{} unless $verbose;
6174 0         0 $xpviosect->add(
6175             sprintf($tmpl,
6176             $cur, $len,
6177             $io->IVX,
6178             $io->LINES,
6179             $io->PAGE, $io->PAGE_LEN,
6180             $io->LINES_LEFT, "NULL",
6181             "NULL", "NULL",
6182             cchar( $io->IoTYPE ), $io->IoFLAGS
6183             )
6184             );
6185 0 0       0 $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}",
6186             $xpviosect->index, $io->REFCNT, $io->FLAGS,
6187             $B::C::pv_copy_on_grow ? $pvsym : 0));
6188             }
6189             else { # 5.6 and 5.8
6190 0         0 $xpviosect->comment("xpv_pv, cur, len, iv, nv, magic, stash, xio_ifp, xio_ofp, xio_dirpu, ..., subprocess, type, flags");
6191 0         0 $xpviosect->add(
6192             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",
6193             $pvsym, $cur, $len,
6194             $io->IVX, $io->NVX,
6195             $io->LINES, $io->PAGE,
6196             $io->PAGE_LEN, $io->LINES_LEFT,
6197             "NULL", "NULL",
6198             "NULL", $io->SUBPROCESS,
6199             cchar( $io->IoTYPE ), $io->IoFLAGS
6200             )
6201             );
6202 0         0 $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x",
6203             $xpviosect->index, $io->REFCNT, $io->FLAGS));
6204             }
6205 0 0       0 $svsect->debug($fullname, $io->flagspv) if $debug{flags};
6206 0         0 $sym = savesym( $io, sprintf( "(IO*)&sv_list[%d]", $svsect->index ) );
6207              
6208 0 0 0     0 if ($PERL510 and !$B::C::pv_copy_on_grow and $cur) {
      0        
6209 0         0 $init->add(sprintf("SvPVX(sv_list[%d]) = %s;", $svsect->index, $pvsym));
6210             }
6211 0         0 my ( $field );
6212 0         0 foreach $field (qw(TOP_GV FMT_GV BOTTOM_GV)) {
6213 0         0 my $fsym = $io->$field();
6214 0 0       0 if ($$fsym) {
6215 0         0 $init->add( sprintf( "Io%s(%s) = (GV*)s\\_%x;", $field, $sym, $$fsym ) );
6216 0         0 $fsym->save;
6217             }
6218             }
6219 0         0 foreach $field (qw(TOP_NAME FMT_NAME BOTTOM_NAME)) {
6220 0         0 my $fsym = $io->$field;
6221 0 0       0 $init->add(sprintf("Io%s(%s) = savepvn(%s, %u);", $field, $sym,
6222             cstring( $fsym ), length $fsym)) if $fsym;
6223             }
6224 0         0 $io->save_magic($fullname); # This handle the stash also (we need to inc the refcnt)
6225 0 0 0     0 if (!$PERL56 and !$is_DATA) { # PerlIO
6226             # deal with $x = *STDIN/STDOUT/STDERR{IO} and aliases
6227 0         0 my $perlio_func;
6228             # Note: all single-direction fp use IFP, just bi-directional pipes and
6229             # sockets use OFP also. But we need to set both, pp_print checks OFP.
6230 0         0 my $o = $io->object_2svref();
6231 0         0 eval "require ".ref($o).";";
6232 0         0 my $fd = $o->fileno();
6233             # use IO::Handle ();
6234             # my $fd = IO::Handle::fileno($o);
6235 0         0 my $i = 0;
6236 0         0 foreach (qw(stdin stdout stderr)) {
6237 0 0 0     0 if ($io->IsSTD($_) or (defined($fd) and $fd == -$i)) {
      0        
6238 0         0 $perlio_func = $_;
6239             }
6240 0         0 $i++;
6241             }
6242 0 0       0 if ($perlio_func) {
6243 0         0 $init->add("IoIFP(${sym}) = IoOFP(${sym}) = PerlIO_${perlio_func}();");
6244             #if ($fd < 0) { # fd=-1 signals an error
6245             # XXX print may fail at flush == EOF, wrong init-time?
6246             #}
6247             } else {
6248 0         0 my $iotype = $io->IoTYPE;
6249 0         0 my $ioflags = $io->IoFLAGS;
6250             # If an IO handle was opened at BEGIN, we try to re-init it, based on fd and IoTYPE.
6251             # IOTYPE:
6252             # - STDIN/OUT HANDLE IoIOFP alias
6253             # I STDIN/OUT/ERR HANDLE IoIOFP alias
6254             # < read-only HANDLE fdopen
6255             # > write-only HANDLE if fd<3 or IGNORE warn and comment
6256             # a append HANDLE -"-
6257             # + read and write HANDLE fdopen
6258             # s socket DIE
6259             # | pipe DIE
6260             # # NUMERIC HANDLE fdopen
6261             # space closed IGNORE
6262             # \0 ex/closed? IGNORE
6263 0 0 0     0 if ($iotype eq "\c@" or $iotype eq " ") {
    0          
    0          
6264             warn sprintf("Ignore closed IO Handle %s %s (%d)\n",
6265             cstring($iotype), $fullname, $ioflags)
6266 0 0       0 if $debug{gv};
6267             }
6268             elsif ($iotype =~ /[a>]/) { # write-only
6269 0 0 0     0 warn "Warning: Write BEGIN-block $fullname to FileHandle $iotype \&$fd\n"
6270             if $fd >= 3 or $verbose;
6271 0 0       0 my $mode = $iotype eq '>' ? 'w' : 'a';
6272             #$init->add( sprintf("IoIFP($sym) = IoOFP($sym) = PerlIO_openn(aTHX_ NULL,%s,%d,0,0,NULL,0,NULL);",
6273             # cstring($mode), $fd));
6274 0 0       0 $init->add(sprintf( "%sIoIFP(%s) = IoOFP(%s) = PerlIO_fdopen(%d, %s);%s",
    0          
6275             $fd<3?'':'/*', $sym, $sym, $fd, cstring($mode), $fd<3?'':'*/'));
6276             }
6277             elsif ($iotype =~ /[<#\+]/) {
6278             # skips warning if it's one of our PerlIO::scalar __DATA__ handles
6279 0 0 0     0 warn "Warning: Read BEGIN-block $fullname from FileHandle $iotype \&$fd\n"
6280             if $fd >= 3 or $verbose; # need to setup it up before
6281 0         0 $init->add("/* XXX WARNING: Read BEGIN-block $fullname from FileHandle */",
6282             "IoIFP($sym) = IoOFP($sym) = PerlIO_fdopen($fd, \"r\");");
6283 0         0 my $tell;
6284 0 0 0     0 if ($io->can("tell") and $tell = $io->tell()) {
6285 0         0 $init->add("PerlIO_seek(IoIFP($sym), $tell, SEEK_SET);")
6286             }
6287             } else {
6288             # XXX We should really die here
6289 0         0 warn sprintf("ERROR: Unhandled BEGIN-block IO Handle %s\&%d (%d) from %s\n",
6290             cstring($iotype), $fd, $ioflags, $fullname);
6291 0         0 $init->add("/* XXX WARNING: Unhandled BEGIN-block IO Handle ",
6292             "IoTYPE=$iotype SYMBOL=$fullname, IoFLAGS=$ioflags */",
6293             "IoIFP($sym) = IoOFP($sym) = PerlIO_fdopen($fd, \"$iotype\");");
6294             }
6295             }
6296             }
6297              
6298 0 0       0 if ( $PERL518 ) {
6299 0         0 my $stash = $io->SvSTASH;
6300 0 0 0     0 if ($stash and $$stash) {
6301 0         0 my $stsym = $stash->save("%".$stash->NAME);
6302 0         0 $init->add(
6303             sprintf( "SvREFCNT(%s) += 1;", $stsym ),
6304             sprintf( "SvSTASH_set(%s, %s);", $sym, $stsym )
6305             );
6306             warn sprintf( "done saving STASH %s %s for IO %s\n", $stash->NAME, $stsym, $sym )
6307 0 0       0 if $debug{gv};
6308             }
6309             }
6310              
6311 0         0 return $sym;
6312             }
6313              
6314             sub B::SV::save {
6315 0     0   0 my $sv = shift;
6316              
6317             # This is where we catch an honest-to-goodness Nullsv (which gets
6318             # blessed into B::SV explicitly) and any stray erroneous SVs.
6319 0 0       0 return 0 unless $$sv;
6320 0         0 warn sprintf( "cannot save that type of SV: %s (0x%x)\n", B::class($sv), $$sv );
6321             }
6322              
6323             sub output_all {
6324 0     0 0 0 my $init_name = shift;
6325 0         0 my $section;
6326 0 0       0 return if $check;
6327              
6328 0         0 my @sections =
6329             (
6330             $copsect, $opsect, $unopsect, $binopsect, $logopsect, $condopsect,
6331             $listopsect, $pmopsect, $svopsect, $padopsect, $pvopsect, $loopsect,
6332             $methopsect, $unopauxsect,
6333             $xpvsect, $xpvavsect, $xpvhvsect, $xpvcvsect, $padlistsect,
6334             $padnlsect, $xpvivsect, $xpvuvsect, $xpvnvsect, $xpvmgsect, $xpvlvsect,
6335             $xrvsect, $xpvbmsect, $xpviosect, $svsect, $padnamesect,
6336             );
6337 0 0       0 if ($PERL522) {
6338 0         0 pop @sections;
6339 0         0 for my $n (sort keys %padnamesect) {
6340 0         0 push @sections, $padnamesect{$n};
6341             }
6342             }
6343 0 0       0 if ($CPERL52) {
6344 0         0 for my $n (sort keys %avcowsect) {
6345 0         0 push @sections, $avcowsect{$n};
6346             }
6347 0         0 for my $n (sort keys %avcogsect) {
6348 0         0 push @sections, $avcogsect{$n};
6349             }
6350             }
6351 0 0 0     0 printf "\t/* %s */", $symsect->comment if $symsect->comment and $verbose;
6352 0         0 $symsect->output( \*STDOUT, "#define %s\n" );
6353 0         0 print "\n";
6354 0         0 output_declarations();
6355             # XXX add debug versions with ix=opindex if $debug{flags}
6356 0         0 foreach $section (@sections) {
6357 0         0 my $lines = $section->index + 1;
6358 0 0       0 if ($lines) {
6359 0         0 my $name = $section->name;
6360 0         0 my $typename = $section->typename;
6361             # static SV** arrays for AvSTATIC, HvSTATIC, ...
6362 0 0 0     0 if ($typename eq 'SV*' and $name =~ /^(?:avco[gw])_(\d+)$/) {
6363 0         0 my $n = $1;
6364 0 0       0 $typename = 'const SV*' if $name =~ /^avcow_/;
6365 0         0 print "Static $typename ${name}_list[$lines][$n];\n";
6366             } else {
6367 0         0 print "Static $typename ${name}_list[$lines];\n";
6368             }
6369             }
6370             }
6371              
6372             # hack for when Perl accesses PVX of GVs
6373 0         0 print 'Static const char emptystring[] = "\0";',"\n";
6374             # newXS for core XS needs a filename
6375 0         0 print 'Static const char xsfile[] = "universal.c";',"\n";
6376 0 0       0 if ($MULTI) {
6377 0         0 print "#define ptr_undef 0\n";
6378             } else {
6379 0 0       0 if ($] > 5.01903) {
6380 0         0 print "#define ptr_undef NULL\n";
6381             } else {
6382 0         0 print "#define ptr_undef &PL_sv_undef\n";
6383             }
6384 0 0       0 if ($PERL510) { # XXX const sv SIGSEGV
6385 0         0 print "#undef CopFILE_set\n";
6386 0         0 print "#define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv))\n";
6387             }
6388             }
6389             # print "#define MyPVX(sv) ".($] < 5.010 ? "SvPVX(sv)" : "((sv)->sv_u.svu_pv)")."\n";
6390 0 0       0 if ($] < 5.008008 ) {
6391 0         0 print <<'EOT';
6392             #ifndef SvSTASH_set
6393             # define SvSTASH_set(sv,hv) SvSTASH((sv)) = (hv)
6394             #endif
6395             #ifndef Newxz
6396             # define Newxz(v,n,t) Newz(0,v,n,t)
6397             #endif
6398             EOT
6399             }
6400 0 0       0 if ($] < 5.008009 ) {
6401 0         0 print <<'EOT';
6402             #ifndef SvREFCNT_inc_simple_NN
6403             # define SvREFCNT_inc_simple_NN(sv) (++SvREFCNT(sv), (SV*)(sv))
6404             #endif
6405             #ifndef STR_WITH_LEN
6406             #define STR_WITH_LEN(s) ("" s ""), (sizeof(s)-1)
6407             #endif
6408             EOT
6409             }
6410 0 0       0 if ($] < 5.013007 ) {
6411 0         0 print <<'EOT';
6412             #ifndef CvSTASH_set
6413             # define CvSTASH_set(cv,hv) CvSTASH((cv)) = (hv)
6414             #endif
6415             EOT
6416             }
6417 0 0       0 if ($] < 5.013010 ) { # added with c43ae56ff9cd before 5.13.10 at 2011-01-21
6418 0         0 print <<'EOT';
6419             #ifndef GvCV_set
6420             # define GvCV_set(gv,cv) (GvCV(gv) = (cv))
6421             #endif
6422             #ifndef GvGP_set
6423             # define GvGP_set(gv,gp) (GvGP(gv) = (gp))
6424             #endif
6425             EOT
6426             }
6427 0 0 0     0 if ($] >= 5.021005 and $] < 5.023) {
6428 0         0 print <<'EOT';
6429             /* PadlistNAMES broken as lvalue with v5.21.6-197-g0f94cb1,
6430             fixed with 5.22.1 and 5.23.0 */
6431             #if (PERL_VERSION == 22) || ( PERL_VERSION == 21 && PERL_SUBVERSION > 5)
6432             # undef PadlistNAMES
6433             # define PadlistNAMES(pl) *((PADNAMELIST **)PadlistARRAY(pl))
6434             #endif
6435             EOT
6436             }
6437             # handy accessors only in cperl for now:
6438 0         0 print <<'EOT';
6439             #ifndef get_svs
6440             # define get_svs(str, flags) get_sv((str), (flags))
6441             # define get_avs(str, flags) get_av((str), (flags))
6442             # define get_hvs(str, flags) get_hv((str), (flags))
6443             #endif
6444             EOT
6445 0 0 0     0 if (%init2_remap and !$HAVE_DLFCN_DLOPEN) {
6446 0         0 print <<'EOT';
6447             XS(XS_DynaLoader_dl_load_file);
6448             XS(XS_DynaLoader_dl_find_symbol);
6449             EOT
6450             }
6451 0 0 0     0 printf "\t/* %s */\n", $decl->comment if $decl->comment and $verbose;
6452 0         0 $decl->output( \*STDOUT, "%s\n" );
6453 0         0 print "\n";
6454              
6455 0         0 foreach $section (@sections) {
6456 0         0 my $lines = $section->index + 1;
6457 0 0       0 if ($lines) {
6458 0         0 my $name = $section->name;
6459 0         0 my $typename = $section->typename;
6460             # static SV** arrays for AvSTATIC, HvSTATIC, ...
6461 0 0 0     0 if ($typename eq 'SV*' and $name =~ /^(?:avco[wg])_(\d+)$/) {
6462 0         0 my $n = $1;
6463 0 0       0 $typename = 'const SV*' if $name =~ /^avcow_/;
6464 0         0 printf "Static %s %s_list[%u][%u] = {\n", $typename, $name, $lines, $n;
6465             } else {
6466 0         0 printf "Static %s %s_list[%u] = {\n", $typename, $name, $lines;
6467             }
6468 0 0 0     0 printf "\t/* %s */\n", $section->comment
6469             if $section->comment and $verbose;
6470 0         0 $section->output( \*STDOUT, "\t{ %s }, /* %s_list[%d] %s */%s\n" );
6471 0         0 print "};\n\n";
6472             }
6473             }
6474              
6475 0         0 fixup_ppaddr();
6476 0         0 print "static void perl_init0(pTHX) /* fixup_ppaddr */\n{\n\t";
6477 0 0       0 print "register int i;\n" if @{ $init0->[-1]{values} };
  0         0  
6478 0         0 $init0->output( \*STDOUT, "\t%s\n" );
6479 0         0 print "};\n\n";
6480              
6481 0 0 0     0 printf "\t/* %s */\n", $init->comment if $init->comment and $verbose;
6482 0         0 $init->output( \*STDOUT, "\t%s\n", $init_name );
6483 0 0       0 printf "/* deferred init1 of regexp */\n" if $verbose;
6484 0 0 0     0 printf "/* %s */\n", $init1->comment if $init1->comment and $verbose;
6485 0         0 $init1->output( \*STDOUT, "\t%s\n", 'perl_init1' );
6486 0         0 my $init2_name = 'perl_init2';
6487 0 0       0 printf "/* deferred init of XS/Dyna loaded modules */\n" if $verbose;
6488 0 0 0     0 printf "/* %s */\n", $init2->comment if $init2->comment and $verbose;
6489 0         0 my $remap = 0;
6490 0         0 for my $pkg (sort keys %init2_remap) {
6491 0 0       0 if (exists $xsub{$pkg}) { # check if not removed in between
6492 0         0 my ($stashfile) = $xsub{$pkg} =~ /^Dynamic-(.+)$/;
6493             # get so file from pm. Note: could switch prefix from vendor/site//
6494 0 0       0 if ($stashfile) {
6495 0         0 $init2_remap{$pkg}{FILE} = dl_module_to_sofile($pkg, $stashfile);
6496 0         0 $remap++;
6497             }
6498             }
6499             }
6500 0 0       0 if ($remap) {
6501             # XXX now emit arch-specific dlsym code
6502 0         0 $init2->no_split;
6503 0         0 $init2->add("{");
6504 0 0       0 if ($HAVE_DLFCN_DLOPEN) {
6505 0         0 $init2->add(" #include ");
6506 0         0 $init2->add(" void *handle;");
6507             } else {
6508 0         0 $init2->add(" void *handle;");
6509 0         0 $init2->add(" dTARG; dSP;",
6510             " targ=sv_newmortal();");
6511             }
6512 0         0 for my $pkg (sort keys %init2_remap) {
6513 0 0       0 if (exists $xsub{$pkg}) {
6514 0 0       0 if ($HAVE_DLFCN_DLOPEN) {
6515 0         0 my $ldopt = 'RTLD_NOW|RTLD_NOLOAD';
6516 0 0       0 $ldopt = 'RTLD_NOW' if $^O =~ /bsd/i; # 351 (only on solaris and linux, not any bsd)
6517 0         0 $init2->add( "", sprintf(" handle = dlopen(%s, %s);", cstring($init2_remap{$pkg}{FILE}), $ldopt));
6518             }
6519             else {
6520             $init2->add(" PUSHMARK(SP);",
6521 0         0 sprintf(" XPUSHs(newSVpvs(%s));", cstring($init2_remap{$pkg}{FILE})),
6522             " PUTBACK;",
6523             " XS_DynaLoader_dl_load_file(aTHX_ NULL);",
6524             " SPAGAIN;",
6525             " handle = INT2PTR(void*,POPi);",
6526             " PUTBACK;",
6527             );
6528             }
6529 0         0 for my $mg (@{$init2_remap{$pkg}{MG}}) {
  0         0  
6530 0 0       0 warn "init2 remap xpvmg_list[$mg->{ID}].xiv_iv to dlsym of $pkg\: $mg->{NAME}\n"
6531             if $verbose;
6532 0 0       0 if ($HAVE_DLFCN_DLOPEN) {
6533             $init2->add(sprintf(" xpvmg_list[%d].xiv_iv = PTR2IV( dlsym(handle, %s) );",
6534 0         0 $mg->{ID}, cstring($mg->{NAME})));
6535             } else {
6536             $init2->add(" PUSHMARK(SP);",
6537             " XPUSHi(PTR2IV(handle));",
6538             sprintf(" XPUSHs(newSVpvs(%s));", cstring($mg->{NAME})),
6539             " PUTBACK;",
6540             " XS_DynaLoader_dl_find_symbol(aTHX_ NULL);",
6541             " SPAGAIN;",
6542 0         0 sprintf(" xpvmg_list[%d].xiv_iv = POPi;", $mg->{ID}),
6543             " PUTBACK;",
6544             );
6545             }
6546             }
6547             }
6548             }
6549 0         0 $init2->add("}");
6550 0         0 $init2->split;
6551             }
6552 0         0 $init2->output( \*STDOUT, "\t%s\n", $init2_name );
6553 0 0       0 if ($verbose) {
6554 0         0 my $caller = caller;
6555 0 0       0 warn $caller eq 'B::CC' ? B::CC::compile_stats() : compile_stats();
6556 0         0 warn "NULLOP count: $nullop_count\n";
6557             }
6558             }
6559              
6560             sub output_declarations {
6561 0     0 0 0 print <<'EOT';
6562             #define UNUSED 0
6563             #define sym_0 0
6564              
6565             static void
6566             my_mg_RC_off(pTHX_ SV* sv, int type) {
6567             MAGIC *mg;
6568             for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
6569             if (mg->mg_type == type && (mg->mg_flags | MGf_REFCOUNTED))
6570             mg->mg_flags &= ~MGf_REFCOUNTED;
6571             }
6572             }
6573              
6574             EOT
6575 0 0 0     0 if ($PERL510 and IS_MSVC) {
6576             # initializing char * differs in levels of indirection from int
6577 0         0 print "#pragma warning( disable : 4047 )\n";
6578             # targ: unreferenced local variable
6579 0         0 print "#pragma warning( disable : 4101 )\n";
6580             }
6581              
6582             # Need fresh re-hash of strtab. share_hek does not allow hash = 0
6583 0 0       0 if ( $PERL510 ) {
6584 0         0 print <<'_EOT0';
6585             PERL_STATIC_INLINE HEK *
6586             my_share_hek( pTHX_ const char *str, I32 len );
6587             #undef share_hek
6588             #define share_hek(str, len) my_share_hek( aTHX_ str, len );
6589              
6590             PERL_STATIC_INLINE HEK *
6591             my_share_hek_0( pTHX_ const char *str, I32 len);
6592              
6593             #define HEK_HE(hek) \
6594             ((struct shared_he *)(((char *)(hek)) \
6595             - STRUCT_OFFSET(struct shared_he, \
6596             shared_he_hek)))
6597             #define HEK_shared_he(hek) \
6598             ((struct shared_he *)(((char *)(hek)) \
6599             - STRUCT_OFFSET(struct shared_he, \
6600             shared_he_hek))) \
6601             ->shared_he_he
6602              
6603             #define hek_hek_refcount(hek) \
6604             HEK_shared_he(hek).he_valu.hent_refcount
6605              
6606             #define unshare_hek_hek(hek) --(hek_hek_refcount(hek))
6607              
6608             _EOT0
6609              
6610             }
6611 0 0       0 if ($PERL522) {
6612 0         0 print <<'EOF';
6613             /* unfortunately we have to override this perl5.22 struct.
6614             The Padname string buffer in xpadn_str is pointed by xpadn_pv.
6615             */
6616             #define _PADNAME_BASE \
6617             char * xpadn_pv; \
6618             HV * xpadn_ourstash; \
6619             union { \
6620             HV * xpadn_typestash; \
6621             CV * xpadn_protocv; \
6622             } xpadn_type_u; \
6623             U32 xpadn_low; \
6624             U32 xpadn_high; \
6625             U32 xpadn_refcnt; \
6626             int xpadn_gen; \
6627             U8 xpadn_len; \
6628             U8 xpadn_flags
6629              
6630             #ifdef PERL_PADNAME_MINIMAL
6631             #define MY_PADNAME_BASE _PADNAME_BASE
6632             #else
6633             #define MY_PADNAME_BASE struct padname xpadn_padname
6634             #endif
6635              
6636             EOF
6637              
6638 0         0 for my $s (sort keys %padnamesect) {
6639 0 0       0 if ($padnamesect{$s}->index >= 0) {
6640 0         0 print <<"EOF";
6641             struct my_padname_with_str_$s {
6642             MY_PADNAME_BASE;
6643             char xpadn_str[$s];
6644             };
6645             typedef struct my_padname_with_str_$s PADNAME_$s;
6646             EOF
6647             }
6648             }
6649             #} elsif ($PERL518) {
6650             # print "typedef PADNAME MyPADNAME;\n";
6651             }
6652 0 0 0     0 if ($PERL510 and !$PERL514) {
6653 0         0 print "typedef struct refcounted_he COPHH;\n";
6654 0         0 print <<'EOF';
6655             #define cophh_store_pvn(cophh, keypv, keylen, hash, value, flags) \
6656             Perl_refcounted_he_new(aTHX_ cophh, newSVpvn_flags(keypv, keylen, flags), value)
6657             #define cophh_store_pvs(cophh, key, value, flags) \
6658             Perl_refcounted_he_new(aTHX_ cophh, Perl_newSVpvn_flags(aTHX_ STR_WITH_LEN(key), SVs_TEMP), value)
6659             #define CopHINTHASH_set(c,h) ((c)->cop_hints_hash = (h))
6660             EOF
6661             }
6662 0 0       0 if ($B::C::Config::have_HEK_STATIC) {
6663 0         0 print "/* store full char[] to avoid excess elements in array\n";
6664 0         0 print " (HEK only declared as char[1]) */\n";
6665 0         0 print "struct hek_ptr { U32 hek_hash; I32 hek_len; char hek_key[]; };\n";
6666             }
6667             # Tricky hack for -fcog since 5.10 on !c99 compilers required. We need a char* as
6668             # *first* sv_u element to be able to statically initialize it. A int does not allow it.
6669             # gcc error: initializer element is not computable at load time
6670             # We introduce a SVPV as SV.
6671             # In core since 5.12
6672 0 0 0     0 if ($PERL510 and $] < 5.012 and !$C99) {
      0        
6673 0         0 print <<'EOT0';
6674             typedef struct svpv {
6675             void * sv_any;
6676             U32 sv_refcnt;
6677             U32 sv_flags;
6678             union {
6679             char* svu_pv;
6680             IV svu_iv;
6681             UV svu_uv;
6682             SV* svu_rv;
6683             SV** svu_array;
6684             HE** svu_hash;
6685             GP* svu_gp;
6686             } sv_u;
6687             #ifdef DEBUG_LEAKING_SCALARS
6688             PERL_BITFIELD32 sv_debug_optype:9;
6689             PERL_BITFIELD32 sv_debug_inpad:1;
6690             PERL_BITFIELD32 sv_debug_cloned:1;
6691             PERL_BITFIELD32 sv_debug_line:16;
6692             # if PERL_VERSION < 11
6693             U32 sv_debug_serial; /* 5.10 only */
6694             # endif
6695             # if PERL_VERSION > 8
6696             char * sv_debug_file;
6697             # endif
6698             #endif
6699             } SVPV;
6700             EOT0
6701              
6702             }
6703 0 0       0 if ($PERL512) {
    0          
6704 0         0 print "typedef struct p5rx RE;\n";
6705             }
6706             elsif ($PERL510) {
6707 0         0 print "typedef SV * RE;\n";
6708             }
6709             else {
6710 0         0 print "typedef char * RE;\n";
6711             }
6712 0 0       0 if ($] == 5.010000) {
6713 0         0 print "#ifndef RX_EXTFLAGS\n";
6714 0         0 print "# define RX_EXTFLAGS(rx) ((rx)->extflags)\n";
6715 0         0 print "#endif\n";
6716             }
6717 0 0 0     0 if ($] >= 5.021001 and !$CPERL52) {
6718 0         0 print "Static IV PL_sv_objcount = 0; /* deprecated with 5.21.1 but still needed and used */\n";
6719             }
6720 0         0 print "SV* sv;\n";
6721 0 0       0 print "Static GV *gv_list[$gv_index];\n" if $gv_index;
6722             }
6723              
6724             sub output_boilerplate {
6725 0     0 0 0 my $creator = "created at ".scalar localtime()." with B::C $B::C::VERSION ";
6726 0 0       0 $creator .= $B::C::REVISION if $B::C::REVISION;
6727 0         0 $creator .= " for $^X";
6728 0         0 print "/* $creator */\n";
6729             # Store the sv_list index in sv_debug_file when debugging
6730 0 0 0     0 print "#define DEBUG_LEAKING_SCALARS 1\n" if $debug{flags} and $DEBUG_LEAKING_SCALARS;
6731 0 0       0 if ($B::C::Config::have_independent_comalloc) {
6732 0         0 print <<'_EOT1';
6733             #ifdef NEED_MALLOC_283
6734             # include "malloc-2.8.3.h"
6735             #endif
6736             _EOT1
6737              
6738             }
6739 0         0 print <<'_EOT2';
6740             #define PERL_CORE
6741             #include "EXTERN.h"
6742             #include "perl.h"
6743             #include "XSUB.h"
6744              
6745             /* Workaround for mapstart: the only op which needs a different ppaddr */
6746             #undef Perl_pp_mapstart
6747             #define Perl_pp_mapstart Perl_pp_grepstart
6748             #undef OP_MAPSTART
6749             #define OP_MAPSTART OP_GREPSTART
6750              
6751             #ifdef BROKEN_STATIC_REDECL
6752             #define Static extern
6753             #else
6754             #define Static static
6755             #endif /* BROKEN_STATIC_REDECL */
6756              
6757             #ifdef BROKEN_UNION_INIT
6758             #error BROKEN_UNION_INIT no longer needed, as Perl requires an ANSI compiler
6759             #endif
6760              
6761             /* No longer available when C is defined. */
6762             #ifndef Nullsv
6763             # define Null(type) ((type)NULL)
6764             # define Nullsv Null(SV*)
6765             # define Nullhv Null(HV*)
6766             # define Nullgv Null(GV*)
6767             # define Nullop Null(OP*)
6768             #endif
6769             #ifndef GV_NOTQUAL
6770             # define GV_NOTQUAL 0
6771             #endif
6772             /* Since 5.8.8 */
6773             #ifndef Newx
6774             # define Newx(v,n,t) New(0,v,n,t)
6775             #endif
6776             /* Since 5.14 */
6777             #if !defined(PERL_STATIC_INLINE)
6778             # ifdef HAS_STATIC_INLINE
6779             # define PERL_STATIC_INLINE static inline
6780             # else
6781             # define PERL_STATIC_INLINE static
6782             # endif
6783             #endif
6784             /* cperl compat */
6785             #ifndef HEK_STATIC
6786             # define HEK_STATIC(hek) 0
6787             #endif
6788              
6789             _EOT2
6790              
6791 0 0       0 if ($] < 5.008008) {
6792 0         0 print "#define GvSVn(s) GvSV(s)\n";
6793             }
6794              
6795             # XXX boot_DynaLoader is exported only >=5.8.9
6796             # does not compile on darwin with EXTERN_C declaration
6797             # See branch `boot_DynaLoader`
6798 0         0 print <<'_EOT4';
6799              
6800             #define XS_DynaLoader_boot_DynaLoader boot_DynaLoader
6801             EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
6802              
6803             static void xs_init (pTHX);
6804             static void dl_init (pTHX);
6805             _EOT4
6806              
6807 0 0 0     0 print <<'_EOT' if $CPERL51 and $^O ne 'MSWin32';
6808             EXTERN_C void dl_boot (pTHX);
6809             _EOT
6810              
6811 0 0 0     0 if ($B::C::av_init2 and $B::C::Config::use_declare_independent_comalloc) {
6812 0         0 print "void** dlindependent_comalloc(size_t, size_t*, void**);\n";
6813             }
6814 0 0       0 if ($B::C::av_init2) {
6815 0         0 my $last = $xpvavsect->index;
6816 0         0 my $size = $last + 1;
6817 0 0       0 if ($last) {
6818 0         0 $decl->add("Static void* avchunks[$size];");
6819 0         0 $decl->add("Static size_t avsizes[$size] = ");
6820 0         0 my $ptrsize = $Config{ptrsize};
6821 0         0 my $acc = "";
6822 0         0 for (0..$last) {
6823 0 0       0 if ($xpvav_sizes[$_] > 0) {
6824 0         0 $acc .= $xpvav_sizes[$_] * $ptrsize;
6825             } else {
6826 0         0 $acc .= 3 * $ptrsize;
6827             }
6828 0 0       0 $acc .= "," if $_ != $last;
6829 0 0       0 $acc .= "\n\t" unless ($_+1) % 30;
6830             }
6831 0         0 $decl->add("\t{$acc};");
6832 0         0 $init->add_initav("if (!independent_comalloc( $size, avsizes, avchunks ))");
6833 0         0 $init->add_initav(" Perl_die(aTHX_ \"panic: AV alloc failed\");");
6834             }
6835             }
6836 0 0       0 if ( !$B::C::destruct ) {
6837 0         0 print <<'_EOT4';
6838             static int fast_perl_destruct( PerlInterpreter *my_perl );
6839             static void my_curse( pTHX_ SV* const sv );
6840              
6841             #ifndef dVAR
6842             # ifdef PERL_GLOBAL_STRUCT
6843             # define dVAR pVAR = (struct perl_vars*)PERL_GET_VARS()
6844             # else
6845             # define dVAR dNOOP
6846             # endif
6847             #endif
6848             _EOT4
6849              
6850             } else {
6851 0         0 print <<'_EOT5';
6852             int my_perl_destruct( PerlInterpreter *my_perl );
6853             _EOT5
6854              
6855             }
6856 0 0       0 if ($] < 5.008009) {
6857 0         0 print <<'_EOT3';
6858             #ifndef savesharedpvn
6859             char *savesharedpvn(const char *const s, const STRLEN len);
6860             #endif
6861             _EOT3
6862              
6863             }
6864             }
6865              
6866             sub init_op_addr {
6867 0     0 0 0 my ( $op_type, $num ) = @_;
6868 0         0 my $op_list = $op_type . "_list";
6869              
6870 0         0 $init0->add( split /\n/, <<_EOT6 );
6871             for (i = 0; i < ${num}; ++i) {
6872             ${op_list}\[i].op_ppaddr = PL_ppaddr[PTR2IV(${op_list}\[i].op_ppaddr)];
6873             }
6874             _EOT6
6875              
6876             }
6877              
6878             sub output_main_rest {
6879              
6880 0 0   0 0 0 if ( $PERL510 ) {
6881 0         0 print <<'_EOT7';
6882             /* The first assignment got already refcount bumped */
6883             PERL_STATIC_INLINE HEK *
6884             my_share_hek( pTHX_ const char *str, I32 len) {
6885             U32 hash;
6886             PERL_HASH(hash, str, abs(len));
6887             return share_hek_hek(Perl_share_hek(aTHX_ str, len, hash));
6888             }
6889              
6890             _EOT7
6891             }
6892 0 0       0 if ( $PERL510 ) {
6893 0         0 print <<'_EOT7';
6894             PERL_STATIC_INLINE HEK *
6895             my_share_hek_0( pTHX_ const char *str, I32 len) {
6896             U32 hash;
6897             PERL_HASH(hash, str, abs(len));
6898             return Perl_share_hek(aTHX_ str, len, hash);
6899             }
6900              
6901             _EOT7
6902             }
6903              
6904 0 0       0 if ($] < 5.008009) {
6905 0         0 print <<'_EOT7a';
6906             #ifndef savesharedpvn
6907             char *savesharedpvn(const char *const s, const STRLEN len) {
6908             char *const d = (char*)PerlMemShared_malloc(len + 1);
6909             if (!d) { exit(1); }
6910             d[len] = '\0';
6911             return (char *)memcpy(d, s, len);
6912             }
6913             #endif
6914             _EOT7a
6915              
6916             }
6917             # -fno-destruct only >=5.8
6918 0 0       0 if ( !$B::C::destruct ) {
6919 0         0 print <<'_EOT8';
6920              
6921             #ifndef SvDESTROYABLE
6922             #define SvDESTROYABLE(sv) 1
6923             #endif
6924             /* 5.8 */
6925             #ifndef CvISXSUB
6926             #define CvISXSUB(sv) CvXSUB(sv)
6927             #endif
6928             #ifndef SvRV_set
6929             #define SvRV_set(a,b) SvRV(a) = (b)
6930             #endif
6931             /* 5.6 */
6932             #ifndef PERL_EXIT_DESTRUCT_END
6933             #define PERL_EXIT_DESTRUCT_END 2
6934             #endif
6935              
6936             static void
6937             my_curse( pTHX_ SV* const sv ) {
6938             dSP;
6939             dVAR;
6940             HV* stash;
6941              
6942             #if PERL_VERSION > 7
6943             assert(SvOBJECT(sv));
6944             do {
6945             stash = SvSTASH(sv);
6946             assert(SvTYPE(stash) == SVt_PVHV);
6947             if (HvNAME(stash)) {
6948             CV* destructor = NULL;
6949             if (!SvOBJECT(stash)) destructor = (CV *)SvSTASH(stash);
6950             if (!destructor
6951             #if (PERL_VERSION > 18) || (PERL_VERSION == 18 && PERL_SUBVERSION > 1)
6952             || HvMROMETA(stash)->destroy_gen != PL_sub_generation
6953             #endif
6954             ) {
6955             GV * const gv = gv_fetchmeth_autoload(stash, "DESTROY", 7, 0);
6956             if (gv) {
6957             destructor = GvCV(gv);
6958             if (!SvOBJECT(stash)) {
6959             SvSTASH(stash) =
6960             destructor ? (HV *)destructor : ((HV *)0)+1;
6961             #if (PERL_VERSION > 18) || (PERL_VERSION == 18 && PERL_SUBVERSION > 1)
6962             HvAUX(stash)->xhv_mro_meta->destroy_gen = PL_sub_generation;
6963             #endif
6964             }
6965             }
6966             }
6967             assert(!destructor || destructor == ((CV *)0)+1
6968             || SvTYPE(destructor) == SVt_PVCV);
6969             if (destructor && destructor != ((CV *)0)+1
6970             /* A constant subroutine can have no side effects, so
6971             don't bother calling it. */
6972             && !CvCONST(destructor)
6973             /* Don't bother calling an empty destructor or one that
6974             returns immediately. */
6975             && (CvISXSUB(destructor)
6976             || (CvSTART(destructor)
6977             && (CvSTART(destructor)->op_next->op_type != OP_LEAVESUB)
6978             && (CvSTART(destructor)->op_next->op_type != OP_PUSHMARK
6979             || CvSTART(destructor)->op_next->op_next->op_type != OP_RETURN
6980             )
6981             ))
6982             )
6983             {
6984             SV* const tmpref = newRV(sv);
6985             DEBUG_D(PerlIO_printf(Perl_debug_log, "Calling %s::DESTROY\n", HvNAME(stash)));
6986             SvREADONLY_on(tmpref); /* DESTROY() could be naughty */
6987             ENTER;
6988             PUSHSTACKi(PERLSI_DESTROY);
6989             EXTEND(SP, 2);
6990             PUSHMARK(SP);
6991             PUSHs(tmpref);
6992             PUTBACK;
6993             call_sv((SV*)destructor, G_DISCARD|G_EVAL|G_KEEPERR|G_VOID);
6994             POPSTACK;
6995             SPAGAIN;
6996             LEAVE;
6997             if(SvREFCNT(tmpref) < 2) {
6998             /* tmpref is not kept alive! */
6999             SvREFCNT(sv)--;
7000             SvRV_set(tmpref, NULL);
7001             SvROK_off(tmpref);
7002             }
7003             SvREFCNT_dec(tmpref);
7004             }
7005             }
7006             } while (SvOBJECT(sv) && SvSTASH(sv) != stash);
7007              
7008             if (SvOBJECT(sv)) {
7009             /* Curse before freeing the stash, as freeing the stash could cause
7010             a recursive call into S_curse. */
7011             SvOBJECT_off(sv); /* Curse the object. */
7012             SvSTASH_set(sv,0); /* SvREFCNT_dec may try to read this */
7013             }
7014             #endif
7015             }
7016              
7017             static int fast_perl_destruct( PerlInterpreter *my_perl ) {
7018             dVAR;
7019             VOL signed char destruct_level; /* see possible values in intrpvar.h */
7020             HV *hv;
7021             #ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
7022             pid_t child;
7023             #endif
7024              
7025             #ifndef MULTIPLICITY
7026             # ifndef PERL_UNUSED_ARG
7027             # define PERL_UNUSED_ARG(x) ((void)x)
7028             # endif
7029             PERL_UNUSED_ARG(my_perl);
7030             #endif
7031              
7032             assert(PL_scopestack_ix == 1);
7033              
7034             /* wait for all pseudo-forked children to finish */
7035             #if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7036             PERL_WAIT_FOR_CHILDREN;
7037             #endif
7038              
7039             destruct_level = PL_perl_destruct_level;
7040             #ifdef DEBUGGING
7041             {
7042             const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
7043             if (s) {
7044             const int i = atoi(s);
7045             #ifdef DEBUGGING
7046             if (destruct_level < i) destruct_level = i;
7047             #endif
7048             #ifdef PERL_TRACK_MEMPOOL
7049             /* RT #114496, for perl_free */
7050             PL_perl_destruct_level = i;
7051             #endif
7052             }
7053             }
7054             #endif
7055              
7056             if (PL_exit_flags & PERL_EXIT_DESTRUCT_END) {
7057             dJMPENV;
7058             int x = 0;
7059              
7060             JMPENV_PUSH(x);
7061             if (PL_endav && !PL_minus_c) {
7062             #if PERL_VERSION > 13
7063             PL_phase = PERL_PHASE_END;
7064             #endif
7065             call_list(PL_scopestack_ix, PL_endav);
7066             }
7067             JMPENV_POP;
7068             }
7069             _EOT8
7070              
7071 0         0 for (0 .. $#B::C::static_free) {
7072             # set static op members to NULL
7073 0         0 my $s = $B::C::static_free[$_];
7074 0 0       0 if ($s =~ /\(OP\*\)&unopaux_list/) {
7075 0         0 print " ($s)->op_type = OP_NULL;\n";
7076             }
7077             }
7078              
7079 0         0 print <<'_EOT9';
7080             LEAVE;
7081             FREETMPS;
7082             assert(PL_scopestack_ix == 0);
7083              
7084             /* Need to flush since END blocks can produce output */
7085             my_fflush_all();
7086              
7087             PL_main_start = NULL;
7088             PL_main_cv = NULL;
7089             PL_curcop = &PL_compiling;
7090             #if PERL_VERSION >= 13
7091             PL_phase = PERL_PHASE_DESTRUCT;
7092             #endif
7093              
7094             #if PERL_VERSION > 7
7095             if (PL_threadhook(aTHX)) {
7096             /* Threads hook has vetoed further cleanup */
7097             #if (PERL_VERSION > 8) || ((PERL_VERSION == 8) && (PERL_SUBVERSION > 8))
7098             PL_veto_cleanup = TRUE;
7099             return STATUS_EXIT;
7100             #else
7101             return STATUS_NATIVE_EXPORT;
7102             #endif
7103             }
7104             #if defined(PERLIO_LAYERS)
7105             # if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7106             PerlIO_destruct(aTHX);
7107             # endif
7108             #endif
7109              
7110             /* B::C -O3 specific: first curse (i.e. call DESTROY) all our static SVs */
7111             if (PL_sv_objcount) {
7112             int i = 1;
7113             DEBUG_D(PerlIO_printf(Perl_debug_log, "\nCursing named global static sv_arena:\n"));
7114             PL_in_clean_all = 1;
7115             for (; i < SvREFCNT(&sv_list[0]); i++) {
7116             SV *sv = &sv_list[i];
7117             if (SvREFCNT(sv)) {
7118             #if PERL_VERSION > 11
7119             if (SvTYPE(sv) == SVt_IV && SvROK(sv))
7120             #else
7121             if (SvTYPE(sv) == SVt_RV)
7122             #endif
7123             sv = SvRV(sv);
7124             if (sv && SvOBJECT(sv) && SvTYPE(sv) >= SVt_PVMG && SvSTASH(sv)
7125             && SvTYPE(sv) != SVt_PVCV && SvTYPE(sv) != SVt_PVIO
7126             && PL_defstash /* Still have a symbol table? */
7127             && SvDESTROYABLE(sv))
7128             {
7129             SvREFCNT(sv) = 0;
7130             my_curse(aTHX_ sv);
7131             }
7132             }
7133             }
7134             }
7135             if (DEBUG_D_TEST) {
7136             SV* sva;
7137             PerlIO_printf(Perl_debug_log, "\n");
7138             for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) {
7139             PerlIO_printf(Perl_debug_log, "sv_arena: 0x%p - 0x%p (%lu)\n",
7140             sva, sva+SvREFCNT(sva), (long)SvREFCNT(sva));
7141             }
7142             }
7143             #endif
7144              
7145             #if PERL_VERSION > 7
7146             PL_stashcache = (HV*)&PL_sv_undef; /* sometimes corrupted */
7147             #endif
7148             #if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7149             if (PL_sv_objcount) {
7150             # if PERL_VERSION > 7
7151             PL_stashcache = newHV(); /* Hack: sometimes corrupted, holding a GV */
7152             # endif
7153             PL_in_clean_all = 1;
7154             sv_clean_objs(); /* and now curse the rest */
7155             PL_sv_objcount = 0;
7156             }
7157             #endif
7158              
7159             PL_warnhook = NULL;
7160             PL_diehook = NULL;
7161             /* call exit list functions */
7162             while (PL_exitlistlen-- > 0)
7163             PL_exitlist[PL_exitlistlen].fn(aTHX_ PL_exitlist[PL_exitlistlen].ptr);
7164             PL_exitlist = NULL;
7165              
7166             #if defined(PERLIO_LAYERS)
7167             # if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7168             PerlIO_cleanup(aTHX);
7169             # endif
7170             #endif
7171              
7172             #if PERL_VERSION > 7
7173             PL_stashcache = (HV*)&PL_sv_undef;
7174             #endif
7175             /* Silence strtab refcnt warnings during global destruction */
7176             Zero(HvARRAY(PL_strtab), HvMAX(PL_strtab), HE*);
7177             /* NULL the HEK "dfs" */
7178             #if PERL_VERSION > 10
7179             PL_registered_mros = (HV*)&PL_sv_undef;
7180             CopHINTHASH_set(&PL_compiling, NULL);
7181             #endif
7182              
7183             return 0;
7184             }
7185             _EOT9
7186              
7187             }
7188             # special COW handling for 5.10 because of S_unshare_hek_or_pvn limitations
7189             # XXX This fails in S_doeval SAVEFREEOP(PL_eval_root): test 15
7190             # if ( $PERL510 and (@B::C::static_free or $free->index > -1))
7191             else {
7192 0         0 print <<'_EOT7';
7193             int my_perl_destruct( PerlInterpreter *my_perl ) {
7194             VOL signed char destruct_level = PL_perl_destruct_level;
7195             const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
7196              
7197             /* set all our static pv and hek to &PL_sv_undef for perl_destruct() */
7198             _EOT7
7199              
7200             #for (0 .. $hek_index-1) {
7201             # # TODO: non-static only, seperate data structures please
7202             # printf " memset(HEK_HE(hek%d), 0, sizeof(struct shared_he));\n", $_;
7203             #}
7204 0         0 for (0 .. $#B::C::static_free) {
7205             # set the sv/xpv to &PL_sv_undef, not the pv itself.
7206             # If set to NULL pad_undef will fail in SvPVX_const(namesv) == '&'
7207             # XXX Another idea >5.10 is SvFLAGS(pv) = SVTYPEMASK
7208 0         0 my $s = $B::C::static_free[$_];
7209 0 0       0 if ($s =~ /^sv_list\[\d+\]\./) { # pv directly (unused)
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
7210 0         0 print " $s = NULL;\n";
7211             } elsif ($s =~ /^sv_list/) {
7212 0         0 print " SvLEN(&$s) = 0;\n";
7213 0         0 print " SvPV_set(&$s, (char*)&PL_sv_undef);\n";
7214             } elsif ($s =~ /^&sv_list/) {
7215 0         0 print " SvLEN($s) = 0;\n";
7216 0         0 print " SvPV_set($s, (char*)&PL_sv_undef);\n";
7217             } elsif ($s =~ /^\(HV\*\)&sv_list/) {
7218 0         0 print " SvREADONLY_on((SV*)$s);\n";
7219 0         0 print " SvREFCNT($s) = SvREFCNT_IMMORTAL;\n";
7220             } elsif ($s =~ /^\(AV\*\)&sv_list/) { # SVs_OBJECT flag, as the HV
7221             #print " SvREADONLY_on((SV*)$s);\n";
7222             #print " SvREFCNT($s) = SvREFCNT_IMMORTAL;\n";
7223             } elsif ($s =~ /^&padnamelist_list/) {
7224 0         0 print " Safefree(PadnamelistARRAY($s));\n";
7225 0         0 print " PadnamelistMAX($s) = 0;\n";
7226 0         0 print " PadnamelistREFCNT($s) = 0;\n";
7227             } elsif ($s =~ /^&padname(_\d+)?_list/) {
7228 0         0 print " PadnameREFCNT($s) = 0;\n";
7229             # dead code ---
7230             } elsif ($s =~ /^cop_list/) {
7231 0 0 0     0 if ($ITHREADS or !$MULTI) {
7232 0         0 print " CopFILE_set(&$s, NULL);";
7233             }
7234 0 0 0     0 if ($] >= 5.017) {
    0 0        
    0          
7235 0         0 print " CopSTASH_set(&$s, NULL);\n";
7236             } elsif ($] < 5.016 and $ITHREADS) {
7237 0         0 print " CopSTASHPV(&$s) = NULL;\n";
7238             } elsif ($] < 5.016 and !$ITHREADS) {
7239 0         0 print " CopSTASH(&$s) = NULL;\n";
7240             } else { # 5.16 experiment
7241 0         0 print " CopSTASHPV_set(&$s, NULL, 0);\n";
7242             }
7243             } elsif ($s =~ /\(OP\*\)&unopaux_list/) {
7244 0         0 print " ($s)->op_type = OP_NULL;\n";
7245             # end dead code ---
7246             #} elsif ($s =~ /^pv\d/) {
7247             # print " $s = \"\";\n";
7248             } elsif ($s ne 'ptr_undef') {
7249 0         0 warn("unknown $s at \@static_free[$_]");
7250             }
7251             }
7252 0         0 $free->output( \*STDOUT, "%s\n" );
7253              
7254 0         0 my $riter_type = "I32";
7255 0 0       0 if ($CPERL51) {
7256 0 0       0 $riter_type = $CPERL55 ? "U32" : "SSize_t";
7257             }
7258 0         0 my $hvmax_type = "STRLEN";
7259 0 0       0 if ($CPERL51) {
7260 0 0       0 $hvmax_type = $CPERL55 ? "U32" : "SSize_t";
7261             }
7262 0         0 print "#define RITER_T $riter_type\n";
7263 0         0 print "#define HVMAX_T $hvmax_type\n";
7264              
7265 0         0 print <<'_EOT7a';
7266              
7267             /* Avoid Unbalanced string table refcount warning with PERL_DESTRUCT_LEVEL=2 */
7268             if (s) {
7269             const int i = atoi(s);
7270             if (destruct_level < i) destruct_level = i;
7271             }
7272             if (destruct_level >= 1) {
7273             const HVMAX_T max = HvMAX(PL_strtab);
7274             HE * const * const array = HvARRAY(PL_strtab);
7275             RITER_T riter = 0;
7276             HE *hent = array[0];
7277             for (;;) {
7278             if (hent) {
7279             HE * const next = HeNEXT(hent);
7280             if (!HEK_STATIC(&((struct shared_he*)hent)->shared_he_hek))
7281             Safefree(hent);
7282             hent = next;
7283             }
7284             if (!hent) {
7285             if (++riter > max)
7286             break;
7287             hent = array[riter];
7288             }
7289             }
7290             /* Silence strtab refcnt warnings during global destruction */
7291             Zero(HvARRAY(PL_strtab), max, HE*);
7292             /* NULL the HEK "dfs" */
7293             #if PERL_VERSION > 10
7294             PL_registered_mros = (HV*)&PL_sv_undef;
7295             CopHINTHASH_set(&PL_compiling, NULL);
7296             #endif
7297             }
7298              
7299             /* B::C specific: prepend static svs to arena for sv_clean_objs */
7300             SvANY(&sv_list[0]) = (void *)PL_sv_arenaroot;
7301             PL_sv_arenaroot = &sv_list[0];
7302             #if PERL_VERSION > 7
7303             if (DEBUG_D_TEST) {
7304             SV* sva;
7305             PerlIO_printf(Perl_debug_log, "\n");
7306             for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) {
7307             PerlIO_printf(Perl_debug_log, "sv_arena: 0x%p - 0x%p (%lu)\n",
7308             sva, sva+SvREFCNT(sva), (long)SvREFCNT(sva));
7309             }
7310             }
7311              
7312             return perl_destruct( my_perl );
7313             #else
7314             perl_destruct( my_perl );
7315             return 0;
7316             #endif
7317             }
7318             _EOT7a
7319             }
7320              
7321 0         0 print <<'_EOT8';
7322              
7323             /* yanked from perl.c */
7324             static void
7325             xs_init(pTHX)
7326             {
7327             char *file = __FILE__;
7328             dTARG; dSP; CV * cv;
7329             _EOT8
7330 0 0 0     0 if ($CPERL51 and $debug{cv}) {
7331 0         0 print q{
7332             /* -DC set dl_debug to 3 */
7333             SV* sv = get_svs("DynaLoader::dl_debug", GV_ADD);
7334             sv_upgrade(sv, SVt_IV);
7335             SvIV_set(sv, 3);};
7336             }
7337             #if ($staticxs) { #FIXME!
7338             # print "\n#undef USE_DYNAMIC_LOADING
7339             #}
7340              
7341 0         0 delete $xsub{'DynaLoader'};
7342 0         0 delete $xsub{'UNIVERSAL'};
7343 0         0 print("/* XS bootstrapping code*/\n");
7344 0         0 print("\tSAVETMPS;\n");
7345 0         0 print("\ttarg=sv_newmortal();\n");
7346 0         0 foreach my $stashname ( sort keys %static_ext ) {
7347 0         0 my $stashxsub = $stashname;
7348 0         0 $stashxsub =~ s/::/__/g;
7349             #if ($stashxsub =~ m/\/(\w+)\.\w+$/ {$stashxsub = $1;}
7350             # cygwin has Win32CORE in static_ext
7351 0 0       0 warn "bootstrapping static $stashname added to xs_init\n" if $verbose;
7352 0         0 print "\tnewXS(\"$stashname\::bootstrap\", boot_$stashxsub, file);\n";
7353             }
7354 0         0 print "#ifdef USE_DYNAMIC_LOADING\n";
7355 0         0 print "\tPUSHMARK(sp);\n";
7356 0         0 printf "\tXPUSHp(\"DynaLoader\", %d);\n", length("DynaLoader");
7357 0         0 print "\tPUTBACK;\n";
7358 0 0       0 warn "bootstrapping DynaLoader added to xs_init\n" if $verbose;
7359 0         0 print "\tcv = newXS(\"DynaLoader::boot_DynaLoader\", boot_DynaLoader, file);\n";
7360 0         0 print "\tboot_DynaLoader(aTHX_ cv);\n";
7361 0         0 print "\tSPAGAIN;\n";
7362 0 0 0     0 if ($CPERL51 and $^O ne 'MSWin32') {
7363 0         0 print "\tdl_boot(aTHX);\n";
7364             }
7365 0         0 print "#endif\n";
7366              
7367             # my %core = map{$_ => 1} core_packages();
7368 0         0 foreach my $stashname ( sort keys %xsub ) {
7369 0         0 my $incpack = inc_packname($stashname);
7370 0 0       0 unless (exists $curINC{$incpack}) { # skip deleted packages
7371 0 0       0 warn "skip xs_init for $stashname !\$INC{$incpack}\n" if $debug{pkg};
7372 0         0 delete $include_package{$stashname};
7373 0 0       0 delete $xsub{$stashname} unless $static_ext{$stashname};
7374 0         0 next;
7375             }
7376 0 0 0     0 if ( $xsub{$stashname} !~ m/^Dynamic/ and !$static_ext{$stashname}) {
7377 0         0 my $stashxsub = $stashname;
7378 0 0       0 warn "bootstrapping $stashname added to xs_init\n" if $verbose;
7379 0         0 $stashxsub =~ s/::/__/g;
7380 0         0 print "\tPUSHMARK(sp);\n";
7381 0         0 printf "\tXPUSHp(\"%s\", %d);\n", # "::bootstrap" gets appended, TODO
7382             0 ? "strdup($stashname)" : $stashname, length($stashname);
7383 0         0 print "\tPUTBACK;\n";
7384 0         0 print "\tboot_$stashxsub(aTHX_ NULL);\n";
7385 0         0 print "\tSPAGAIN;\n";
7386             }
7387             }
7388 0         0 print "\tFREETMPS;\n/* end XS bootstrapping code */\n";
7389 0         0 print "}\n\n";
7390              
7391 0         0 my ($dl, $xs);
7392 0         0 my @dl_modules = @DynaLoader::dl_modules;
7393 0 0       0 my @PERLMODS = split(/\,/, $ENV{'PERLMODS'}) if $ENV{'PERLMODS'}; # from cpanel
7394 0         0 foreach my $perlmod (@PERLMODS) {
7395 0         0 warn "Extra module ${perlmod}\n";
7396 0 0       0 push @dl_modules, $perlmod unless grep { $_ ne $perlmod } @dl_modules;
  0         0  
7397             }
7398             # filter out unused dynaloaded B modules, used within the compiler only.
7399 0         0 for my $c (qw(B B::C)) {
7400 0 0 0     0 if (!$xsub{$c} and !$include_package{$c}) {
7401             # (hopefully, see test 103)
7402 0 0 0     0 warn "no dl_init for $c, not marked\n" if $verbose and !$skip_package{$c};
7403             # RT81332 pollute
7404 0         0 @dl_modules = grep { $_ ne $c } @dl_modules;
  0         0  
7405             # XXX Be sure to store the new @dl_modules
7406             }
7407             }
7408 0         0 for my $c (sort keys %skip_package) {
7409 0 0 0     0 warn "no dl_init for $c, skipped\n" if $verbose and $xsub{$c};
7410 0         0 delete $xsub{$c};
7411 0         0 $include_package{$c} = undef;
7412 0         0 @dl_modules = grep { $_ ne $c } @dl_modules;
  0         0  
7413             }
7414 0         0 @DynaLoader::dl_modules = @dl_modules;
7415 0 0       0 warn "\@dl_modules: ",join(" ",@dl_modules),"\n" if $verbose;
7416 0         0 foreach my $stashname (@dl_modules) {
7417 0         0 my $incpack = inc_packname($stashname);
7418             #unless (exists $INC{$incpack}) { # skip deleted packages
7419             # warn "XXX skip dl_init for $stashname !\$INC{$incpack}\n" if $debug{pkg};
7420             # delete $xsub{$stashname};
7421             # @dl_modules = grep { $_ ne $stashname } @dl_modules;
7422             #}
7423 0 0 0     0 if ($stashname eq 'attributes' and $] > 5.011) {
7424 0         0 $xsub{$stashname} = 'Dynamic-' . $INC{'attributes.pm'};
7425             }
7426             # actually boot all non-b-c dependent modules here. we assume XSLoader (Moose, List::MoreUtils)
7427 0 0 0     0 if (!exists( $xsub{$stashname} ) and $include_package{$stashname}) {
7428 0         0 $xsub{$stashname} = 'Dynamic-' . $INC{$incpack};
7429             # Class::MOP without Moose: find Moose.pm
7430 0 0       0 $xsub{$stashname} = 'Dynamic-' . $savINC{$incpack} unless $INC{$incpack};
7431 0 0       0 if (!$savINC{$incpack}) {
7432 0         0 eval "require $stashname;";
7433 0         0 $xsub{$stashname} = 'Dynamic-' . $INC{$incpack};
7434             }
7435 0 0       0 warn "Assuming xs loaded $stashname with $xsub{$stashname}\n" if $verbose;
7436             }
7437 0 0 0     0 if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic/ ) {
7438             # XSLoader.pm: $modlibname = (caller())[1]; needs a path at caller[1] to find auto,
7439             # otherwise we only have -e
7440 0 0       0 $xs++ if $xsub{$stashname} ne 'Dynamic';
7441 0         0 $dl++;
7442             }
7443 0         0 my $stashxsub = $stashname;
7444 0         0 $stashxsub =~ s/::/__/g;
7445 0 0 0     0 if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic-/
      0        
      0        
7446             and ($PERL522 or $staticxs)) {
7447 0         0 print "EXTERN_C void boot_$stashxsub(pTHX_ CV* cv);\n";
7448             }
7449             }
7450 0 0 0     0 warn "\%xsub: ",join(" ",sort keys %xsub),"\n" if $verbose and $debug{cv};
7451             # XXX Adding DynaLoader is too late here! The sections like $init are already dumped (#125)
7452 0 0 0     0 if ($dl and ! $curINC{'DynaLoader.pm'}) {
    0 0        
7453 0         0 die "Error: DynaLoader required but not dumped. Too late to add it.\n";
7454             } elsif ($xs and ! $curINC{'XSLoader.pm'}) {
7455 0         0 die "Error: XSLoader required but not dumped. Too late to add it.\n";
7456             }
7457 0         0 print <<'_EOT9';
7458              
7459             static void
7460             dl_init(pTHX)
7461             {
7462             char *file = __FILE__;
7463             _EOT9
7464              
7465 0 0       0 if ($dl) {
7466             # enforce attributes at the front of dl_init, #259
7467             # also Encode should be booted before PerlIO::encoding
7468 0         0 for my $front (qw(Encode attributes)) {
7469 0 0       0 if (grep { $_ eq $front } @dl_modules) {
  0         0  
7470 0         0 @dl_modules = grep { $_ ne $front } @dl_modules;
  0         0  
7471 0         0 unshift @dl_modules, $front;
7472             }
7473             }
7474 0 0       0 if ($staticxs) {open( XS, ">", $outfile.".lst" ) or return "$outfile.lst: $!\n"}
  0 0       0  
7475 0         0 print "\tdTARG; dSP;\n";
7476 0         0 print "/* DynaLoader bootstrapping */\n";
7477 0         0 print "\tENTER;\n";
7478 0 0       0 print "\t++cxstack_ix; cxstack[cxstack_ix].blk_oldcop = PL_curcop;\n" if $xs;
7479 0 0       0 print "\t/* assert(cxstack_ix == 0); */\n" if $xs;
7480 0         0 print "\tSAVETMPS;\n";
7481 0 0       0 print "\ttarg = sv_newmortal();\n" if $] < 5.008008;
7482              
7483 0 0 0     0 if (exists $xsub{"Coro::State"} and grep { $_ eq "Coro::State" } @dl_modules) {
  0         0  
7484             # Coro readonly symbols in BOOT (#293)
7485             # needed before dl_init, and after init
7486 0         0 print "\t{\n\t GV *sym;\n";
7487 0         0 for my $s (qw(Coro Coro::API Coro::current)) {
7488 0         0 print "\t sym = gv_fetchpv(\"$s\",0,SVt_PV);\n";
7489 0         0 print "\t if (sym && GvSVn(sym)) SvREADONLY_off(GvSVn(sym));\n";
7490             }
7491 0         0 print "\t sym = gv_fetchpv(\"Coro::pool_handler)\",0,SVt_PVCV);\n";
7492 0         0 print "\t if (sym && GvCV(sym)) SvREADONLY_off(GvCV(sym));\n";
7493 0         0 print "\t}\n";
7494             }
7495 0 0 0     0 if (exists $xsub{"EV"} and grep { $_ eq "EV" } @dl_modules) {
  0         0  
7496             # EV readonly symbols in BOOT (#368)
7497 0         0 print "\t{\n\t GV *sym;\n";
7498 0         0 for my $s (qw(EV::API)) {
7499 0         0 print "\t sym = gv_fetchpv(\"$s\",0,SVt_PV);\n";
7500 0         0 print "\t if (sym && GvSVn(sym)) SvREADONLY_off(GvSVn(sym));\n";
7501             }
7502 0         0 print "\t}\n";
7503             }
7504 0         0 foreach my $stashname (@dl_modules) {
7505 0 0 0     0 if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic/ ) {
7506 0         0 $use_xsloader = 1;
7507 0         0 print "\n\tPUSHMARK(sp);\n";
7508             # XXX -O1 or -O2 needs XPUSHs with dynamic pv
7509 0 0       0 printf "\t%s(%s, %d);\n", # "::bootstrap" gets appended
7510             $] < 5.008008 ? "XPUSHp" : "mXPUSHp", "\"$stashname\"", length($stashname);
7511 0 0       0 if ( $xsub{$stashname} eq 'Dynamic' ) {
7512 55     55   402 no strict 'refs';
  55         82  
  55         19978  
7513 0 0       0 warn "dl_init $stashname\n" if $verbose;
7514             # just in case we missed it. DynaLoader really needs the @ISA (#308)
7515 0         0 B::svref_2object( \@{$stashname."::ISA"} ) ->save;
  0         0  
7516 0         0 print "#ifndef STATICXS\n";
7517 0         0 print "\tPUTBACK;\n";
7518 0         0 print qq/\tcall_method("DynaLoader::bootstrap_inherit", G_VOID|G_DISCARD);\n/;
7519             }
7520             else { # XS: need to fix cx for caller[1] to find auto/...
7521 0         0 my ($stashfile) = $xsub{$stashname} =~ /^Dynamic-(.+)$/;
7522 0         0 print "#ifndef STATICXS\n";
7523 0 0 0     0 if ($] >= 5.015003 and $stashfile) {
7524 0 0       0 if ($CPERL51) {
7525 0         0 my $sofile;
7526             # search stashname in loaded sofiles
7527 0         0 my @modparts = split(/::/,$stashname);
7528 0         0 my $modfname = $modparts[-1];
7529 0         0 my $modpname = join('/',@modparts);
7530 0         0 my $needle = "auto/$modpname/$modfname\\.".$Config{dlext};
7531             #warn " load_file: @DynaLoader::dl_shared_objects";
7532             #warn " sofile?: $needle";
7533 0         0 for (@DynaLoader::dl_shared_objects) {
7534 0 0       0 if (m{$needle}) {
7535             #warn " load_file: found $_";
7536 0         0 $sofile = $_; last;
  0         0  
7537             }
7538             }
7539 0 0       0 unless ($sofile) {
7540 0         0 my $modlibname = $stashfile;
7541 0         0 my $c = scalar @modparts;
7542 0 0 0     0 if ($stashname eq 'Cwd' and $stashfile !~ /Cwd/) {
7543 0         0 warn "load_file: fixup Cwd vs $stashfile";
7544 0         0 $c = 3;
7545             }
7546 0         0 $modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename
7547 0         0 $sofile = "$modlibname/auto/$modpname/$modfname.".$Config{dlext};
7548             }
7549             #warn "load_file: $stashname, $stashfile, $sofile";
7550 0         0 $stashfile = $sofile;
7551             }
7552 0         0 my $stashfile_len = length($stashfile);
7553 0         0 $stashfile =~ s/(\\[^nrftacx"' ])/\\$1/g; # windows paths: \\ => \\\\
7554 0         0 printf "\tmXPUSHp(\"%s\", %d);\n", $stashfile, $stashfile_len;
7555             }
7556 0         0 print "\tPUTBACK;\n";
7557 0 0       0 warn "bootstrapping $stashname added to XSLoader dl_init\n" if $verbose;
7558             # XSLoader has the 2nd insanest API in whole Perl, right after make_warnings_object()
7559             # 5.15.3 workaround for [perl #101336]
7560 0 0       0 if ($] >= 5.015003) {
7561 55     55   245 no strict 'refs';
  55         70  
  55         63883  
7562 0 0       0 unless (grep /^DynaLoader$/, get_isa($stashname)) {
7563 0         0 push @{$stashname."::ISA"}, 'DynaLoader';
  0         0  
7564 0         0 svref_2object( \@{$stashname."::ISA"} ) ->save;
  0         0  
7565             }
7566 0 0       0 warn '@',$stashname,"::ISA=(",join(",",@{$stashname."::ISA"}),")\n" if $debug{gv};
  0         0  
7567             # TODO #364: if a VERSION was provided need to add it here
7568 0         0 print qq/\tcall_pv("XSLoader::load_file", G_VOID|G_DISCARD);\n/;
7569             } else {
7570 0 0       0 printf qq/\tCopFILE_set(cxstack[cxstack_ix].blk_oldcop, "%s");\n/,
7571             $stashfile if $stashfile;
7572             # TODO #364: if a VERSION was provided need to add it here
7573 0         0 print qq/\tcall_pv("XSLoader::load", G_VOID|G_DISCARD);\n/;
7574             }
7575             }
7576 0 0       0 if ($staticxs) {
7577 0         0 my ($laststash) = $stashname =~ /::([^:]+)$/;
7578 0         0 my $path = $stashname;
7579 0         0 $path =~ s/::/\//g;
7580 0 0       0 $path .= "/" if $path; # can be empty
7581 0 0       0 $laststash = $stashname unless $laststash; # without ::
7582 0         0 my $sofile = "auto/" . $path . $laststash . '\.' . $Config{dlext};
7583             #warn "staticxs search $sofile in @DynaLoader::dl_shared_objects\n"
7584             # if $verbose and $debug{pkg};
7585 0         0 for (@DynaLoader::dl_shared_objects) {
7586 0 0       0 if (m{^(.+/)$sofile$}) {
7587 0         0 print XS $stashname,"\t",$_,"\n";
7588 0 0       0 warn "staticxs $stashname\t$_\n" if $verbose;
7589 0         0 $sofile = '';
7590 0         0 last;
7591             }
7592             }
7593 0 0       0 print XS $stashname,"\n" if $sofile; # error case
7594 0 0 0     0 warn "staticxs $stashname\t - $sofile not loaded\n" if $sofile and $verbose;
7595             }
7596 0         0 print "#else\n";
7597 0         0 print "\tPUTBACK;\n";
7598 0         0 my $stashxsub = $stashname;
7599 0         0 $stashxsub =~ s/::/__/g;
7600 0 0 0     0 if ($PERL522 or $staticxs) {
7601             # CvSTASH(CvGV(cv)) is invalid without (issue 86)
7602             # TODO: utf8 stashname (does make sense when loading from the fs?)
7603 0 0 0     0 if ($PERL522 and $staticxs) { # GH 333
7604 0         0 print "\t{
7605             CV* cv = (CV*)SvREFCNT_inc_simple_NN(get_cv(\"$stashname\::bootstrap\", GV_ADD));
7606             CvISXSUB_on(cv); /* otherwise a perl assertion fails. */
7607             cv->sv_any->xcv_padlist_u.xcv_hscxt = &PL_stack_sp; /* xs_handshake */
7608             boot_$stashxsub(aTHX_ cv);
7609             }\n";
7610             } else {
7611 0         0 print "\tboot_$stashxsub(aTHX_ get_cv(\"$stashname\::bootstrap\", GV_ADD));\n";
7612             }
7613             } else {
7614 0         0 print "\tboot_$stashxsub(aTHX_ NULL);\n";
7615             }
7616 0         0 print "#endif\n";
7617 0         0 print "\tSPAGAIN;\n";
7618             #print "\tPUTBACK;\n";
7619             } else {
7620             warn "no dl_init for $stashname, ".
7621 0 0       0 (!$xsub{$stashname} ? "not bootstrapped\n" : "bootstrapped as $xsub{$stashname}\n")
    0          
7622             if $verbose;
7623             # XXX Too late. This might fool run-time DynaLoading.
7624             # We really should remove this via init from @DynaLoader::dl_modules
7625 0         0 @DynaLoader::dl_modules = grep { $_ ne $stashname } @DynaLoader::dl_modules;
  0         0  
7626              
7627             }
7628             }
7629 0         0 print "\tFREETMPS;\n";
7630 0 0       0 print "\tcxstack_ix--;\n" if $xs; # i.e. POPBLOCK
7631 0         0 print "\tLEAVE;\n";
7632 0         0 print "/* end DynaLoader bootstrapping */\n";
7633 0 0       0 close XS if $staticxs;
7634             }
7635 0         0 print "}\n";
7636             }
7637              
7638             sub output_main {
7639 0 0   0 0 0 if (!defined($module)) {
7640 0         0 print <<'_EOT10';
7641              
7642             /* if USE_IMPLICIT_SYS, we need a 'real' exit */
7643             #if defined(exit)
7644             #undef exit
7645             #endif
7646              
7647             int
7648             main(int argc, char **argv, char **env)
7649             {
7650             int exitstatus;
7651             int i;
7652             char **fakeargv;
7653             int options_count;
7654             PerlInterpreter *my_perl;
7655              
7656             PERL_SYS_INIT3(&argc,&argv,&env);
7657              
7658             #ifdef WIN32
7659             #define PL_do_undump 0
7660             #endif
7661             if (!PL_do_undump) {
7662             my_perl = perl_alloc();
7663             if (!my_perl)
7664             exit(1);
7665             perl_construct( my_perl );
7666             PL_perl_destruct_level = 0;
7667             }
7668             _EOT10
7669 0 0 0     0 if ($ITHREADS and $] > 5.007) {
7670             # XXX init free elems!
7671 0         0 my $pad_len = regex_padav->FILL; # first is an empty avref
7672 0         0 print <<_EOT11;
7673             #ifdef USE_ITHREADS
7674             if (!*PL_regex_pad) {
7675             /* Someone is overwriting regex_pad since 5.15, but not on -fno-warnings */
7676             PL_regex_padav = newAV();
7677             #if PERL_VERSION > 10
7678             av_push(PL_regex_padav, newSVpvs("")); /* First entry is empty */
7679             #else
7680             av_push(PL_regex_padav, newSViv(0));
7681             #endif
7682             PL_regex_pad = AvARRAY(PL_regex_padav);
7683             }
7684             for( i = 0; i < $pad_len; ++i ) {
7685             av_push( PL_regex_padav, newSViv(0) );
7686             }
7687             PL_regex_pad = AvARRAY( PL_regex_padav );
7688             #endif
7689             _EOT11
7690              
7691             }
7692 0 0       0 print " PL_exit_flags |= PERL_EXIT_DESTRUCT_END;\n" unless $PERL56;
7693 0 0       0 if ($] >= 5.008009) {
7694 0         0 print <<'_SAFE_PUTENV';
7695             #ifndef PERL_USE_SAFE_PUTENV
7696             PL_use_safe_putenv = 0;
7697             #endif
7698             _SAFE_PUTENV
7699             }
7700 0 0       0 if (!$PERL510) {
7701 0         0 print <<'_EOT12';
7702             #if defined(CSH)
7703             if (!PL_cshlen)
7704             PL_cshlen = strlen(PL_cshname);
7705             #endif
7706             _EOT12
7707             }
7708              
7709             # XXX With -e "" we need to fake parse_body() scriptname = BIT_BUCKET
7710 0         0 print <<'_EOT13';
7711             #ifdef ALLOW_PERL_OPTIONS
7712             #define EXTRA_OPTIONS 3
7713             #else
7714             #define EXTRA_OPTIONS 4
7715             #endif /* ALLOW_PERL_OPTIONS */
7716             Newx(fakeargv, argc + EXTRA_OPTIONS + 1, char *);
7717             fakeargv[0] = argv[0];
7718             fakeargv[1] = "-e";
7719             fakeargv[2] = "";
7720             options_count = 3;
7721             _EOT13
7722              
7723             # honour -T
7724 0 0 0     0 if (!$PERL56 and ${^TAINT}) {
7725 0         0 print <<'_EOT14';
7726             fakeargv[options_count] = "-T";
7727             ++options_count;
7728             _EOT14
7729              
7730             }
7731 0         0 print <<'_EOT15';
7732             #ifndef ALLOW_PERL_OPTIONS
7733             fakeargv[options_count] = "--";
7734             ++options_count;
7735             #endif /* ALLOW_PERL_OPTIONS */
7736             for (i = 1; i < argc; i++)
7737             fakeargv[i + options_count - 1] = argv[i];
7738             fakeargv[argc + options_count - 1] = 0;
7739              
7740             exitstatus = perl_parse(my_perl, xs_init, argc + options_count - 1,
7741             fakeargv, env);
7742             if (exitstatus)
7743             exit( exitstatus );
7744              
7745             TAINT;
7746             _EOT15
7747              
7748 0 0       0 if ($use_perl_script_name) {
7749 0         0 my $dollar_0 = cstring($0);
7750 0         0 print sprintf(qq{ sv_setpv_mg(get_svs("0", GV_ADD|GV_NOTQUAL), %s);\n}, $dollar_0);
7751 0         0 print sprintf(qq{ CopFILE_set(&PL_compiling, %s);\n}, $dollar_0);
7752             }
7753             else {
7754             #print q{ warn("PL_origalen=%d\n", PL_origalen);},"\n";
7755 0         0 print qq{ sv_setpv_mg(get_svs("0", GV_ADD|GV_NOTQUAL), argv[0]);\n};
7756 0         0 print qq{ CopFILE_set(&PL_compiling, argv[0]);\n};
7757             }
7758             # more global vars
7759 0 0       0 print " PL_hints = $^H;\n" if $^H;
7760 0 0       0 print " PL_unicode = ${^UNICODE};\n" if ${^UNICODE};
7761             # system-specific needs to be skipped: is set during init_i18nl10n if PerlIO
7762             # is compiled in and on a utf8 locale.
7763             #print " PL_utf8locale = ${^UTF8LOCALE};\n" if ${^UTF8LOCALE};
7764             #print " PL_utf8cache = ${^UTF8CACHE};\n" if ${^UTF8CACHE};
7765             # nomg
7766 0 0       0 print sprintf(qq{ sv_setpv(get_svs(";", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($;)) if $; ne "\34";
7767 0 0       0 print sprintf(qq{ sv_setpv(get_svs("\\"", GV_NOTQUAL), %s); /* \$" */\n}, cstring($")) if $" ne " ";
7768             # global IO vars
7769 0 0       0 if ($PERL56) {
7770 0 0       0 print sprintf(qq{ PL_ofs = %s; PL_ofslen = %u; /* \$, */\n}, cstring($,), length $,) if $,;
7771 0 0       0 print sprintf(qq{ PL_ors = %s; PL_orslen = %u; /* \$\\ */\n}, cstring($\), length $\) if $\;
7772             } else {
7773 0 0       0 print sprintf(qq{ sv_setpv_mg(GvSVn(PL_ofsgv), %s); /* \$, */\n}, cstring($,)) if $,;
7774 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs("\\\\", GV_ADD|GV_NOTQUAL), %s); /* \$\\ */\n}, cstring($\)) if $\; #ORS
7775             }
7776 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs("/", GV_NOTQUAL), %s);\n}, cstring($/)) if $/ ne "\n"; #RS
7777 0 0       0 print qq{ sv_setiv_mg(get_svs("|", GV_ADD|GV_NOTQUAL), $|);\n} if $|; #OUTPUT_AUTOFLUSH
7778             # global format vars
7779 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs("^A", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($^A)) if $^A; #ACCUMULATOR
7780 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
7781 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs(":", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($:)) if $: ne " \n-"; #LINE_BREAK_CHARACTERS
7782 0 0       0 print sprintf(qq/ sv_setpv_mg(get_svs("^", GV_ADD|GV_NOTQUAL), savepvn(%s, %u));\n/, cstring($^), length($^))
7783             if $^ ne "STDOUT_TOP";
7784 0 0       0 print sprintf(qq/ sv_setpv_mg(get_svs("~", GV_ADD|GV_NOTQUAL), savepvn(%s, %u));\n/, cstring($~), length($~))
7785             if $~ ne "STDOUT";
7786 0 0       0 print qq{ sv_setiv_mg(get_svs("%", GV_ADD|GV_NOTQUAL), $%);\n} if $%; #PAGE_NUMBER
7787 0 0 0     0 print qq{ sv_setiv_mg(get_svs("-", GV_ADD|GV_NOTQUAL), $-);\n} unless ($- == 0 or $- == 60); #LINES_LEFT
7788 0 0       0 print qq{ sv_setiv_mg(get_svs("=", GV_ADD|GV_NOTQUAL), $=);\n} if $= != 60; #LINES_PER_PAGE
7789              
7790             # deprecated global vars
7791 55 0   55   32981 print qq{ {SV* s = get_svs("[",GV_NOTQUAL); sv_setiv(s, $[); mg_set(s);}\n} if $[; #ARRAY_BASE
  55         18229  
  55         49255  
  0         0  
7792 0 0       0 if ($] < 5.010) { # OFMT and multiline matching
7793 0         0 eval q[
7794             print sprintf(qq{ sv_setpv(GvSVn(gv_fetchpv("\$#", GV_ADD|GV_NOTQUAL, SVt_PV)), %s);\n},
7795             cstring($#)) if $#;
7796             print sprintf(qq{ sv_setiv(GvSVn(gv_fetchpv("\$*", GV_ADD|GV_NOTQUAL, SVt_IV)), %d);\n}, $*) if $*;
7797             ];
7798             }
7799              
7800 0         0 print sprintf(qq{ sv_setpv_mg(get_svs("\030", GV_ADD|GV_NOTQUAL), %s); /* \$^X */\n}, cstring($^X));
7801 0         0 print <<"EOT";
7802             TAINT_NOT;
7803              
7804             #if PERL_VERSION < 10 || ((PERL_VERSION == 10) && (PERL_SUBVERSION < 1))
7805             PL_compcv = 0;
7806             #else
7807             PL_compcv = MUTABLE_CV(newSV_type(SVt_PVCV));
7808             CvUNIQUE_on(PL_compcv);
7809             CvPADLIST(PL_compcv) = pad_new(0);
7810             #endif
7811              
7812             /* our special compiled init */
7813             perl_init(aTHX);
7814             EOT
7815 0 0       0 print " perl_init1(aTHX);\n" if $init1->index >= 0;
7816 0 0       0 print " dl_init(aTHX);\n" unless defined $module;
7817 0 0       0 print " perl_init2(aTHX);\n" if $init2->index >= 0;
7818 0         0 print "\n exitstatus = perl_run( my_perl );\n";
7819 0         0 foreach my $s ( @{ $init->[-1]{pre_destruct} } ) {
  0         0  
7820 0         0 print " ".$s."\n";
7821             }
7822              
7823 0 0       0 if ( !$B::C::destruct ) {
7824 0 0       0 warn "fast_perl_destruct (-fno-destruct)\n" if $verbose;
7825 0         0 print " fast_perl_destruct( my_perl );\n";
7826             #} elsif ( $PERL510 and (@B::C::static_free or $free->index > -1) ) {
7827             # warn "my_perl_destruct static strings\n" if $verbose;
7828             # print " my_perl_destruct( my_perl );\n";
7829             #} elsif ( $] >= 5.007003 ) {
7830             # print " perl_destruct( my_perl );\n";
7831             }
7832             else {
7833 0         0 print " my_perl_destruct( my_perl );\n";
7834             }
7835             # XXX endav is called via call_list and so it is freed right after usage. Setting dirty here is useless
7836             #print " PL_dirty = 1;\n" unless $B::C::pv_copy_on_grow; # protect against pad undef in END block
7837 0         0 print <<'EOT1';
7838             perl_free( my_perl );
7839              
7840             PERL_SYS_TERM();
7841              
7842             exit( exitstatus );
7843             }
7844             EOT1
7845              
7846             } # module
7847             }
7848              
7849             sub dump_symtable {
7850             # For debugging
7851 0     0 0 0 my ( $sym, $val );
7852 0         0 warn "----Symbol table:\n";
7853             #while ( ( $sym, $val ) = each %symtable )
7854 0         0 for $sym (sort keys %symtable) {
7855 0         0 $val = $symtable{$sym};
7856 0         0 warn "$sym => $val\n";
7857             }
7858 0         0 warn "---End of symbol table\n";
7859             }
7860              
7861             sub save_object {
7862 0     0 0 0 my $sv;
7863 0         0 foreach $sv (@_) {
7864 0         0 svref_2object($sv)->save;
7865             }
7866             }
7867              
7868       0 0   sub Dummy_BootStrap { }
7869              
7870             #ignore nullified cv
7871       0     sub B::SPECIAL::savecv {}
7872              
7873             sub B::GV::savecv {
7874 0     0   0 my $gv = shift;
7875 0         0 my $package = $gv->STASH->NAME;
7876 0         0 my $name = $gv->NAME;
7877 0         0 my $cv = $gv->CV;
7878 0         0 my $sv = $gv->SV;
7879 0         0 my $av = $gv->AV;
7880 0         0 my $hv = $gv->HV;
7881              
7882 0         0 my $fullname = $package . "::" . $name;
7883             warn sprintf( "Checking GV *%s 0x%x\n", cstring($fullname), $$gv )
7884 0 0 0     0 if $debug{gv} and $verbose;
7885             # We may be looking at this package just because it is a branch in the
7886             # symbol table which is on the path to a package which we need to save
7887             # e.g. this is 'Getopt' and we need to save 'Getopt::Long'
7888             #
7889 0 0 0     0 return if ( $package ne 'main' and !$include_package{$package} );
7890 0 0 0     0 return if ( $package eq 'main' and
7891             $name =~ /^([^\w].*|_\<.*|INC|ARGV|SIG|ENV|BEGIN|main::|!)$/ );
7892              
7893 0 0       0 warn sprintf( "Used GV \*$fullname 0x%x\n", $$gv ) if $debug{gv};
7894 0 0 0     0 return unless ( $$cv || $$av || $$sv || $$hv || $gv->IO || $gv->FORM );
      0        
      0        
      0        
      0        
7895 0 0 0     0 if ($$cv and $name eq 'bootstrap' and $cv->XSUB) {
      0        
7896             #return $cv->save($fullname);
7897 0 0       0 warn sprintf( "Skip XS \&$fullname 0x%x\n", $$cv ) if $debug{gv};
7898 0         0 return;
7899             }
7900 0 0 0     0 if ( $$cv and in_static_core($package, $name) and ref($cv) eq 'B::CV' # 5.8,4 issue32
      0        
      0        
7901             and $cv->XSUB ) {
7902 0 0       0 warn("Skip internal XS $fullname\n") if $debug{gv};
7903             # but prevent it from being deleted
7904 0 0       0 unless ($dumped_package{$package}) {
7905             #$dumped_package{$package} = 1;
7906 0         0 mark_package($package, 1);
7907             }
7908 0         0 return;
7909             }
7910 0 0       0 if ($package eq 'B::C') {
7911 0 0       0 warn sprintf( "Skip XS \&$fullname 0x%x\n", $$cv ) if $debug{gv};
7912 0         0 return;
7913             }
7914 0 0       0 if ($fullname =~ /^(bytes|utf8)::AUTOLOAD$/) {
7915 0         0 $gv = force_heavy($package);
7916             }
7917             # XXX fails and should not be needed. The B::C part should be skipped 9 lines above, but be defensive
7918 0 0 0     0 return if $fullname eq 'B::walksymtable' or $fullname eq 'B::C::walksymtable';
7919             # Config is marked on any Config symbol. TIE and DESTROY are exceptions,
7920             # used by the compiler itself
7921 0 0       0 if ($name eq 'Config') {
7922 0 0       0 mark_package('Config', 1) if !$include_package{'Config'};
7923             }
7924 0 0 0     0 $dumped_package{$package} = 1 if !exists $dumped_package{$package} and $package !~ /::$/;
7925 0 0       0 warn sprintf( "Saving GV \*$fullname 0x%x\n", $$gv ) if $debug{gv};
7926 0         0 $gv->save($fullname);
7927             }
7928              
7929             # Fixes bug #307: use foreach, not each
7930             # each is not safe to use (at all). walksymtable is called recursively which might add
7931             # symbols to the stash, which might cause re-ordered rehashes, which will fool the hash
7932             # iterator, leading to missing symbols in the binary.
7933             # Old perl5 bug: The iterator should really be stored in the op, not the hash.
7934             sub walksymtable {
7935 0     0 0 0 my ($symref, $method, $recurse, $prefix) = @_;
7936 0         0 my ($sym, $ref, $fullname);
7937 0 0       0 $prefix = '' unless defined $prefix;
7938              
7939             # If load_utf8_heavy doesn't happen before we walk utf8::
7940             # (when utf8_heavy has already been called) then the stored CV for utf8::S
7941             # WASHNEW could be wrong.
7942 0 0 0     0 load_utf8_heavy() if ( $prefix eq 'utf8::' && defined $symref->{'SWASHNEW'} );
7943              
7944             my @list = sort {
7945             # we want these symbols to be saved last to avoid incomplete saves
7946             # +/- reverse is to defer + - to fix Tie::Hash::NamedCapturespecial cases. GH #247
7947             # _loose_name redefined from utf8_heavy.pl GH #364
7948 0         0 foreach my $v (qw{- + utf8:: bytes::}) {
  0         0  
7949 0 0       0 $a eq $v and return 1;
7950 0 0       0 $b eq $v and return -1;
7951             }
7952             # reverse order for now to preserve original behavior before improved patch
7953 0         0 $b cmp $a
7954             } keys %$symref;
7955              
7956 0         0 foreach my $sym ( @list ) {
7957 55     55   295 no strict 'refs';
  55         95  
  55         8189  
7958 0         0 $ref = $symref->{$sym};
7959 0         0 $fullname = "*main::".$prefix.$sym;
7960 0 0       0 if ($sym =~ /::$/) {
7961 0         0 $sym = $prefix . $sym;
7962 0 0 0     0 if (svref_2object(\*$sym)->NAME ne "main::" && $sym ne "::" && &$recurse($sym)) {
      0        
7963 0         0 walksymtable(\%$fullname, $method, $recurse, $sym);
7964             }
7965             } else {
7966 0         0 svref_2object(\*$fullname)->$method();
7967             }
7968             }
7969             }
7970              
7971             sub walk_syms {
7972 0     0 0 0 my $package = shift;
7973 55     55   229 no strict 'refs';
  55         82  
  55         6532  
7974 0 0       0 return if $dumped_package{$package};
7975 0 0 0     0 warn "walk_syms $package\n" if $debug{pkg} and $verbose;
7976 0         0 $dumped_package{$package} = 1;
7977 0     0   0 walksymtable( \%{$package.'::'}, "savecv", sub { 1 }, $package.'::' );
  0         0  
  0         0  
7978             }
7979              
7980             # simplified walk_syms
7981             # needed to populate @B::C::Config::deps from Makefile.PL from within this %INC context
7982             sub walk_stashes {
7983 0     0 0 0 my ($symref, $prefix) = @_;
7984 55     55   225 no strict 'refs';
  55         70  
  55         11369  
7985 0 0       0 $prefix = '' unless defined $prefix;
7986 0         0 foreach my $sym ( sort keys %$symref ) {
7987 0 0       0 if ($sym =~ /::$/) {
7988 0         0 $sym = $prefix . $sym;
7989 0         0 $B::C::deps{ substr($sym,0,-2) }++;
7990 0 0 0     0 if ($sym ne "main::" && $sym ne "::") {
7991 0         0 walk_stashes(\%$sym, $sym);
7992             }
7993             }
7994             }
7995             }
7996              
7997             sub collect_deps {
7998 0     0 0 0 %B::C::deps = ();
7999 0         0 walk_stashes(\%main::);
8000 0         0 print join " ",(sort keys %B::C::deps);
8001             }
8002              
8003             sub mark_package {
8004 0     0 0 0 my $package = shift;
8005 0         0 my $force = shift;
8006 0 0       0 $force = 0 if $] < 5.010;
8007 0 0       0 return if skip_pkg($package); # or $package =~ /^B::C(C?)::/;
8008 0 0 0     0 if ( !$include_package{$package} or $force ) {
8009 55     55   233 no strict 'refs';
  55         65  
  55         14698  
8010 0 0 0     0 warn "mark_package($package, $force)\n" if $verbose and $debug{pkg};
8011 0         0 my @IO = qw(IO::File IO::Handle IO::Socket IO::Seekable IO::Poll);
8012 0 0       0 mark_package('IO') if grep { $package eq $_ } @IO;
  0         0  
8013 0 0       0 mark_package("DynaLoader") if $package eq 'XSLoader';
8014 0 0       0 $use_xsloader = 1 if $package =~ /^B|Carp$/; # to help CC a bit (49)
8015             # i.e. if force
8016 0 0 0     0 if (exists $include_package{$package}
      0        
8017             and !$include_package{$package}
8018             and $savINC{inc_packname($package)})
8019             {
8020 0 0       0 warn sprintf("$package previously deleted, save now%s\n",
    0          
8021             $force?" (forced)":"") if $verbose;
8022             # $include_package{$package} = 1;
8023 0         0 add_hashINC( $package );
8024 0         0 walk_syms( $package );
8025             } else {
8026             warn sprintf("mark $package%s\n", $force?" (forced)":"")
8027 0 0 0     0 if !$include_package{$package} and $verbose and $debug{pkg};
    0 0        
8028 0         0 $include_package{$package} = 1;
8029 0 0       0 push_package($package) if $] < 5.010;
8030 0 0       0 walk_syms( $package ) if !$B::C::walkall; # fixes i27-1
8031             }
8032 0         0 my @isa = get_isa($package);
8033 0 0       0 if ( @isa ) {
8034             # XXX walking the ISA is often not enough.
8035             # we should really check all new packages since the last full scan.
8036 0         0 foreach my $isa ( @isa ) {
8037 0 0       0 next if $isa eq $package;
8038 0 0       0 if ( $isa eq 'DynaLoader' ) {
8039 0 0       0 unless ( defined( &{ $package . '::bootstrap' } ) ) {
  0         0  
8040 0 0       0 warn "Forcing bootstrap of $package\n" if $verbose;
8041 0         0 eval { $package->bootstrap };
  0         0  
8042             }
8043             }
8044 0 0 0     0 if ( !$include_package{$isa} and !$skip_package{$isa} ) {
8045 55     55   250 no strict 'refs';
  55         84  
  55         35505  
8046 0 0       0 warn "$isa saved (it is in $package\'s \@ISA)\n" if $verbose;
8047 0         0 B::svref_2object( \@{$isa."::ISA"} ) ->save; #308
  0         0  
8048 0 0       0 if (exists $include_package{$isa} ) {
8049 0 0       0 warn "$isa previously deleted, save now\n" if $verbose; # e.g. Sub::Name
8050 0         0 mark_package($isa);
8051 0         0 walk_syms($isa); # avoid deep recursion
8052             } else {
8053             #warn "isa $isa save\n" if $verbose;
8054 0         0 mark_package($isa);
8055             }
8056             }
8057             }
8058             }
8059             }
8060 0         0 return 1;
8061             }
8062              
8063             # XS in CORE which do not need to be bootstrapped extra.
8064             # There are some specials like mro,re,UNIVERSAL.
8065             sub in_static_core {
8066 0     0 0 0 my ($stashname, $cvname) = @_;
8067 0 0       0 if ($stashname eq 'UNIVERSAL') {
8068 0         0 return $cvname =~ /^(isa|can|DOES|VERSION)$/;
8069             }
8070 0 0       0 %static_core_pkg = map {$_ => 1} static_core_packages()
  0         0  
8071             unless %static_core_pkg;
8072 0 0       0 return 1 if $static_core_pkg{$stashname};
8073 0 0       0 if ($stashname eq 'mro') {
8074 0         0 return $cvname eq 'method_changed_in';
8075             }
8076 0 0       0 if ($stashname eq 're') {
8077 0         0 return $cvname =~ /^(is_regexp|regname|regnames|regnames_count|regexp_pattern)$/;;
8078             }
8079 0 0       0 if ($stashname eq 'PerlIO') {
8080 0         0 return $cvname eq 'get_layers';
8081             }
8082 0 0       0 if ($stashname eq 'PerlIO::Layer') {
8083 0         0 return $cvname =~ /^(find|NoWarnings)$/;
8084             }
8085 0         0 return 0;
8086             }
8087              
8088             # XS modules in CORE. Reserved namespaces.
8089             # Note: mro,re,UNIVERSAL have both, static core and dynamic/static XS
8090             # version has an external ::vxs
8091             sub static_core_packages {
8092 0     0 0 0 my @pkg = qw(Internals utf8 UNIVERSAL);
8093 0 0       0 push @pkg, qw(strict coretypes DynaLoader XSLoader) if $CPERL51;
8094 0 0       0 push @pkg, 'attributes' if $] < 5.011; # partially static and dynamic
8095 0 0       0 push @pkg, 'version' if $] >= 5.010; # partially static and dynamic
8096 0 0       0 push @pkg, 'Tie::Hash::NamedCapture' if !$PERL514; # dynamic since 5.14
8097             #push @pkg, 'DynaLoader' if $Config{usedl};
8098             # Win32CORE only in official cygwin pkg. And it needs to be bootstrapped,
8099             # handled by static_ext.
8100 0 0       0 push @pkg, 'Cygwin' if $^O eq 'cygwin';
8101 0 0       0 push @pkg, 'NetWare' if $^O eq 'NetWare';
8102 0 0       0 push @pkg, 'OS2' if $^O eq 'os2';
8103 0 0       0 push @pkg, qw(VMS VMS::Filespec vmsish) if $^O eq 'VMS';
8104             #push @pkg, 'PerlIO' if $] >= 5.008006; # get_layers only
8105 0         0 push @pkg, split(/ /,$Config{static_ext});
8106 0         0 return @pkg;
8107             }
8108              
8109             sub skip_pkg {
8110 0     0 0 0 my $package = shift;
8111 0 0 0     0 if ( $package =~ /^(main::)?(Internals|O)::/
      0        
      0        
      0        
      0        
      0        
      0        
      0        
8112             #or $package =~ /::::/ # CORE/base/lex.t 54
8113             or $package =~ /^B::C::/
8114             or $package eq '__ANON__'
8115             or index($package, " ") != -1 # XXX skip invalid package names
8116             or index($package, "(") != -1 # XXX this causes the compiler to abort
8117             or index($package, ")") != -1 # XXX this causes the compiler to abort
8118             or exists $skip_package{$package}
8119             or ($DB::deep and $package =~ /^(DB|Term::ReadLine)/)) {
8120 0         0 return 1;
8121             }
8122 0         0 return 0;
8123             }
8124              
8125             # Do not delete/ignore packages which were brought in from the script,
8126             # i.e. not defined in B::C or O. Just to be on the safe side.
8127             sub can_delete {
8128 0     0 0 0 my $pkg = shift;
8129 0 0 0     0 if (exists $all_bc_deps{$pkg} and $B::C::can_delete_pkg) { return 1 };
  0         0  
8130 0         0 return undef;
8131             }
8132              
8133             sub should_save {
8134 55     55   251 no strict qw(vars refs);
  55         75  
  55         20399  
8135 0     0 0 0 my $package = shift;
8136 0         0 $package =~ s/::$//;
8137 0 0       0 if ( skip_pkg($package) ) {
8138 0 0       0 delete_unsaved_hashINC($package) if can_delete($package);
8139 0         0 return 0;
8140             }
8141 0 0       0 return $include_package{$package} = 0
8142             if ( $package =~ /::::/ ); # skip ::::ISA::CACHE etc.
8143 0 0       0 warn "Considering $package\n" if $debug{pkg}; #$include_package{$package}
8144 0 0       0 return if index($package, " ") != -1; # XXX skip invalid package names
8145 0 0       0 return if index($package, "(") != -1; # XXX this causes the compiler to abort
8146 0 0       0 return if index($package, ")") != -1; # XXX this causes the compiler to abort
8147             # core static mro has exactly one member, ext/mro has more
8148 0 0       0 if ($package eq 'mro') {
8149             # B::C is setting %mro:: to 3, make sure we have at least 10
8150 0 0       0 if (!is_using_mro()) { # core or ext?
8151 0 0       0 warn "ext/mro not loaded - skip\n" if $debug{pkg};
8152 0         0 return;
8153             } else {
8154 0 0       0 warn "ext/mro already loaded\n" if $debug{pkg};
8155             # $include_package{mro} = 1 if grep { $_ eq 'mro' } @DynaLoader::dl_modules;
8156 0         0 return $include_package{mro};
8157             }
8158             }
8159 0 0 0     0 if ($package eq 'attributes' and $] > 5.011
      0        
8160 0         0 and grep { $_ eq 'attributes' } @DynaLoader::dl_modules)
8161             {
8162 0         0 mark_package($package, 1);
8163 0         0 return 1;
8164             }
8165 0 0       0 if (exists $all_bc_deps{$package}) {
8166 0         0 foreach my $u ( grep( $include_package{$_}, sort keys %include_package ) ) {
8167             # If this package is a prefix to something we are saving, traverse it
8168             # but do not mark it for saving if it is not already
8169             # e.g. to get to B::OP we need to traverse B:: but need not save B
8170 0         0 my $p = $package;
8171 0         0 $p =~ s/(\W)/\\$1/g;
8172 0 0 0     0 return 1 if ( $u =~ /^$p\:\:/ ) && $include_package{$package};
8173             }
8174             }
8175             # Needed since 5.12.2: Check already if deleted
8176 0         0 my $incpack = inc_packname($package);
8177 0 0 0     0 if ( $] > 5.015001 and exists $all_bc_deps{$package}
      0        
      0        
8178             and !exists $curINC{$incpack} and $savINC{$incpack} ) {
8179 0         0 $include_package{$package} = 0;
8180 0 0       0 warn "Cached $package not in \%INC, already deleted (early)\n" if $debug{pkg};
8181 0         0 return 0;
8182             }
8183             # issue348: only drop B::C packages, not any from user code.
8184 0 0 0     0 if (($package =~ /^DynaLoader|XSLoader$/ and $use_xsloader)
      0        
8185             or (!exists $all_bc_deps{$package})) {
8186 0         0 $include_package{$package} = 1;
8187             }
8188             # If this package is in the same file as main:: or our source, save it. (72, 73)
8189 0 0       0 if ($mainfile) {
8190             # Find the first cv in this package for CV->FILE
8191 55     55   262 no strict 'refs';
  55         75  
  55         54097  
8192 0         0 for my $sym (sort keys %{$package.'::'}) {
  0         0  
8193 0 0       0 if (defined &{$package.'::'.$sym}) {
  0         0  
8194             # compare cv->FILE to $mainfile
8195 0         0 my $cv = svref_2object(\&{$package.'::'.$sym});
  0         0  
8196 0 0 0     0 if ($cv and $cv->can('FILE') and $cv->FILE) {
      0        
8197 0 0       0 $include_package{$package} = 1 if $mainfile eq $cv->FILE;
8198 0         0 last;
8199             }
8200             }
8201             }
8202             }
8203             # add overloaded but otherwise empty packages (#172)
8204 0 0 0     0 if ($savINC{'overload.pm'} and exists ${$package.'::'}{OVERLOAD} and exists ${$package.'::'}{'()'}) {
  0   0     0  
  0         0  
8205 0         0 mark_package($package, 1);
8206 0         0 mark_package('overload', 1);
8207 0         0 return 1;
8208             }
8209             # Omit the packages which we use (and which cause grief
8210             # because of fancy "goto &$AUTOLOAD" stuff).
8211             # XXX Surely there must be a nicer way to do this.
8212 0 0       0 if ( exists $include_package{$package} ) {
8213 0 0       0 if (! exists $all_bc_deps{$package}) {
    0          
8214 0         0 $include_package{$package} = 1;
8215 0         0 $curINC{$incpack} = $savINC{$incpack};
8216 0 0       0 warn "Cached new $package is kept\n" if $debug{pkg};
8217             }
8218             elsif (!$include_package{$package}) {
8219 0 0       0 delete_unsaved_hashINC($package) if can_delete($package);
8220 0 0       0 warn "Cached $package is already deleted\n" if $debug{pkg};
8221             } else {
8222 0 0       0 warn "Cached $package is cached\n" if $debug{pkg};
8223             }
8224 0         0 return $include_package{$package};
8225             }
8226              
8227             # Now see if current package looks like an OO class. This is probably too strong.
8228 0 0       0 if (!$all_bc_deps{$package}) {
8229 0         0 foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE)) {
8230             # 5.10 introduced version and Regexp::DESTROY, which we dont want automatically.
8231             # XXX TODO This logic here is wrong and unstable. Fixes lead to more failures.
8232             # The walker deserves a rewrite.
8233 0 0 0     0 if ( UNIVERSAL::can( $package, $m ) and $package !~ /^(B::C|version|Regexp|utf8|SelectSaver)$/ ) {
8234 0 0 0     0 next if $package eq 'utf8' and $m eq 'DESTROY'; # utf8::DESTROY is empty
8235             # we load Errno by ourself to avoid double Config warnings [perl #]
8236             # and we have special logic to detect and include it
8237 0 0 0     0 next if $package =~ /^(Errno|Tie::Hash::NamedCapture)$/ and $m eq 'TIEHASH';
8238             # XXX Config and FileHandle should not just return. If unneeded skip em.
8239 0 0 0     0 return 0 if $package eq 'Config' and $m =~ /DESTROY|TIEHASH/; # Config detected in GV
8240             # IO::File|IO::Handle added for B::CC only
8241 0 0 0     0 return 0 if $package =~ /^(FileHandle|IO::File|IO::Handle)/ and $m eq 'new';
8242 0 0       0 warn "$package has method $m: saving package\n" if $debug{pkg};
8243 0         0 return mark_package($package);
8244             }
8245             }
8246             }
8247 0 0 0     0 if ($package !~ /^PerlIO/ and can_delete($package)) {
8248 0         0 delete_unsaved_hashINC($package);
8249             }
8250 0 0       0 if (can_delete($package)) {
    0          
8251 0 0       0 warn "Delete $package\n" if $debug{pkg};
8252 0         0 return $include_package{$package} = 0;
8253             } elsif (! exists $all_bc_deps{$package}) { # and not in @deps
8254 0 0       0 warn "Keep $package\n" if $debug{pkg};
8255 0         0 return $include_package{$package} = 1;
8256             } else { # in @deps
8257             # warn "Ignore $package\n" if $debug{pkg};
8258 0         0 return;
8259             }
8260             }
8261              
8262             sub inc_packname {
8263 225     225 0 160 my $package = shift;
8264             # See below at the reverse packname_inc: utf8 => utf8.pm + utf8_heavy.pl
8265 225         484 $package =~ s/\:\:/\//g;
8266 225         198 $package .= '.pm';
8267 225         225 return $package;
8268             }
8269              
8270             sub packname_inc {
8271 0     0 0 0 my $package = shift;
8272 0         0 $package =~ s/\//::/g;
8273 0 0       0 if ($package =~ /^(Config_git\.pl|Config_heavy.pl)$/) {
8274 0         0 return 'Config';
8275             }
8276 0 0       0 if ($package eq 'utf8_heavy.pl') {
8277 0         0 return 'utf8';
8278             }
8279 0         0 $package =~ s/\.p[lm]$//;
8280 0         0 return $package;
8281             }
8282              
8283             sub delete_unsaved_hashINC {
8284 225     225 0 186 my $package = shift;
8285 225         230 my $incpack = inc_packname($package);
8286             # Not already saved package, so it is not loaded again at run-time.
8287 225 50       316 return if $dumped_package{$package};
8288             # Never delete external packages, but this check is done before
8289 225 0 33     600 return if $package =~ /^DynaLoader|XSLoader$/
      33        
8290             and defined $use_xsloader
8291             and $use_xsloader == 0;
8292 225 50 33     414 return if $^O eq 'MSWin32' and $package =~ /^Carp|File::Basename$/;
8293 225         395 $include_package{$package} = 0;
8294 225 50       321 if ($curINC{$incpack}) {
8295             #warn "Deleting $package from \%INC\n" if $debug{pkg};
8296 0 0       0 $savINC{$incpack} = $curINC{$incpack} if !$savINC{$incpack};
8297 0         0 $curINC{$incpack} = undef;
8298 0         0 delete $curINC{$incpack};
8299             }
8300             }
8301              
8302             sub add_hashINC {
8303 0     0 0 0 my $package = shift;
8304 0         0 my $incpack = inc_packname($package);
8305 0         0 $include_package{$package} = 1;
8306 0 0       0 unless ($curINC{$incpack}) {
8307 0 0       0 if ($savINC{$incpack}) {
8308 0 0       0 warn "Adding $package to \%INC (again)\n" if $debug{pkg};
8309 0         0 $curINC{$incpack} = $savINC{$incpack};
8310             # need to check xsub
8311 0 0       0 $use_xsloader = 1 if $package =~ /^DynaLoader|XSLoader$/;
8312             } else {
8313 0 0       0 warn "Adding $package to \%INC\n" if $debug{pkg};
8314 0         0 for (@INC) {
8315 0         0 my $p = $_.'/'.$incpack;
8316 0 0       0 if (-e $p) { $curINC{$incpack} = $p; last; }
  0         0  
  0         0  
8317             }
8318 0 0       0 $curINC{$incpack} = $incpack unless $curINC{$incpack};
8319             }
8320             }
8321             }
8322              
8323             sub walkpackages {
8324 0     0 0 0 my ( $symref, $recurse, $prefix ) = @_;
8325 55     55   265 no strict 'vars';
  55         93  
  55         9897  
8326 0 0       0 $prefix = '' unless defined $prefix;
8327             # check if already deleted - failed since 5.15.2
8328 0 0       0 return if $savINC{inc_packname(substr($prefix,0,-2))};
8329 0         0 for my $sym (sort keys %$symref) {
8330 0         0 my $ref = $symref->{$sym};
8331 0 0       0 next unless $ref;
8332 0         0 local (*glob);
8333 0         0 *glob = $ref;
8334 0 0       0 if ( $sym =~ /::$/ ) {
8335 0         0 $sym = $prefix . $sym;
8336 0 0 0     0 warn("Walkpackages $sym\n") if $debug{pkg} and $debug{walk};
8337             # This walker skips main subs to avoid recursion into O compiler subs again
8338             # and main syms are already handled
8339 0 0 0     0 if ( $sym ne "main::" && $sym ne "::" && &$recurse($sym) ) {
      0        
8340 0         0 walkpackages( \%glob, $recurse, $sym );
8341             }
8342             }
8343             }
8344             }
8345              
8346             sub save_unused_subs {
8347 55     55   238 no strict qw(refs);
  55         76  
  55         73398  
8348 0     0 0 0 my %sav_debug;
8349 0 0       0 if ( $debug{unused} ) {
8350 0         0 %sav_debug = %debug;
8351 0         0 %debug = ();
8352             }
8353 0 0       0 my $main = $module ? $module."::" : "main::";
8354              
8355             # -fwalkall: better strategy for compile-time added and required packages:
8356             # loop savecv and check pkg cache for new pkgs.
8357             # if so loop again with those new pkgs only, until the list of new pkgs is empty
8358 0         0 my ($walkall_cnt, @init_unused, @unused, @dumped) = (0);
8359             #do
8360 0         0 @init_unused = grep { $include_package{$_} } keys %include_package;
  0         0  
8361 0 0       0 if ($verbose) {
8362 0 0       0 warn "Prescan for unused subs in $main " . ($sav_debug{unused} ? " (silent)\n" : "\n");
8363             }
8364             # XXX TODO better strategy for compile-time added and required packages:
8365             # loop savecv and check pkg cache for new pkgs.
8366             # if so loop again with those new pkgs only, until the list of new pkgs is empty
8367 0         0 descend_marked_unused();
8368 0 0       0 walkpackages( \%{$main}, \&should_save, $main eq 'main::' ? undef : $main );
  0         0  
8369 0 0       0 warn "Saving unused subs in $main" . ($sav_debug{unused} ? " (silent)\n" : "\n")
    0          
8370             if $verbose;
8371 0         0 walksymtable( \%{$main}, "savecv", \&should_save );
  0         0  
8372 0         0 @unused = grep { $include_package{$_} } keys %include_package;
  0         0  
8373 0 0       0 @dumped = grep { $dumped_package{$_} and $_ ne 'main' } keys %dumped_package;
  0         0  
8374 0 0       0 warn sprintf("old unused: %d, new: %d, dumped: %d\n", scalar @init_unused, scalar @unused, scalar @dumped)
8375             if $verbose;
8376 0 0       0 if (!$B::C::walkall) {
8377 0         0 @unused = @init_unused = ();
8378             } else {
8379 0         0 my $done;
8380 0   0     0 do {
8381 0         0 $done = dump_rest();
8382 0         0 @unused = grep { $include_package{$_} } keys %include_package;
  0         0  
8383 0 0       0 @dumped = grep { $dumped_package{$_} and $_ ne 'main' } keys %dumped_package;
  0         0  
8384             } while @unused > @dumped and $done;
8385 0 0       0 last if $walkall_cnt++ > 3;
8386             }
8387             #} while @unused > @init_unused;
8388              
8389 0 0       0 if ( $sav_debug{unused} ) {
8390 0         0 %debug = %sav_debug;
8391             }
8392              
8393             # If any m//i is run-time loaded we'll get a "Undefined subroutine utf8::SWASHNEW"
8394             # With -fno-fold we don't insist on loading utf8_heavy and Carp.
8395             # Until it is compile-time required.
8396 0 0 0     0 if (exists($INC{'unicore/To/Title.pl'})
      0        
      0        
      0        
      0        
8397             or exists($INC{'unicore/To/Tc.pl'}) #242
8398             or exists($INC{'unicore/Heavy.pl'}) #242
8399             or ($savINC{'utf8_heavy.pl'} and ($B::C::fold or exists($savINC{'utf8.pm'})))) {
8400 0 0       0 require "utf8.pm" unless $savINC{"utf8.pm"};
8401 0         0 mark_package('utf8');
8402 0         0 load_utf8_heavy();
8403             }
8404             # run-time Carp
8405             # With -fno-warnings we don't insist on initializing warnings::register_categories and Carp.
8406             # Until it is compile-time required.
8407             # 68KB exe size 32-bit
8408 0 0 0     0 if ($] >= 5.013005 and ($B::C::warnings and exists $dumped_package{Carp})) {
      0        
8409 0         0 svref_2object( \&{"warnings\::register_categories"} )->save; # 68Kb 32bit
  0         0  
8410 0         0 add_hashINC("warnings");
8411 0         0 add_hashINC("warnings::register");
8412             }
8413             #196 missing INIT
8414 0 0 0     0 if ($xsub{EV} and $dumped_package{EV} and $EV::VERSION le '4.21') {
      0        
8415 0         0 $init2->add_eval
8416             (
8417             q(EV::default_loop() or )
8418             .q(die 'EV: cannot initialise libev backend. bad $ENV{LIBEV_FLAGS}?';)
8419             );
8420             }
8421 0 0       0 if ($use_xsloader) {
8422 0         0 force_saving_xsloader();
8423 0         0 mark_package('Config', 1); # required by Dynaloader and special cased previously
8424             }
8425             }
8426              
8427             sub inc_cleanup {
8428 0     0 0 0 my $rec_cnt = shift;
8429             # %INC sanity check issue 89:
8430             # omit unused, unsaved packages, so that at least run-time require will pull them in.
8431 0         0 my @deleted_inc;
8432 0 0       0 if ($CPERL51) {
8433 0         0 for (qw(strict coretypes DynaLoader XSLoader)) {
8434 0         0 $dumped_package{$_}++;
8435 0         0 $curINC{$_.".pm"} = $INC{$_.".pm"};
8436             }
8437             }
8438 0         0 for my $package (sort keys %INC) {
8439 0         0 my $pkg = packname_inc($package);
8440 0 0 0     0 if ($package =~ /^(Config_git\.pl|Config_heavy.pl)$/ and !$dumped_package{'Config'}) {
    0 0        
    0 0        
8441 0         0 delete $curINC{$package};
8442             } elsif ($package eq 'utf8_heavy.pl' and !$include_package{'utf8'}) {
8443 0         0 delete $curINC{$package};
8444 0         0 delete_unsaved_hashINC('utf8');
8445             } elsif (!$B::C::walkall and !exists $dumped_package{$pkg}) {
8446 0         0 delete_unsaved_hashINC($pkg);
8447 0         0 push @deleted_inc, $pkg;
8448             }
8449             }
8450             # sync %curINC deletions back to %INC
8451 0         0 for my $p (sort keys %INC) {
8452 0 0       0 if (!exists $curINC{$p}) {
8453 0         0 delete $INC{$p};
8454 0         0 push @deleted_inc, $p;
8455             }
8456             }
8457 0 0 0     0 if ($debug{pkg} and $verbose) {
8458 0         0 warn "\%include_package: ".join(" ",grep{$include_package{$_}} sort keys %include_package)."\n";
  0         0  
8459 0         0 warn "\%dumped_package: ".join(" ",grep{$dumped_package{$_}} sort keys %dumped_package)."\n";
  0         0  
8460             }
8461             # issue 340,350: do only on -fwalkall? do it in the main walker step
8462             # as in branch walkall-early?
8463 0 0       0 if ($B::C::walkall) {
8464 0         0 my $again = dump_rest();
8465 0 0 0     0 inc_cleanup($rec_cnt++) if $again and $rec_cnt < 2; # maximal 3 times
8466             }
8467             # final cleanup
8468 0         0 for my $p (sort keys %INC) {
8469 0         0 my $pkg = packname_inc($p);
8470 0 0       0 delete_unsaved_hashINC($pkg) unless exists $dumped_package{$pkg};
8471             # sync %curINC deletions back to %INC
8472 0 0 0     0 if (!exists $curINC{$p} and exists $INC{$p}) {
8473 0         0 delete $INC{$p};
8474 0         0 push @deleted_inc, $p;
8475             }
8476             }
8477 0 0 0     0 if ($debug{pkg} and $verbose) {
8478 0 0       0 warn "Deleted from \%INC: ".join(" ",@deleted_inc)."\n" if @deleted_inc;
8479 0         0 my @inc = grep !/auto\/.+\.(al|ix)$/, sort keys %INC;
8480 0         0 warn "\%INC: ".join(" ",@inc)."\n";
8481             }
8482             }
8483              
8484             sub dump_rest {
8485 0     0 0 0 my $again;
8486 0 0 0     0 warn "dump_rest:\n" if $verbose or $debug{pkg};
8487             #for my $p (sort keys %INC) {
8488             #}
8489 0         0 for my $p (sort keys %include_package) {
8490 0         0 $p =~ s/^main:://;
8491 0 0 0     0 if ($include_package{$p} and !exists $dumped_package{$p}
      0        
      0        
8492             and !$static_core_pkg{$p}
8493             and $p !~ /^(threads|main|__ANON__|PerlIO)$/
8494             )
8495             {
8496 0 0 0     0 if ($p eq 'warnings::register' and !$B::C::warnings) {
8497 0         0 delete_unsaved_hashINC('warnings::register');
8498 0         0 next;
8499             }
8500 0         0 $again++;
8501 0 0 0     0 warn "$p marked but not saved, save now\n" if $verbose or $debug{pkg};
8502             # mark_package( $p, 1);
8503             #eval {
8504             # require(inc_packname($p)) && add_hashINC( $p );
8505             #} unless $savINC{inc_packname($p)};
8506 0         0 walk_syms( $p );
8507             }
8508             }
8509 0         0 $again;
8510             }
8511              
8512             my @made_c3;
8513              
8514             sub make_c3 {
8515 0 0   0 0 0 my $package = shift or die;
8516              
8517 0 0       0 return if ( grep { $_ eq $package } @made_c3 );
  0         0  
8518 0         0 push @made_c3, $package;
8519              
8520 0         0 mark_package( 'mro', 1 );
8521 0         0 mark_package($package);
8522 0   0     0 my $isa_packages = mro::get_linear_isa($package) || [];
8523 0         0 foreach my $isa (@$isa_packages) {
8524 0         0 mark_package($isa);
8525             }
8526 0 0 0     0 warn "set c3 for $package\n" if $verbose or $debug{pkg};
8527              
8528             ## from setmro.xs:
8529             # classname = ST(0);
8530             # class_stash = gv_stashsv(classname, GV_ADD);
8531             # meta = HvMROMETA(class_stash);
8532             # Perl_mro_set_mro(aTHX_ meta, ST(1));
8533              
8534 0         0 $init2->add( sprintf( 'Perl_mro_set_mro(aTHX_ HvMROMETA(%s), newSVpvs("c3"));',
8535             savestashpv($package) ) );
8536             }
8537              
8538             # global state only, unneeded for modules
8539             sub save_context {
8540             # forbid run-time extends of curpad syms, names and INC
8541 0 0   0 0 0 warn "save context:\n" if $verbose;
8542 0         0 my $warner = $SIG{__WARN__};
8543 0 0       0 save_sig($warner) if $B::C::save_sig;
8544             # honour -w and %^H
8545 0         0 $init->add( "/* honor -w */",
8546             sprintf "PL_dowarn = ( %s ) ? G_WARN_ON : G_WARN_OFF;", $^W );
8547 0 0       0 if ($^{TAINT}) {
8548             $init->add( "/* honor -Tt */",
8549             "PL_tainting = TRUE;",
8550             # -T -1 false, -t 1 true
8551 0 0       0 "PL_taint_warn = ".($^{TAINT} < 0 ? "FALSE" : "TRUE").";");
8552             }
8553              
8554 0 0       0 if ($PERL510) {
8555             # need to mark assign c3 to %main::. no need to assign the default dfs
8556 0 0 0     0 if (is_using_mro() && mro::get_mro("main") eq 'c3') {
8557 0         0 make_c3('main');
8558             }
8559             # Tie::Hash::NamedCapture is added for *+ *-, Errno for *!
8560             #no strict 'refs';
8561             #if ( defined(objsym(svref_2object(\*{'main::+'}))) or defined(objsym(svref_2object(\*{'main::-'}))) ) {
8562             # use strict 'refs';
8563             # if (!$include_package{'Tie::Hash::NamedCapture'}) {
8564             # $init->add("/* force saving of Tie::Hash::NamedCapture */");
8565             # if ($] >= 5.014) {
8566             # mark_package('Config', 1); # DynaLoader needs Config to set the EGV
8567             # walk_syms('Config');
8568             # svref_2object(\&{'Tie::Hash::NamedCapture::bootstrap'})->save;
8569             # }
8570             # mark_package('Tie::Hash::NamedCapture', 1);
8571             # } # else already included
8572             #} else {
8573             # use strict 'refs';
8574             # delete_unsaved_hashINC('Tie::Hash::NamedCapture');
8575             #}
8576 55     55   298 no strict 'refs';
  55         121  
  55         2963  
8577 0 0       0 if ( defined(objsym(svref_2object(\*{'main::!'}))) ) {
  0         0  
8578 55     55   205 use strict 'refs';
  55         90  
  55         3568  
8579 0 0       0 if (!$include_package{'Errno'}) {
8580 0         0 $init->add("/* force saving of Errno */");
8581 0         0 mark_package('Config', 1);
8582 0         0 walk_syms('Config');
8583 0         0 mark_package('Errno', 1);
8584 0         0 svref_2object(\&{'Errno::bootstrap'})->save;
  0         0  
8585             } # else already included
8586             } else {
8587 55     55   218 use strict 'refs';
  55         77  
  55         10044  
8588 0         0 delete_unsaved_hashINC('Errno');
8589             }
8590             }
8591              
8592 0         0 my ($curpad_nam, $curpad_sym);
8593             {
8594             # Record comppad sv's names, may not be static
8595 0         0 local $B::C::const_strings = 0;
  0         0  
8596 0         0 $init->add("/* curpad names */");
8597 0 0       0 warn "curpad names:\n" if $verbose;
8598 0         0 $curpad_nam = ( comppadlist->ARRAY )[0]->save('curpad_name');
8599 0 0       0 warn "curpad syms:\n" if $verbose;
8600 0         0 $init->add("/* curpad syms */");
8601 0         0 $curpad_sym = ( comppadlist->ARRAY )[1]->save('curpad_syms');
8602             }
8603 0         0 my ($inc_hv, $inc_av);
8604             {
8605 0 0       0 local $B::C::const_strings = 1 if $B::C::ro_inc;
  0         0  
8606 0 0       0 warn "\%INC and \@INC:\n" if $verbose;
8607 0         0 $init->add('/* %INC */');
8608 0         0 inc_cleanup(0);
8609 0         0 my $inc_gv = svref_2object( \*main::INC );
8610 0         0 $inc_hv = $inc_gv->HV->save('main::INC');
8611 0         0 $init->add('/* @INC */');
8612 0         0 $inc_av = $inc_gv->AV->save('main::INC');
8613             }
8614             # ensure all included @ISA's are stored (#308), and also assign c3 (#325)
8615 0         0 my @saved_isa;
8616 0         0 for my $p (sort keys %include_package) {
8617 55     55   224 no strict 'refs';
  55         81  
  55         35244  
8618 0 0 0     0 if ($include_package{$p} and exists(${$p.'::'}{ISA}) and ${$p.'::'}{ISA}) {
  0   0     0  
  0         0  
8619 0         0 push @saved_isa, $p;
8620 0         0 svref_2object( \@{$p.'::ISA'} )->save($p.'::ISA');
  0         0  
8621 0 0 0     0 if ($PERL510 and is_using_mro() && mro::get_mro($p) eq 'c3') {
      0        
8622 0         0 make_c3($p);
8623             }
8624             }
8625             }
8626 0 0 0     0 warn "Saved \@ISA for: ".join(" ",@saved_isa)."\n" if @saved_isa and ($verbose or $debug{pkg});
      0        
8627 0         0 $init->add(
8628             "GvHV(PL_incgv) = $inc_hv;",
8629             "GvAV(PL_incgv) = $inc_av;",
8630             "PL_curpad = AvARRAY($curpad_sym);",
8631             "PL_comppad = $curpad_sym;", # fixed "panic: illegal pad"
8632             "PL_stack_sp = PL_stack_base;" # reset stack (was 1++)
8633             );
8634 0 0       0 if ($] < 5.017005) {
    0          
    0          
8635 0         0 $init->add(
8636             "av_store((AV*)CvPADLIST(PL_main_cv), 0, SvREFCNT_inc_simple_NN($curpad_nam)); /* namepad */",
8637             "av_store((AV*)CvPADLIST(PL_main_cv), 1, SvREFCNT_inc_simple_NN($curpad_sym)); /* curpad */");
8638             } elsif ($] < 5.019003) {
8639 0         0 $init->add(
8640             "PadlistARRAY(CvPADLIST(PL_main_cv))[0] = PL_comppad_name = (PAD*)SvREFCNT_inc_simple_NN($curpad_nam); /* namepad */",
8641             "PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)SvREFCNT_inc_simple_NN($curpad_sym); /* curpad */");
8642             } elsif ($] < 5.022) {
8643 0         0 $init->add(
8644             "PadlistARRAY(CvPADLIST(PL_main_cv))[0] = PL_comppad_name = (PAD*)SvREFCNT_inc_simple_NN($curpad_nam); /* namepad */",
8645             "PadnamelistMAXNAMED(PL_comppad_name) = AvFILL($curpad_nam);",
8646             "PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)SvREFCNT_inc_simple_NN($curpad_sym); /* curpad */");
8647             } else {
8648 0         0 $init->add(
8649             "PadlistNAMES(CvPADLIST(PL_main_cv)) = PL_comppad_name = $curpad_nam; /* namepad */",
8650             "PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)$curpad_sym; /* curpad */");
8651             }
8652 0 0       0 if ($] < 5.017) {
8653 0         0 my $amagic_generate = B::amagic_generation();
8654 0 0       0 warn "amagic_generation = $amagic_generate\n" if $verbose;
8655 0         0 $init->add("PL_amagic_generation = $amagic_generate;");
8656             };
8657             }
8658              
8659             sub descend_marked_unused {
8660             #if ($B::C::walkall) {
8661             # for my $pack (keys %all_bc_deps) {
8662             # mark_unused($pack, 0) if !exists $include_package{$pack} and !skip_pkg($pack);
8663             # }
8664             #}
8665 0     0 0 0 foreach my $pack ( sort keys %INC ) {
8666 0         0 my $p = packname_inc($pack);
8667 0 0 0     0 mark_package($p) if !skip_pkg($p) and !$all_bc_deps{$p} and $pack !~ /(autosplit\.ix|\.al)$/;
      0        
8668             }
8669 0 0 0     0 if ($debug{pkg} and $verbose) {
8670 0         0 warn "\%include_package: ".join(" ",grep{$include_package{$_}} sort keys %include_package)."\n";
  0         0  
8671 0         0 warn "\%skip_package: ".join(" ",sort keys %skip_package)."\n";
8672             }
8673 0         0 foreach my $pack ( sort keys %include_package ) {
8674 0 0       0 mark_package($pack) unless skip_pkg($pack);
8675             }
8676             warn "descend_marked_unused: "
8677 0 0       0 .join(" ",sort keys %include_package)."\n" if $debug{pkg};
8678             }
8679              
8680             sub save_main {
8681              
8682 0 0   0 0 0 warn "Starting compile\n" if $verbose;
8683 0 0       0 warn "Walking tree\n" if $verbose;
8684 0         0 %Exporter::Cache = (); # avoid B::C and B symbols being stored
8685 0 0       0 _delete_macros_vendor_undefined() if $PERL512;
8686 0         0 set_curcv B::main_cv;
8687 0         0 seek( STDOUT, 0, 0 ); #exclude print statements in BEGIN{} into output
8688 0 0       0 binmode( STDOUT, ':utf8' ) unless $PERL56;
8689            
8690 0 0       0 $verbose
8691             ? walkoptree_slow( main_root, "save" )
8692             : walkoptree( main_root, "save" );
8693 0         0 save_main_rest();
8694             }
8695              
8696             sub _delete_macros_vendor_undefined {
8697 0     0   0 foreach my $class (qw(POSIX IO Fcntl Socket Exporter Errno)) {
8698 55     55   265 no strict 'refs';
  55         78  
  55         1397  
8699 55     55   187 no strict 'subs';
  55         80  
  55         1457  
8700 55     55   222 no warnings 'uninitialized';
  55         66  
  55         139367  
8701 0         0 my $symtab = $class . '::';
8702 0         0 for my $symbol ( sort keys %$symtab ) {
8703 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)};
8704 0 0       0 next if ref $symtab->{$symbol};
8705 0         0 local $@;
8706 0         0 my $code = "$class\:\:$symbol();";
8707 0         0 eval $code;
8708 0 0       0 if ( $@ =~ m{vendor has not defined} ) {
8709 0         0 delete $symtab->{$symbol};
8710 0         0 next;
8711             }
8712             }
8713             }
8714 0         0 return 1;
8715             }
8716              
8717             sub fixup_ppaddr {
8718             # init op addrs must be the last action, otherwise
8719             # some ops might not be initialized
8720             # but it needs to happen before CALLREGCOMP, as a /i calls a compiled utf8::SWASHNEW
8721 0 0   0 0 0 if ($B::C::optimize_ppaddr) {
8722 0         0 foreach my $i (@op_sections) {
8723 0         0 my $section = $$i;
8724 0         0 my $num = $section->index;
8725 0 0       0 next unless $num >= 0;
8726 0         0 init_op_addr( $section->name, $num + 1 );
8727             }
8728             }
8729             }
8730              
8731             # save %SIG ( in case it was set in a BEGIN block )
8732             sub save_sig {
8733             # local $SIG{__WARN__} = shift;
8734 0     0 0 0 $init->no_split;
8735 0         0 my @save_sig;
8736 0         0 foreach my $k ( sort keys %SIG ) {
8737 0 0       0 next unless ref $SIG{$k};
8738 0         0 my $cvref = svref_2object( \$SIG{$k} );
8739 0 0 0     0 next if ref($cvref) eq 'B::CV' and $cvref->FILE =~ m|B/C\.pm$|; # ignore B::C SIG warn handler
8740 0         0 push @save_sig, [$k, $cvref];
8741             }
8742 0 0       0 unless (@save_sig) {
8743 0 0       0 $init->add( "/* no %SIG in BEGIN block */" ) if $verbose;
8744 0 0       0 warn "no %SIG in BEGIN block\n" if $verbose;
8745 0         0 return;
8746             }
8747 0 0       0 $init->add( "/* save %SIG */" ) if $verbose;
8748 0 0       0 warn "save %SIG\n" if $verbose;
8749 0         0 $init->add( "{", "\tHV* hv = get_hvs(\"main::SIG\", GV_ADD);" );
8750 0         0 foreach my $x ( @save_sig ) {
8751 0         0 my ($k, $cvref) = @$x;
8752 0         0 my $sv = $cvref->save;
8753 0         0 my ($cstring, $cur, $utf8) = strlen_flags($k);
8754 0         0 $init->add( '{', sprintf "\t".'SV* sv = (SV*)%s;', $sv );
8755 0         0 $init->add( sprintf("\thv_store(hv, %s, %u, %s, %d);",
8756             $cstring, $cur, 'sv', 0 ) );
8757 0         0 $init->add( "\t".'mg_set(sv);', '}' );
8758             }
8759 0         0 $init->add('}');
8760 0         0 $init->split;
8761             }
8762              
8763             sub force_saving_xsloader {
8764 0     0 0 0 mark_package("XSLoader", 1);
8765             # mark_package("DynaLoader", 1);
8766 0 0       0 if ($] < 5.015003) {
    0          
8767 0         0 $init->add("/* force saving of XSLoader::load */");
8768 0         0 eval { XSLoader::load; };
  0         0  
8769             # does this really save the whole packages?
8770 0         0 $dumped_package{XSLoader} = 1;
8771 0         0 svref_2object( \&XSLoader::load )->save;
8772             } elsif ($CPERL51) {
8773 0         0 $init->add("/* XSLoader::load_file already builtin into cperl */");
8774 0         0 $dumped_package{XSLoader} = 1;
8775 0         0 $dumped_package{DynaLoader} = 1;
8776 0         0 add_hashINC("XSLoader"); # builtin
8777             } else {
8778 0         0 $init->add("/* custom XSLoader::load_file */");
8779             # does this really save the whole packages?
8780 0         0 $dumped_package{DynaLoader} = 1;
8781 0         0 svref_2object( \&XSLoader::load_file )->save;
8782 0         0 svref_2object( \&DynaLoader::dl_load_flags )->save; # not saved as XSUB constant?
8783             }
8784 0 0       0 add_hashINC("XSLoader") if $] < 5.015003;
8785 0         0 add_hashINC("DynaLoader");
8786 0         0 $use_xsloader = 0; # do not load again
8787             }
8788              
8789             sub save_main_rest {
8790             # this is mainly for the test suite
8791             # local $SIG{__WARN__} = sub { print STDERR @_ } unless $debug{runtime};
8792              
8793             warn "done main optree, walking symtable for extras\n"
8794 0 0 0 0 0 0 if $verbose or $debug{cv};
8795 0         0 $init->add("");
8796 0         0 $init->add("/* done main optree, extra subs which might be unused */");
8797 0         0 save_unused_subs();
8798 0         0 $init->add("/* done extras */");
8799              
8800             # startpoints: XXX TODO push BEGIN/END blocks to modules code.
8801 0 0       0 warn "Writing init_av\n" if $debug{av};
8802 0         0 my $init_av = init_av->save('INIT');
8803 0         0 my $end_av;
8804             {
8805             # >=5.10 need to defer nullifying of all vars in END, not only new ones.
8806 0         0 local ($B::C::pv_copy_on_grow, $B::C::const_strings);
  0         0  
8807 0         0 $in_endav = 1;
8808 0 0       0 warn "Writing end_av\n" if $debug{av};
8809 0         0 $init->add("/* END block */");
8810 0         0 $end_av = end_av->save('END');
8811 0         0 $in_endav = 0;
8812             }
8813 0 0       0 if ( !defined($module) ) {
8814             $init->add(
8815             "/* startpoints */",
8816 0         0 sprintf( "PL_main_root = s\\_%x;", ${ main_root() } ),
8817 0         0 sprintf( "PL_main_start = s\\_%x;", ${ main_start() } ),
  0         0  
8818             );
8819 0 0       0 $init->add(index($init_av,'(AV*)')>=0
8820             ? "PL_initav = $init_av;"
8821             : "PL_initav = (AV*)$init_av;");
8822 0 0       0 $init->add(index($end_av,'(AV*)')>=0
8823             ? "PL_endav = $end_av;"
8824             : "PL_endav = (AV*)$end_av;");
8825             }
8826 0 0       0 save_context() unless defined($module);
8827             # warn "use_xsloader=$use_xsloader\n" if $verbose;
8828             # If XSLoader was forced later, e.g. in curpad, INIT or END block
8829 0 0       0 force_saving_xsloader() if $use_xsloader;
8830              
8831 0 0       0 return if $check;
8832 0 0       0 warn "Writing output\n" if $verbose;
8833 0         0 output_boilerplate();
8834              
8835             # add static modules like " Win32CORE"
8836 0         0 foreach my $stashname ( split /\s+/, $Config{static_ext} ) {
8837 0 0       0 next if $stashname =~ /^\s*$/; # often a leading space
8838 0         0 $static_ext{$stashname}++;
8839 0         0 my $stashxsub = $stashname;
8840 0         0 $stashxsub =~ s/::/__/g;
8841 0         0 print "EXTERN_C void boot_$stashxsub (pTHX_ CV* cv);\n";
8842             }
8843 0         0 print "\n";
8844 0   0     0 output_all($init_name || "perl_init");
8845 0         0 print "\n";
8846 0         0 output_main_rest();
8847              
8848 0 0       0 if ( defined($module) ) {
8849 0 0       0 my $cmodule = $module ? $module : "main";
8850 0         0 $cmodule =~ s/::/__/g;
8851              
8852 0         0 my $start = "op_list[0]";
8853 0 0       0 warn "curpad syms:\n" if $verbose;
8854 0         0 $init->add("/* curpad syms */");
8855 0         0 my $curpad_sym = ( comppadlist->ARRAY )[1]->save;
8856              
8857 0         0 print <<"EOT";
8858              
8859             #include "XSUB.h"
8860             XS(boot_$cmodule)
8861             {
8862             dXSARGS;
8863             perl_init();
8864             ENTER;
8865             SAVETMPS;
8866             SAVEVPTR(PL_curpad);
8867             SAVEVPTR(PL_op);
8868             dl_init(aTHX);
8869             PL_curpad = AvARRAY($curpad_sym);
8870             PL_comppad = $curpad_sym;
8871             PL_op = $start;
8872             perl_run( aTHX ); /* Perl_runops_standard(aTHX); */
8873             FREETMPS;
8874             LEAVE;
8875             ST(0) = &PL_sv_yes;
8876             XSRETURN(1);
8877             }
8878             EOT
8879              
8880             } else {
8881 0         0 output_main();
8882             }
8883             }
8884              
8885             sub init_sections {
8886 0     0 0 0 my @sections = (
8887             decl => \$decl,
8888             init0 => \$init0,
8889             free => \$free,
8890             sym => \$symsect,
8891             hek => \$heksect,
8892             binop => \$binopsect,
8893             condop => \$condopsect,
8894             cop => \$copsect,
8895             padop => \$padopsect,
8896             listop => \$listopsect,
8897             logop => \$logopsect,
8898             loop => \$loopsect,
8899             op => \$opsect,
8900             pmop => \$pmopsect,
8901             pvop => \$pvopsect,
8902             svop => \$svopsect,
8903             unop => \$unopsect,
8904             unopaux => \$unopauxsect,
8905             methop => \$methopsect,
8906             sv => \$svsect,
8907             xpv => \$xpvsect,
8908             xpvav => \$xpvavsect,
8909             xpvhv => \$xpvhvsect,
8910             xpvcv => \$xpvcvsect,
8911             xpviv => \$xpvivsect,
8912             xpvuv => \$xpvuvsect,
8913             xpvnv => \$xpvnvsect,
8914             xpvmg => \$xpvmgsect,
8915             xpvlv => \$xpvlvsect,
8916             xrv => \$xrvsect,
8917             xpvbm => \$xpvbmsect,
8918             xpvio => \$xpviosect,
8919             padlist => \$padlistsect,
8920             padnamelist => \$padnlsect,
8921             padname => \$padnamesect,
8922             );
8923 0 0       0 if ($PERL522) {
8924 0         0 pop @sections;
8925             }
8926 0         0 my ( $name, $sectref );
8927 0         0 while ( ( $name, $sectref ) = splice( @sections, 0, 2 ) ) {
8928 0         0 $$sectref = new B::C::Section $name, \%symtable, 0;
8929             }
8930 0 0       0 if ($PERL522) {
8931 0         0 for my $size (@padnamesect_sizes) {
8932 0         0 my $name = "padname_$size";
8933 0         0 $padnamesect{$size} = new B::C::Section $name, \%symtable, 0;
8934             }
8935             }
8936 0         0 $init = new B::C::InitSection 'init', \%symtable, 0;
8937 0         0 $init1 = new B::C::InitSection 'init1', \%symtable, 0;
8938 0         0 $init2 = new B::C::InitSection 'init2', \%symtable, 0;
8939 0         0 %savINC = %curINC = %INC;
8940             }
8941              
8942             sub mark_unused {
8943 0     0 0 0 my ( $pkg, $val ) = @_;
8944 0         0 $include_package{$pkg} = $val;
8945             }
8946              
8947             sub mark_skip {
8948 15     15 0 68 for (@_) {
8949 225         317 delete_unsaved_hashINC($_);
8950             # $include_package{$_} = 0;
8951 225 50       444 $skip_package{$_} = 1 unless $include_package{$_};
8952             }
8953             }
8954              
8955             sub compile {
8956 0     0 0   my @options = @_;
8957             # Allow debugging in CHECK blocks without Od
8958 0 0         $DB::single = 1 if defined &DB::DB;
8959 0           my ( $option, $opt, $arg );
8960 0           my @eval_at_startup;
8961 0           $B::C::can_delete_pkg = 1;
8962 0           $B::C::save_sig = 1;
8963 0           $B::C::destruct = 1;
8964 0           $B::C::stash = 0;
8965 0           $B::C::cow = 0;
8966 0 0         $B::C::fold = 1 if $] >= 5.013009; # always include utf8::Cased tables
8967 0 0         $B::C::warnings = 1 if $] >= 5.013005; # always include Carp warnings categories and B
8968 0 0 0       $B::C::optimize_warn_sv = 1 if $^O ne 'MSWin32' or $Config{cc} !~ m/^cl/i;
8969 0 0         $B::C::dyn_padlist = 1 if $] >= 5.017; # default is dynamic and safe, disable with -O4
8970 0           $B::C::walkall = 1;
8971              
8972 0           mark_skip qw(B::C B::C::Config B::CC B::Asmdata B::FAKEOP O
8973             B::Pseudoreg B::Shadow B::C::InitSection);
8974             #mark_skip('DB', 'Term::ReadLine') if defined &DB::DB;
8975              
8976             OPTION:
8977 0           while ( $option = shift @options ) {
8978 0 0         if ( $option =~ /^-(.)(.*)/ ) {
8979 0           $opt = $1;
8980 0           $arg = $2;
8981             }
8982             else {
8983 0           unshift @options, $option;
8984 0           last OPTION;
8985             }
8986 0 0 0       if ( $opt eq "-" && $arg eq "-" ) {
8987 0           shift @options;
8988 0           last OPTION;
8989             }
8990 0 0         if ( $opt eq "w" ) {
8991 0           $warn_undefined_syms = 1;
8992             }
8993 0 0 0       if ( $opt eq "c" ) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
8994 0           $check = 1;
8995             }
8996             elsif ( $opt eq "D" ) {
8997 0   0       $arg ||= shift @options;
8998 0 0         if ($arg eq 'full') {
    0          
8999 0           $arg = 'OcAHCMGSPpsWF';
9000 0           $all_bc_deps{'B::Flags'}++;
9001             }
9002             elsif ($arg eq 'ufull') {
9003 0           $arg = 'uOcAHCMGSPpsWF';
9004 0           $all_bc_deps{'B::Flags'}++;
9005             }
9006 0           foreach my $arg ( split( //, $arg ) ) {
9007 0 0         if (exists $debug_map{$arg}) {
    0          
    0          
    0          
9008 0           $debug{ $debug_map{$arg} }++;
9009             }
9010             elsif ( $arg eq "o" ) {
9011 0           $verbose++;
9012 0           B->debug(1);
9013             }
9014             elsif ( $arg eq "F" ) {
9015 0 0 0       $debug{flags}++ if $] > 5.008 and eval "require B::Flags;";
9016 0           $all_bc_deps{'B::Flags'}++;
9017             # $debug{flags}++ if require B::Flags;
9018             }
9019             elsif ( $arg eq "r" ) {
9020 0           $debug{runtime}++;
9021             $SIG{__WARN__} = sub {
9022 0     0     warn @_;
9023 0           my $s = join(" ", @_);
9024 0           chomp $s;
9025 0 0         $init->add("/* ".$s." */") if $init;
9026 0           };
9027             }
9028             else {
9029 0           warn "ignoring unknown debug option: $arg\n";
9030             }
9031             }
9032             }
9033             elsif ( $opt eq "o" ) {
9034 0   0       $arg ||= shift @options;
9035 0           $outfile = $arg;
9036 0 0         if ($check) {
9037 0           warn "Warning: -o argument ignored with -c\n";
9038             } else {
9039 0 0         open( STDOUT, ">", $arg ) or return "$arg: $!\n";
9040             }
9041             }
9042             elsif ( $opt eq "s" and $arg eq "taticxs" ) {
9043 0 0         $outfile = "perlcc" unless $outfile;
9044 0           $staticxs = 1;
9045             }
9046             elsif ( $opt eq "n" ) {
9047 0   0       $arg ||= shift @options;
9048 0           $init_name = $arg;
9049             }
9050             elsif ( $opt eq "m" ) {
9051             # $arg ||= shift @options;
9052 0           $module = $arg;
9053 0           mark_unused( $arg, 1 );
9054             }
9055             elsif ( $opt eq "v" ) {
9056 0           $verbose = 1;
9057             }
9058             elsif ( $opt eq "u" ) {
9059 0   0       $arg ||= shift @options;
9060 0 0         if ($arg =~ /\.p[lm]$/) {
9061 0           eval "require(\"$arg\");"; # path as string
9062             } else {
9063 0           eval "require $arg;"; # package as bareword with ::
9064             }
9065 0           mark_unused( $arg, 1 );
9066             }
9067             elsif ( $opt eq "U" ) {
9068 0   0       $arg ||= shift @options;
9069 0           mark_skip( $arg );
9070             }
9071             elsif ( $opt eq "f" ) {
9072 0   0       $arg ||= shift @options;
9073 0           $arg =~ m/(no-)?(.*)/;
9074 0   0       my $no = defined($1) && $1 eq 'no-';
9075 0 0         $arg = $no ? $2 : $arg;
9076 0 0         if ( exists $option_map{$arg} ) {
9077 0           ${ $option_map{$arg} } = !$no;
  0            
9078             }
9079             else {
9080 0           die "Invalid optimization '$arg'";
9081             }
9082             }
9083             elsif ( $opt eq "O" ) {
9084 0 0         $arg = 1 if $arg eq "";
9085 0           my @opt;
9086 0           foreach my $i ( 1 .. $arg ) {
9087 0           push @opt, @{ $optimization_map{$i} }
9088 0 0         if exists $optimization_map{$i};
9089             }
9090 0           unshift @options, @opt;
9091 0 0         warn "options : ".(join " ",@opt)."\n" if $verbose;
9092             }
9093             elsif ( $opt eq "e" ) {
9094 0           push @eval_at_startup, $arg;
9095             }
9096             elsif ( $opt eq "l" ) {
9097 0           $max_string_len = $arg;
9098             }
9099             }
9100 0 0 0       if (!$B::C::Config::have_independent_comalloc) {
    0          
9101 0 0         if ($B::C::av_init2) {
    0          
9102 0           $B::C::av_init = 1;
9103 0           $B::C::av_init2 = 0;
9104             } elsif ($B::C::av_init) {
9105 0           $B::C::av_init2 = 0;
9106             }
9107             } elsif ($B::C::av_init2 and $B::C::av_init) {
9108 0           $B::C::av_init = 0;
9109             }
9110 0 0 0       $B::C::save_data_fh = 1 if $] >= 5.008 and (($] < 5.009004) or $MULTI);
      0        
9111 0 0 0       $B::C::destruct = 1 if $] < 5.008 or $^O eq 'MSWin32'; # skip -ffast-destruct there
9112              
9113 0           init_sections();
9114 0           foreach my $i (@eval_at_startup) {
9115 0           $init2->add_eval($i);
9116             }
9117 0 0         if (@options) { # modules or main?
9118             return sub {
9119 0     0     my $objname;
9120 0           foreach $objname (@options) {
9121 0           eval "save_object(\\$objname)";
9122             }
9123 0   0       output_all($init_name || "init_module");
9124             }
9125 0           }
9126             else {
9127 0     0     return sub { save_main() };
  0            
9128             }
9129             }
9130              
9131             1;
9132              
9133             __END__