File Coverage

blib/lib/B/C.pm
Criterion Covered Total %
statement 187 4467 4.1
branch 15 3666 0.4
condition 5 1932 0.2
subroutine 56 237 23.6
pod 0 97 0.0
total 263 10399 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   8757481 use strict;
  55         161  
  55         10245  
14              
15             our $VERSION = '1.55_04';
16             our (%debug, $check, %Config);
17             BEGIN {
18 55     55   895 require B::C::Config;
19 55         398 *Config = \%B::C::Config::Config;
20 55 50 33     758 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       3501 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   419 use strict;
  55         171  
  55         64977  
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   506 use strict;
  55         813  
  55         57946  
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       0 $j =~ s{(s\\_[0-9a-f]+)}
  0         0  
247 0         0 { exists($sym->{$1}) ? $sym->{$1} : $default; }ge;
248             print $fh "\t$j\n";
249 0 0       0 }
  0         0  
250             if (@{ $section->[-1]{evals} }) {
251 0 0       0 # We need to output evals after dl_init, in init2
252 0         0 if ($section->name ne 'init2') {
253             die "Invalid section ".$section->name."->add_eval, use init2";
254 0         0 } else {
  0         0  
255 0         0 foreach my $s ( @{ $section->[-1]{evals} } ) {
256             print $fh "\teval_pv(\"$s\",1);\n";
257             }
258             }
259 0         0 }
260             print $fh "}\n";
261 0         0  
262 0         0 $section->SUPER::add("${init_name}_${name}(aTHX);");
263             ++$name;
264             }
265 0         0  
266             print $fh <<"EOT";
267             PERL_STATIC_INLINE int ${init_name}(pTHX)
268             {
269 0 0       0 EOT
270 0         0 if ($section->name eq 'init') {
271             print $fh "\tperl_init0(aTHX);\n";
272 0         0 }
273 0         0 $section->SUPER::output( $fh, $format );
274             print $fh "\treturn 0;\n}\n";
275             }
276              
277 55     55   509 package B::C;
  55         159  
  55         1530  
278 55     55   956 use strict;
  55         154  
  55         1118  
279 55     55   32686 use Exporter ();
  55         82219  
  55         8718  
280             use Errno (); #needed since 5.14
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 55         37843 use B
300             qw(minus_c sv_undef walkoptree walkoptree_slow main_root main_start peekop
301             cchar svref_2object compile_stats comppadlist hash
302 55     55   518 threadsv_names main_cv init_av end_av opnumber cstring
  55         141  
303             HEf_SVKEY SVf_POK SVp_POK SVf_ROK SVf_IOK SVf_NOK SVf_IVisUV SVf_READONLY);
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 0 0 0 0   0 sub _load_mro {
311 0     0   0 eval q/require mro; 1/ or die if $] >= 5.010;
312             *_load_mro = sub {};
313             }
314              
315 0 0   0 0 0 sub is_using_mro {
316             return keys %{mro::} > 10 ? 1 : 0;
317             }
318              
319 55 50   55   680 BEGIN {
320 55         8312 if ($] >= 5.008) {
321 55         3294 @B::NV::ISA = 'B::IV'; # add IVX to nv. This fixes test 23 for Perl 5.8
322             B->import(qw(regex_padav SVp_NOK SVp_IOK CVf_CONST CVf_ANON
323 55         4748 SVf_FAKE)); # both unsupported for 5.6
324             eval q[
325             sub SVs_OBJECT() {0x00100000}
326             sub SVf_AMAGIC() {0x10000000}
327             ];
328 0         0 } else {
329             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 0         0 ];
339             @B::PVMG::ISA = qw(B::PVNV B::RV);
340 0     0 0 0 }
341 55 50       398 sub SVf_UTF8 { 0x20000000 }
342 55         1649 if ($] >= 5.008001) {
343             B->import(qw(SVt_PVGV CVf_WEAKOUTSIDE)); # added with 5.8.1
344 0         0 } else {
345 0         0 eval q[sub SVt_PVGV() {13}];
346             eval q[sub CVf_WEAKOUTSIDE() { 0x0 }]; # unused
347 55 50       286 }
348             if ($] >= 5.010) {
349             #require mro; # mro->import();
350 0     0 0 0 # not exported:
351 55         3109 sub SVf_OOK { 0x02000000 }
352             eval q[sub SVs_GMG() { 0x00200000 }
353 55 50       354 sub SVs_SMG() { 0x00400000 }];
    0          
    0          
354 55         1534 if ($] >= 5.018) {
355 55         2295 B->import(qw(PMf_EVAL RXf_EVAL_SEEN));
356             eval q[sub PMf_ONCE(){ 0x10000 }]; # PMf_ONCE also not exported
357 0         0 } elsif ($] >= 5.014) {
358             eval q[sub PMf_ONCE(){ 0x8000 }];
359 0         0 } elsif ($] >= 5.012) {
360             eval q[sub PMf_ONCE(){ 0x0080 }];
361 0         0 } else { # 5.10. not used with <= 5.8
362             eval q[sub PMf_ONCE(){ 0x0002 }];
363 55 50       364 }
364 55         1570 if ($] > 5.021006) {
365             B->import(qw(SVf_PROTECT CVf_ANONCONST SVs_PADSTALE));
366 0         0 } else {
367             eval q[sub SVf_PROTECT() { 0x0 }
368             sub CVf_ANONCONST(){ 0x0 }
369             sub SVs_PADSTALE() { 0x0 }
370             ]; # unused
371             }
372 0         0 } else {
373             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 55 50       286 }
380 0         0 if ($] < 5.018) {
381             eval q[sub RXf_EVAL_SEEN() { 0x0 }
382             sub PMf_EVAL() { 0x0 }
383             sub SVf_IsCOW() { 0x0 }
384             ]; # unused
385             } else {
386 55         1603 # 5.18
387             B->import(qw(SVf_IsCOW));
388 55         972 #if (exists ${B::}{PADNAME::}) {
389             @B::PADNAME::ISA = qw(B::PV);
390             #}
391 55         907 #if (exists ${B::}{PADLIST::}) {
392             @B::PADLIST::ISA = qw(B::AV);
393             #}
394 55 50       373 #if (exists ${B::}{PADNAMELIST::}) {
395 55         425 if ($] > 5.021005) { # 5.22
396 55         763 @B::PADNAME::ISA = ();
397             @B::PADNAMELIST::ISA = qw(B::AV);
398 55 50 33     2054 }
399 0         0 if ($Config{usecperl} and $] >= 5.022002) {
400             eval q[sub SVpav_REAL () { 0x40000000 }
401             sub SVpav_REIFY (){ 0x80000000 }
402             ];
403             }
404             }
405 55     55   34108 }
  55         330  
  55         8711  
406             use B::Asmdata qw(@specialsv_name);
407 55     55   52866  
  55         602389  
  55         505  
408             use FileHandle;
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             # skipping here: oFr which need extra logic
508             our %debug_map = (
509             'O' => 'op',
510             'A' => 'av',
511             'H' => 'hv',
512             'C' => 'cv',
513             'M' => 'mg',
514             'R' => 'rx',
515             'G' => 'gv',
516             'S' => 'sv',
517             'P' => 'pv',
518             'W' => 'walk',
519             'c' => 'cops',
520             's' => 'sub',
521             'p' => 'pkg',
522             # 'm' => 'meth',
523             'u' => 'unused',
524             );
525              
526             my @xpvav_sizes;
527             my ($max_string_len, $in_endav);
528             my %static_core_pkg; # = map {$_ => 1} static_core_packages();
529              
530             my $MULTI = $Config{usemultiplicity};
531             my $ITHREADS = $Config{useithreads};
532             my $DEBUGGING = ($Config{ccflags} =~ m/-DDEBUGGING/);
533             my $DEBUG_LEAKING_SCALARS = $Config{ccflags} =~ m/-DDEBUG_LEAKING_SCALARS/;
534             my $CPERL56 = ( $Config{usecperl} and $] >= 5.025003 ); #sibparent, VALID
535             my $CPERL55 = ( $Config{usecperl} and $] >= 5.025001 ); #HVMAX_T, RITER_T, ...
536             my $CPERL52 = ( $Config{usecperl} and $] >= 5.022002 ); #sv_objcount, AvSTATIC, sigs
537             my $CPERL51 = ( $Config{usecperl} );
538             my $PERL5257 = ( $CPERL56 or $] >= 5.025007 ); # VALID/TAIL, sibparent, ...
539             my $PERL524 = ( $] >= 5.023005 ); #xpviv sharing assertion
540             my $PERL522 = ( $] >= 5.021006 ); #PADNAMELIST, IsCOW, padname_with_str, compflags
541             my $PERL518 = ( $] >= 5.017010 );
542             my $PERL514 = ( $] >= 5.013002 );
543             my $PERL512 = ( $] >= 5.011 );
544             my $PERL510 = ( $] >= 5.009005 );
545             my $PERL56 = ( $] < 5.008001 ); # yes. 5.8.0 is a 5.6.x
546             #my $C99 = $Config{d_c99_variadic_macros}; # http://docs.sun.com/source/819-3688/c99.app.html#pgfId-1003962
547             my $MAD = $Config{mad};
548             my $MYMALLOC = $Config{usemymalloc} eq 'define';
549             my $HAVE_DLFCN_DLOPEN = $Config{i_dlfcn} && $Config{d_dlopen};
550             # %Lu is not supported on older 32bit systems
551 0 0   0 0 0 my $u32fmt = $Config{ivsize} == 4 ? "%lu" : "%u";
552             sub IS_MSVC () { $^O eq 'MSWin32' and $Config{cc} eq 'cl' }
553             my $have_sibparent = ($PERL5257 or $Config{ccflags} =~ /-DPERL_OP_PARENT/) ? 1 : 0;
554              
555             my @threadsv_names;
556              
557 55     55   77299 BEGIN {
558             @threadsv_names = threadsv_names();
559 55 50   0 0 108779 # This the Carp free workaround for DynaLoader::bootstrap
  0         0  
560             eval 'sub DynaLoader::croak {die @_}' unless $CPERL51;
561             }
562              
563             # needed for init2 remap and Dynamic annotation
564 0 0   0 0 0 sub dl_module_to_sofile {
565             my $module = shift
566 0 0       0 or die 'dl_module_to_sofile($module, $path) missing module name';
567             my $modlibname = shift
568 0         0 or die 'dl_module_to_sofile($module, $path): missing module path for '.$module;
569 0         0 my @modparts = split(/::/,$module);
570 0         0 my $modfname = $modparts[-1];
571 0         0 my $modpname = join('/',@modparts);
572 0         0 my $c = @modparts;
573 0 0       0 $modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename
574 0         0 die "dl_module_to_sofile: empty modlibname" unless $modlibname;
575 0         0 my $sofile = "$modlibname/auto/$modpname/$modfname.".$Config{dlext};
576             return $sofile;
577             }
578              
579             # 5.15.3 workaround [perl #101336], without .bs support
580             # XSLoader::load_file($module, $modlibname, ...)
581 0 0 0 0 0 0 my $dlext = $Config{dlext};
  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             eval q|
583             sub XSLoader::load_file {
584             #package DynaLoader;
585             my $module = shift or die "missing module name";
586             my $modlibname = shift or die "missing module filepath";
587             print STDOUT "XSLoader::load_file(\"$module\", \"$modlibname\" @_)\n"
588             if ${DynaLoader::dl_debug};
589              
590             push @_, $module;
591             # works with static linking too
592             my $boots = "$module\::bootstrap";
593             goto &$boots if defined &$boots;
594              
595             my @modparts = split(/::/,$module); # crashes threaded, issue 100
596             my $modfname = $modparts[-1];
597             my $modpname = join('/',@modparts);
598             my $c = @modparts;
599             $modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename
600             die "missing module filepath" unless $modlibname;
601             my $file = "$modlibname/auto/$modpname/$modfname."|.qq(."$dlext").q|;
602              
603             # skip the .bs "bullshit" part, needed for some old solaris ages ago
604              
605             print STDOUT "goto DynaLoader::bootstrap_inherit\n"
606             if ${DynaLoader::dl_debug} and not -f $file;
607             goto \&DynaLoader::bootstrap_inherit if not -f $file;
608             my $modxsname = $module;
609             $modxsname =~ s/\W/_/g;
610             my $bootname = "boot_".$modxsname;
611             @DynaLoader::dl_require_symbols = ($bootname);
612              
613             my $boot_symbol_ref;
614             if ($boot_symbol_ref = DynaLoader::dl_find_symbol(0, $bootname)) {
615             print STDOUT "dl_find_symbol($bootname) ok => goto boot\n"
616             if ${DynaLoader::dl_debug};
617             goto boot; #extension library has already been loaded, e.g. darwin
618             }
619             # Many dynamic extension loading problems will appear to come from
620             # this section of code: XYZ failed at line 123 of DynaLoader.pm.
621             # Often these errors are actually occurring in the initialisation
622             # C code of the extension XS file. Perl reports the error as being
623             # in this perl code simply because this was the last perl code
624             # it executed.
625              
626             my $libref = DynaLoader::dl_load_file($file, 0) or do {
627             die("Can't load '$file' for module $module: " . DynaLoader::dl_error());
628             };
629             push(@DynaLoader::dl_librefs,$libref); # record loaded object
630              
631             my @unresolved = DynaLoader::dl_undef_symbols();
632             if (@unresolved) {
633             die("Undefined symbols present after loading $file: @unresolved\n");
634             }
635              
636             $boot_symbol_ref = DynaLoader::dl_find_symbol($libref, $bootname) or do {
637             die("Can't find '$bootname' symbol in $file\n");
638             };
639             print STDOUT "dl_find_symbol($libref, $bootname) ok => goto boot\n"
640             if ${DynaLoader::dl_debug};
641             push(@DynaLoader::dl_modules, $module); # record loaded module
642              
643             boot:
644             my $xs = DynaLoader::dl_install_xsub($boots, $boot_symbol_ref, $file);
645             print STDOUT "dl_install_xsub($boots, $boot_symbol_ref, $file)\n"
646             if ${DynaLoader::dl_debug};
647             # See comment block above
648             push(@DynaLoader::dl_shared_objects, $file); # record files loaded
649             return &$xs(@_);
650             }
651             | if $] >= 5.015003 and !$CPERL51;
652             # Note: cperl uses a different API: the 2nd arg is the sofile directly
653              
654             # Code sections
655             my (
656             $init, $decl, $symsect, $binopsect, $condopsect,
657             $copsect, $padopsect, $listopsect, $logopsect, $loopsect,
658             $opsect, $pmopsect, $pvopsect, $svopsect, $unopsect,
659             $methopsect, $unopauxsect,
660             $svsect, $xpvsect, $xpvavsect, $xpvhvsect, $xpvcvsect,
661             $xpvivsect, $xpvuvsect, $xpvnvsect, $xpvmgsect, $xpvlvsect,
662             $xrvsect, $xpvbmsect, $xpviosect, $heksect, $free,
663             $padlistsect, $padnamesect, $padnlsect, $init0, $init1, $init2
664             );
665             my (%padnamesect, %avcowsect, %avcogsect);
666             my @padnamesect_sizes = (8, 16, 24, 32, 40, 48, 56, 64);
667              
668             my @op_sections =
669             \(
670             $binopsect, $condopsect, $copsect, $padopsect,
671             $listopsect, $logopsect, $loopsect, $opsect,
672             $pmopsect, $pvopsect, $svopsect, $unopsect,
673             $methopsect, $unopauxsect
674             );
675             # push @op_sections, ($resect) if $PERL512;
676             sub walk_and_save_optree;
677 14     14 0 164271 my $saveoptree_callback = \&walk_and_save_optree;
678 0     0 0 0 sub set_callback { $saveoptree_callback = shift }
679             sub saveoptree { &$saveoptree_callback(@_) }
680 0 0   0 0 0 sub save_main_rest;
  0         0  
  0         0  
681 0 0   0 0 0 sub verbose { if (@_) { $verbose = shift; } else { $verbose; } }
  0         0  
  0         0  
682             sub module { if (@_) { $module = shift; } else { $module; } }
683              
684 0     0 0 0 sub walk_and_save_optree {
685 0 0       0 my ( $name, $root, $start ) = @_;
686             if ($root) {
687             # B.xs: walkoptree does more, reifying refs. rebless or recreating it.
688 0 0       0 # TODO: add walkoptree_debug support.
689             $verbose ? walkoptree_slow( $root, "save" ) : walkoptree( $root, "save" );
690 0         0 }
691             return objsym($start);
692             }
693              
694             # Look this up here so we can do just a number compare
695             # rather than looking up the name of every BASEOP in B::OP
696             my $OP_THREADSV = opnumber('threadsv');
697             my $OP_DBMOPEN = opnumber('dbmopen');
698             my $OP_FORMLINE = opnumber('formline');
699             my $OP_UCFIRST = opnumber('ucfirst');
700             my $OP_CUSTOM = opnumber('custom');
701              
702             # special handling for nullified COP's.
703             my %OP_COP = ( opnumber('nextstate') => 1 );
704             $OP_COP{ opnumber('setstate') } = 1 if $] > 5.005003 and $] < 5.005062;
705             $OP_COP{ opnumber('dbstate') } = 1 unless $PERL512;
706             warn %OP_COP if $debug{cops};
707              
708             # 1. called from method_named, so hashp should be defined
709             # 2. called from svop before method_named to cache the $package_pv
710 0     0 0 0 sub svop_or_padop_pv {
711 0         0 my $op = shift;
712 0 0       0 my $sv;
713 0 0 0     0 if (!$op->can("sv")) {
714 0         0 if ($op->can('name') and $op->name eq 'padsv') {
715 0         0 my @c = comppadlist->ARRAY;
716 0 0 0     0 my @pad = $c[1]->ARRAY;
717             return $pad[$op->targ]->PV if $pad[$op->targ] and $pad[$op->targ]->can("PV");
718             # This might fail with B::NULL (optimized ex-const pv) entries in the pad.
719             }
720 0 0 0     0 # $op->can('pmreplroot') fails for 5.14
721 0         0 if (ref($op) eq 'B::PMOP' and $op->pmreplroot->can("sv")) {
722             $sv = $op->pmreplroot->sv;
723 0 0       0 } else {
724             return $package_pv unless $op->flags & 4;
725 0 0 0     0 # op->first is disallowed for !KIDS and OPpCONST_BARE
726 0 0       0 return $package_pv if $op->name eq 'const' and $op->flags & 64;
727 0         0 return $package_pv unless $op->first->can("sv");
728             $sv = $op->first->sv;
729             }
730 0         0 } else {
731             $sv = $op->sv;
732             }
733             # XXX see SvSHARED_HEK_FROM_PV for the stash in S_method_common pp_hot.c
734 0 0 0     0 # In this hash the CV is stored directly
735             if ($sv and $$sv) {
736             #if ($PERL510) { # PVX->hek_hash - STRUCT_OFFSET(struct hek, hek_key)
737             #} else { # UVX
738 0 0       0 #}
739 0 0       0 return $sv->PV if $sv->can("PV");
740             if (ref($sv) eq "B::SPECIAL") { # DateTime::TimeZone
741 0 0       0 # XXX null -> method_named
742 0         0 warn "NYI S_method_common op->sv==B::SPECIAL, keep $package_pv\n" if $debug{gv};
743             return $package_pv;
744 0 0       0 }
745 0 0       0 if ($sv->FLAGS & SVf_ROK) {
746 0         0 goto missing if $sv->isa("B::NULL");
747 0 0       0 my $rv = $sv->RV;
748 0         0 if ($rv->isa("B::PVGV")) {
749 0 0       0 my $o = $rv->IO;
750             return $o->STASH->NAME if $$o;
751 0 0       0 }
752 0         0 goto missing if $rv->isa("B::PVMG");
753             return $rv->STASH->NAME;
754             } else {
755 0 0       0 missing:
    0          
756             if ($op->name ne 'method_named') {
757             # Called from first const/padsv before method_named. no magic pv string, so a method arg.
758 0         0 # The first const pv as method_named arg is always the $package_pv.
759             return $package_pv;
760 0         0 } elsif ($sv->isa("B::IV")) {
761             warn sprintf("Experimentally try method_cv(sv=$sv,$package_pv) flags=0x%x",
762             $sv->FLAGS);
763 0         0 # XXX untested!
764             return svref_2object(method_cv($$sv, $package_pv));
765             }
766             }
767 0         0 } else {
768 0         0 my @c = comppadlist->ARRAY;
769 0 0 0     0 my @pad = $c[1]->ARRAY;
770             return $pad[$op->targ]->PV if $pad[$op->targ] and $pad[$op->targ]->can("PV");
771             }
772             }
773              
774 0 0   0 0 0 sub IsCOW {
775 0         0 if ($PERL522) {
776             return $_[0]->FLAGS & SVf_IsCOW;
777 0   0     0 }
778             return ($] >= 5.017008 and $_[0]->FLAGS & SVf_IsCOW); # since 5.17.8
779             }
780 0   0 0 0 0 sub IsCOW_hek {
781             return IsCOW($_[0]) && !$_[0]->LEN;
782             }
783              
784             if ($Config{usecperl} and $] >= 5.022002) {
785             eval q[sub isAvSTATIC {
786             my $flags = shift->FLAGS;
787             return !($flags & SVpav_REAL) && !($flags & SVpav_REIFY)
788             }];
789             } else {
790             eval q[sub isAvSTATIC () { 0 }];
791             }
792              
793 0     0 0 0 sub canAvSTATIC {
794 0         0 my ($av, $fullname) = @_;
795 0         0 my $flags = $av->FLAGS;
796             return 1;
797             }
798              
799 0     0 0 0 sub savesym {
800 55     55   675 my ( $obj, $value ) = @_;
  55         208  
  55         6178  
801 0         0 no strict 'refs';
802 0         0 my $sym = sprintf( "s\\_%x", $$obj );
803 0         0 $symtable{$sym} = $value;
804             return $value;
805             }
806              
807 0     0 0 0 sub objsym {
808 55     55   421 my $obj = shift;
  55         169  
  55         26852  
809 0         0 no strict 'refs';
810             return $symtable{ sprintf( "s\\_%x", $$obj ) };
811             }
812              
813 0     0 0 0 sub getsym {
814 0         0 my $sym = shift;
815             my $value;
816 0 0       0  
817 0         0 return 0 if $sym eq "sym_0"; # special case
818 0 0       0 $value = $symtable{$sym};
819 0         0 if ( defined($value) ) {
820             return $value;
821             }
822 0 0       0 else {
823 0         0 warn "warning: undefined symbol $sym\n" if $warn_undefined_syms;
824             return "UNUSED";
825             }
826             }
827              
828 0     0 0 0 sub delsym {
829 0         0 my ( $obj ) = @_;
830 0         0 my $sym = sprintf( "s\\_%x", $$obj );
831             delete $symtable{$sym};
832             }
833 0     0 0 0  
834 0     0 0 0 sub curcv { $B::C::curcv }
835             sub set_curcv($) { $B::C::curcv = shift; }
836              
837             # returns cstring, len, utf8 flags of a string
838 0     0 0 0 sub strlen_flags {
839 0         0 my $s = shift;
840 0 0 0     0 my ($len, $flags) = (0,"0");
841 0         0 if (!$PERL56 and utf8::is_utf8($s)) {
842 0         0 my $us = $s;
843 0         0 $flags = 'SVf_UTF8';
844             $len = utf8::upgrade($us);
845 0         0 } else {
846             $len = length $s;
847 0         0 }
848             return (cstring($s), $len, $flags);
849             }
850              
851 0     0 0 0 sub savestash_flags {
852 0 0       0 my ($name, $cstring, $len, $flags) = @_;
853             return $stashtable{$name} if exists $stashtable{$name};
854 0 0       0 #return '(HV*)&PL_sv_undef' if $name =~ /^(|B::CC?)$/; # protect against empty stashes
855 0         0 $flags = $flags ? "$flags|GV_ADD" : "GV_ADD";
856 0         0 my $sym = "hv$hv_index";
857 0         0 $decl->add("Static HV *$sym;");
858 0 0 0     0 $hv_index++;
859 0         0 if ($PERL518 and $name) { # since 5.18 save @ISA before calling stashpv
860 55     55   497 my @isa = get_isa($name);
  55         166  
  55         81260  
861 0 0 0     0 no strict 'refs';
  0         0  
862 0         0 if (@isa and exists ${$name.'::'}{ISA} ) {
  0         0  
863             svref_2object( \@{"$name\::ISA"} )->save("$name\::ISA");
864             }
865 0 0       0 }
866 0         0 my $pvsym = $len ? constpv($name) : '""';
867 0         0 $stashtable{$name} = $sym;
868             $init->add( sprintf( "%s = gv_stashpvn(%s, %u, %s); /* $name */",
869 0         0 $sym, $pvsym, $len, $flags));
870             return $sym;
871             }
872              
873 0     0 0 0 sub savestashpv {
874 0         0 my $name = shift;
875             return savestash_flags($name, strlen_flags($name));
876             }
877              
878 0     0 0 0 sub savere {
879 0   0     0 my $re = shift;
880 0         0 my $flags = shift || 0;
881 0         0 my $sym;
882 0         0 my $pv = $re;
883 0         0 my ($cstring, $cur, $utf8) = strlen_flags($pv);
884 0 0       0 my $len = 0; # static buffer
    0          
885 0         0 if ($PERL514) {
886 0 0       0 $xpvsect->add( sprintf( "Nullhv, {0}, %u, %u", $cur, $len ) );
887             $svsect->add( sprintf( "&xpv_list[%d], 1, %x, {%s}", $xpvsect->index,
888 0         0 0x4405, ($C99?".svu_pv=":"").'(char*)'.savepv($pv) ) );
889             $sym = sprintf( "&sv_list[%d]", $svsect->index );
890             }
891             elsif ($PERL510) {
892             # BUG! Should be the same as newSVpvn($resym, $relen) but is not
893             #$sym = sprintf("re_list[%d]", $re_index++);
894 0 0       0 #$resect->add(sprintf("0,0,0,%s", $cstring));
895 0         0 my $s1 = ($PERL514 ? "NULL," : "") . "{0}, %u, %u";
896 0 0       0 $xpvsect->add( sprintf( $s1, $cur, $len ) );
897             $svsect->add( sprintf( "&xpv_list[%d], 1, %x, {%s}", $xpvsect->index,
898 0         0 0x4405, ($C99?".svu_pv=":"").'(char*)'.savepv($pv) ) );
899 0         0 my $s = "sv_list[".$svsect->index."]";
900 0 0       0 $sym = "&$s";
901             push @B::C::static_free, $s if $len; # and $B::C::pv_copy_on_grow;
902             # $resect->add(sprintf("&xpv_list[%d], $u32fmt, 0x%x", $xpvsect->index, 1, 0x4405));
903             }
904 0         0 else {
905 0         0 $sym = sprintf( "re%d", $re_index++ );
906             $decl->add( sprintf( "Static const char *%s = %s;", $sym, $cstring ) );
907 0         0 }
908             return ( $sym, $cur );
909             }
910              
911 0     0 0 0 sub constpv {
912             return savepv(shift, 1);
913             }
914              
915 0     0 0 0 sub savepv {
916 0         0 my $pv = shift;
917 0         0 my $const = shift;
918             my ($cstring, $cur, $utf8) = strlen_flags($pv);
919 0 0       0 # $decl->add( sprintf( "/* %s */", $cstring) ) if $debug{pv};
920 0         0 return $strtable{$cstring} if defined $strtable{$cstring};
921 0 0       0 my $pvsym = sprintf( "pv%d", $pv_index++ );
922 0 0 0     0 $const = $const ? " const" : "";
923 0         0 if ( defined $max_string_len && $cur > $max_string_len ) {
  0         0  
924 0         0 my $chars = join ', ', map { cchar $_ } split //, pack("a*", $pv);
925 0         0 $decl->add( sprintf( "Static%s char %s[] = { %s };", $const, $pvsym, $chars ) );
926             $strtable{$cstring} = $pvsym;
927 0 0       0 } else {
928 0         0 if ( $cstring ne "0" ) { # sic
929 0         0 $decl->add( sprintf( "Static%s char %s[] = %s;", $const, $pvsym, $cstring ) );
930             $strtable{$cstring} = $pvsym;
931             }
932 0         0 }
933             return $pvsym;
934             }
935              
936 0     0 0 0 sub save_rv {
937 0 0       0 my ($sv, $fullname) = @_;
938 0         0 if (!$fullname) {
939             $fullname = '(unknown)';
940             }
941             # confess "Can't save RV: not ROK" unless $sv->FLAGS & SVf_ROK;
942             # 5.6: Can't locate object method "RV" via package "B::PVMG"
943 0         0 # since 5.11 it must be a PV, the RV was removed from the IV
944             my $rv;
945             #if ($] >= 5.011 and ref($sv) =~ /^B::[IP]V$/) {
946             # warn "$sv is no IV nor PV\n" if $debug{sv};
947             # $sv = bless $sv, 'B::PV'; # only observed with DB::args[0]
948             #}
949             #elsif ($] < 5.011 and ref($sv) =~ /^B::[RP]V$/) {
950             # warn "$sv is no RV nor PV\n" if $debug{sv};
951             # $sv = bless $sv, 'B::RV';
952 0         0 #}
953 0         0 $rv = $sv->RV->save($fullname);
954             $rv =~ s/^\(([AGHS]V|IO)\s*\*\)\s*(\&sv_list.*)$/$2/;
955 0         0  
956             return $rv;
957             }
958              
959             # => savesym, cur, len, pv, static, flags
960 0     0 0 0 sub save_pv_or_rv {
961             my ($sv, $fullname) = @_;
962 0         0  
963 0         0 my $flags = $sv->FLAGS;
964 0         0 my $rok = $flags & SVf_ROK;
965 0         0 my $pok = $flags & SVf_POK;
966 0 0 0     0 my $gmg = $flags & SVs_GMG;
967             my $iscow = (IsCOW($sv) or ($B::C::cow and $PERL518)) ? 1 : 0;
968 0         0 #my $wascow = IsCOW($sv) ? 1 : 0;
969 0         0 my ( $cur, $len, $savesym, $pv ) = ( 0, 1, 'NULL', "" );
970             my ($static, $shared_hek);
971             # overloaded VERSION symbols fail to xs boot: ExtUtils::CBuilder with Fcntl::VERSION (i91)
972 0 0 0     0 # 5.6: Can't locate object method "RV" via package "B::PV" Carp::Clan
973             if ($rok and !$PERL56) {
974 0 0       0 # this returns us a SV*. 5.8 expects a char* in xpvmg.xpv_pv
975 0 0       0 warn "save_pv_or_rv: save_rv(",$sv,")\n" if $debug{sv};
976 0         0 $savesym = ($PERL510 ? "" : "(char*)") . save_rv($sv, $fullname);
977 0 0       0 $static = 1; # avoid run-time overwrite of the PV/RV slot (#273)
978 0         0 if ($savesym =~ /get_cv/) { # Moose::Util::TypeConstraints::Builtins::_RegexpRef
979 0         0 $static = 0;
980 0         0 $pv = $savesym;
981             $savesym = 'NULL';
982             }
983             }
984 0 0       0 else {
985 0         0 if ($pok) {
986 0 0 0     0 $pv = pack "a*", $sv->PV; # XXX!
987             $cur = ($sv and $sv->can('CUR') and ref($sv) ne 'B::GV') ? $sv->CUR : length($pv);
988 0 0 0     0 # comppadname bug with overlong strings
      0        
      0        
989 0         0 if ($] < 5.008008 and $cur > 100 and $fullname =~ m/ :pad\[0\]/ and $pv =~ m/\0\0/) {
990 0 0       0 my $i = index($pv,"\0");
991 0         0 if ($i > -1) {
992 0         0 $pv = substr($pv,0,$i);
993 0 0       0 $cur = $i;
994             warn "Warning: stripped wrong comppad name for $fullname to ".cstring($pv)."\n"
995             if $verbose;
996             }
997             }
998 0 0 0     0 } else {
999 55     55   576 if ($gmg && $fullname) {
  55         157  
  55         158775  
1000 0 0 0     0 no strict 'refs';
  0         0  
1001 0         0 $pv = ($fullname and ref($fullname)) ? "${$fullname}" : '';
1002 0         0 $cur = length (pack "a*", $pv);
1003             $pok = 1;
1004 0         0 } else {
1005             ($pv,$cur) = ("",0);
1006             }
1007 0 0       0 }
1008 0 0       0 $shared_hek = $PERL510 ? (($flags & 0x09000000) == 0x09000000) : undef;
1009 0 0 0     0 $shared_hek = $shared_hek ? 1 : IsCOW_hek($sv);
1010             $static = ($B::C::const_strings or $iscow or ($flags & SVf_READONLY))
1011 0 0 0     0 ? 1 : 0;
      0        
      0        
1012             $static = 0 if $shared_hek
1013             or ($fullname and ($fullname =~ m/ :pad/
1014 0 0 0     0 or ($fullname =~ m/^DynaLoader/ and $pv =~ m/^boot_/)));
1015 0 0 0     0 $static = 0 if $static and $pv =~ /::bootstrap$/;
      0        
1016 0 0 0     0 $static = 0 if $static and $] > 5.017 and ref($sv) eq 'B::PVMG'; # 242: e.g. $1
      0        
      0        
      0        
1017             $static = 0 if $static and $B::C::const_strings and $fullname and
1018 0 0 0     0 ($fullname =~ /^warnings::(Dead)?Bits/ or $fullname =~ /::AUTOLOAD$/);
      0        
1019 0 0 0     0 if ($shared_hek and $pok and !$cur) { #272 empty key
1020 0 0       0 warn "use emptystring for empty shared key $fullname\n" if $debug{pv} or $debug{hv};
1021 0         0 $savesym = "emptystring" unless $fullname =~ /unopaux_item.* const/;
1022             $static = 0;
1023 0 0 0     0 }
1024 0 0 0     0 if ($static and $PERL510) { # force dynamic PADNAME strings
  0 0 0     0  
    0          
    0          
1025             if ($] < 5.016) { $static = 0 if $flags & 0x40000000; } # SVpad_NAME
1026             # w. 5.18 even const and VERSION
1027 0 0       0 elsif ($] < 5.020 and $fullname =~ /(^svop const|::VERSION)$/) {
1028 0         0 warn "static=0 for $fullname\n" if $debug{pv};
1029             $static = 0;
1030             }
1031 0 0       0 elsif ($] < 5.022 and ($flags & 0x40008000 == 0x40008000)) { # SVpad_NAME
1032 0         0 warn "static=0 for SVpad_NAME $fullname\n" if $debug{pv};
1033             $static = 0;
1034             }
1035 0 0       0 }
1036 0         0 if ($pok) {
1037             my $s = "sv_list[" . ($svsect->index + 1) . "]";
1038             # static pv (!SvLEN) only valid since cd84013aab030da47b76a44fb3 (sv.c: !SvLEN does not mean undefined)
1039             # i.e. since v5.17.6. because conversion to IV would fail.
1040             # But a "" or "0" or "[a-z]+" string can have SvLEN=0
1041             # since its is converted to 0.
1042             # Only a readonly "" or "0" string can have SvLEN=0 since it's
1043             # converted to 0, which leads to the same result.
1044             # perlcc -O3 -r -e'print "ok" if 1 == "1"'
1045             # vs
1046             # perlcc -O2 -r -e'print "ok" if 1 == "1"'
1047 0 0 0     0 # ok
      0        
1048 0         0 if ($static and $] < 5.017006 and $pv !~ /^0?$/) {
1049             $static = 0;
1050             }
1051 0 0 0     0 # but we can optimize static set-magic ISA entries. #263, #91
      0        
      0        
1052             if ($B::C::const_strings and ref($sv) eq 'B::PVMG'
1053 0         0 and $flags & SVs_SMG and $fullname =~ /ISA/) {
1054             $static = 1; # warn "static $fullname";
1055 0 0       0 }
1056 0         0 if ($static) {
1057             $len = 0;
1058 0 0 0     0 #warn cstring($sv->PV)." $iscow $wascow";
1059 0 0       0 if ($iscow and $PERL518) { # 5.18 COW logic
    0          
1060 0         0 if ($B::C::Config::have_HEK_STATIC) {
1061 0         0 $iscow = 1;
1062             $shared_hek = 1;
1063 0         0 # $pv .= "\000\001";
1064             $savesym = save_hek($pv,$fullname,0);
1065             # warn "static shared hek: $savesym";
1066             # $savesym =~ s/&\(HEK\)(hek\d+)/&($1.hek_key)/;
1067             } elsif ($B::C::cow) {
1068 0         0 # wrong in many cases but saves a lot of memory, only do this with -O2
1069 0         0 $len = $cur+2;
1070 0         0 $pv .= "\000\001";
1071             $savesym = savepv($pv);
1072 0         0 } else {
1073 0         0 $iscow = 0;
1074             $savesym = constpv($pv);
1075             }
1076 0         0 } else {
1077             $savesym = constpv($pv);
1078 0 0       0 }
1079 0         0 if ($savesym =~ /\)?get_cv/) { # Moose::Util::TypeConstraints::Builtins::_RegexpRef
1080 0         0 $static = 0;
1081 0         0 $len = $cur +1;
1082 0         0 $pv = $savesym;
1083             $savesym = 'NULL';
1084 0 0       0 }
1085 0         0 if ($iscow) {
1086             $flags |= SVf_IsCOW;
1087 0         0 } else {
1088             $flags &= ~SVf_IsCOW;
1089             }
1090             #push @B::C::static_free, $savesym if $len and $savesym =~ /^pv/ and !$B::C::in_endav;
1091 0         0 } else {
1092 0 0       0 $len = $cur+1;
1093 0 0       0 if ($shared_hek) {
1094 0         0 if ($savesym eq "emptystring") {
1095 0 0       0 $free->add(" SvLEN(&$s) = 0;");
1096             $len = 0 if $PERL518;
1097 0         0 } else {
1098             $len = 0;
1099 0         0 }
1100             $free->add(" SvFAKE_off(&$s);");
1101 0 0 0     0 } else {
      0        
1102 0         0 if ($iscow and $cur and $PERL518) {
1103 0         0 $len++;
1104 0         0 $pv .= "\000\001";
1105             $flags |= SVf_IsCOW;
1106             }
1107             }
1108             }
1109 0         0 } else {
1110             $len = 0;
1111             }
1112             }
1113             #if ($iscow and $len and $PERL518) { # 5.18 COW logic
1114             # my $offset = $len % $Config{ptrsize};
1115             # $len += $Config{ptrsize} - $offset if $offset;
1116             #}
1117             warn sprintf("Saving pv as %s %s cur=%d, len=%d, static=%d cow=%d %s flags=0x%x\n",
1118             $savesym, cstring($pv), $cur, $len,
1119 0 0       0 $static, $iscow, $shared_hek ? "shared, $fullname" : $fullname, $flags)
    0          
1120 0         0 if $debug{pv};
1121             return ( $savesym, $cur, $len, $pv, $static, $flags );
1122             }
1123              
1124             # Shared global string in PL_strtab.
1125             # Mostly GvNAME and GvFILE, but also CV prototypes or bareword hash keys.
1126             # Note: currently not used in list context
1127 0     0 0 0 sub save_hek {
1128             my ($str, $fullname, $dynamic) = @_; # not cstring'ed
1129             # $dynamic: see lexsub CvNAME in CV::save
1130 0 0       0 # force empty string for CV prototypes
1131 0 0 0     0 return "NULL" unless defined $str;
      0        
      0        
1132             return "NULL" if $dynamic and !length $str and !@_
1133             and $fullname !~ /unopaux_item.* const/;
1134             # The first assigment is already refcount bumped, we have to manually
1135 0         0 # do it for all others
1136 0         0 my ($cstr, $cur, $utf8) = strlen_flags($str);
1137 0 0 0     0 my $hek_key = $str.":".$utf8;
1138 0         0 if ($dynamic and defined $hektable{$hek_key}) {
1139             return sprintf("share_hek_hek(%s)", $hektable{$hek_key});
1140 0 0 0     0 }
1141 0         0 if (!$dynamic and defined $statichektable{$hek_key}) {
1142             return $statichektable{$hek_key};
1143 0 0       0 }
1144 0 0       0 $cur = - $cur if $utf8;
1145 0         0 $cstr = '""' if $cstr eq "0";
1146 0 0       0 my $sym = sprintf( "hek%d", $hek_index++ );
1147 0         0 if (!$dynamic) {
1148 0         0 $statichektable{$hek_key} = $sym;
1149 0         0 my $key = $cstr;
1150             my $len = abs($cur);
1151 0 0       0 # strip CowREFCNT
1152 0         0 if ($key =~ /\\000\\001"$/) {
1153 0         0 $key =~ s/\\000\\001"$/"/;
1154             $len -= 2;
1155             }
1156 0 0       0 # add the flags. a static hek is unshared
1157 0         0 if (!$utf8) { # 0x88: HVhek_STATIC + HVhek_UNSHARED
1158             $key =~ s/"$/\\000\\210"/;
1159 0         0 } else { # 0x89: + HVhek_UTF8
1160             $key =~ s/"$/\\000\\211"/;
1161             }
1162             #warn sprintf("Saving static hek %s %s cur=%d\n", $sym, $cstr, $cur)
1163             # if $debug{pv};
1164 0         0 # not const because we need to set the HASH at init
1165             $decl->add(sprintf("Static struct hek_ptr %s = { %u, %d, %s};",
1166 0         0 $sym, 0, $len, $key));
1167             $init->add(sprintf("PERL_HASH(%s.hek_hash, %s.hek_key, %u);", $sym, $sym, $len));
1168 0         0 } else {
1169 0         0 $hektable{$hek_key} = $sym;
1170             $decl->add(sprintf("Static HEK *%s;", $sym));
1171 0 0       0 warn sprintf("Saving hek %s %s cur=%d\n", $sym, $cstr, $cur)
1172             if $debug{pv};
1173             # randomized global shared hash keys:
1174             # share_hek needs a non-zero hash parameter, unlike hv_store.
1175             # Vulnerable to oCERT-2011-003 style DOS attacks?
1176             # user-input (object fields) do not affect strtab, it is pretty safe.
1177             # But we need to randomize them to avoid run-time conflicts
1178             # e.g. "Prototype mismatch: sub bytes::length (_) vs (_)"
1179             #if (0 and $PERL510) { # no refcount
1180             # $init->add(sprintf("%s = my_share_hek_0(%s, %d);", $sym, $cstr, $cur));
1181 0         0 #} else { # vs. bump the refcount
1182             $init->add(sprintf("%s = share_hek(%s, %d);", $sym, $cstr, $cur));
1183             #}
1184             # protect against Unbalanced string table refcount warning with PERL_DESTRUCT_LEVEL=2
1185             # $free->add(" $sym = NULL;");
1186 0         0 }
1187             return $sym;
1188             }
1189              
1190 0     0 0 0 sub gv_fetchpvn {
1191 0 0       0 my ($name, $flags, $type) = @_;
1192 0 0       0 warn 'undefined flags' unless defined $flags;
1193 0         0 warn 'undefined type' unless defined $type;
1194 0 0       0 my ($cname, $cur, $utf8) = strlen_flags($name);
1195 0 0       0 if ($] >= 5.009002) {
    0          
1196 0         0 $flags .= length($flags) ? "|$utf8" : $utf8 if $utf8;
1197             return "gv_fetchpvn_flags($cname, $cur, $flags, $type)";
1198 0         0 } else {
1199             return "gv_fetchpv($cname, $flags, $type)";
1200             }
1201             }
1202              
1203             # get_cv() returns a CV*
1204 0     0 0 0 sub get_cv {
1205 0 0       0 my ($name, $flags) = @_;
1206 0         0 $name = "" if $name eq "__ANON__";
1207 0 0       0 my ($cname, $cur, $utf8) = strlen_flags($name);
1208 0 0       0 warn 'undefined flags' unless defined $flags;
1209 0 0       0 if ($] >= 5.009002) {
    0          
1210 0         0 $flags .= length($flags) ? "|$utf8" : $utf8 if $utf8;
1211             return qq[get_cvn_flags($cname, $cur, $flags)];
1212 0         0 } else {
1213             return qq[get_cv($cname, $flags)];
1214             }
1215             }
1216              
1217 0     0 0 0 sub ivx ($) {
1218 0         0 my $ivx = shift;
1219 0         0 my $ivdformat = $Config{ivdformat};
1220 0         0 $ivdformat =~ s/["\0]//g; #" poor editor
1221 0 0       0 $ivdformat =~ s/".$/"/; # cperl bug 5.22.2 #61 (never released)
1222 0 0       0 unless ($ivdformat) {
1223             $ivdformat = $Config{ivsize} == 4 ? 'd' : 'ld';
1224 0         0 }
1225 0         0 my $POW = ( $Config{ivsize} * 4 - 1 ); # poor editor
1226 0         0 my $intmax = (1 << $POW) - 1;
1227             my $L = 'L';
1228 0 0       0 # LL for 32bit -2147483648L or 64bit -9223372036854775808L
1229             $L = 'LL' if $Config{ivsize} == 2*$Config{ptrsize};
1230 0 0       0 # UL if > INT32_MAX = 2147483647
1231 0 0       0 my $sval = sprintf("%${ivdformat}%s", $ivx, $ivx > $intmax ? "U$L" : "");
1232 0         0 if ($ivx < -$intmax) {
1233             $sval = sprintf("%${ivdformat}%s", $ivx, 'LL'); # DateTime
1234 0 0       0 }
1235             if ($INC{'POSIX.pm'}) {
1236 0 0       0 # i262: LONG_MIN -9223372036854775808L integer constant is so large that it is unsigned
    0          
1237 0         0 if ($ivx == POSIX::LONG_MIN()) {
1238             $sval = "PERL_LONG_MIN";
1239             }
1240 0         0 elsif ($ivx == POSIX::LONG_MAX()) {
1241             $sval = "PERL_LONG_MAX";
1242             }
1243             #elsif ($ivx == POSIX::HUGE_VAL()) {
1244             # $sval = "HUGE_VAL";
1245             #}
1246 0 0       0 }
1247 0         0 $sval = '0' if $sval =~ /(NAN|inf)$/i;
1248             return $sval;
1249             #return $C99 ? ".xivu_uv = $sval" : $sval; # this is version dependent
1250             }
1251              
1252             # protect from warning: floating constant exceeds range of ‘double’ [-Woverflow]
1253 0     0 0 0 sub nvx ($) {
1254             my $nvx = shift;
1255              
1256 0 0       0 # Handle infinite and NaN values
1257 0 0 0     0 if ( defined $nvx ) {
1258 0 0       0 if ( $Config{d_isinf} or $] < 5.012 ) {
1259 0 0       0 return 'INFINITY' if $nvx =~ /^Inf/i;
1260             return '-INFINITY' if $nvx =~ /^-Inf/i;
1261 0 0 0     0 }
      0        
1262             return 'NAN' if $nvx =~ /^NaN/i and ($Config{d_isnan} or $] < 5.012);
1263             # TODO NANL for long double
1264             }
1265 0         0  
1266 0         0 my $nvgformat = $Config{nvgformat};
1267 0         0 $nvgformat =~ s/["\0]//g; #" poor editor
1268 0 0       0 $nvgformat =~ s/".$/"/; # cperl bug 5.22.2 #61
1269 0         0 unless ($nvgformat) {
1270             $nvgformat = 'g';
1271 0         0 }
1272 0         0 my $dblmax = "1.79769313486232e+308";
1273 0 0       0 my $ldblmax = "1.18973149535723176502e+4932";
1274             if ($nvgformat eq 'g') { # a very poor choice to keep precision
1275             # on intel 17-18, on ppc 31, on sparc64/s390 34
1276 0 0       0 # TODO: rather use the binary representation of our union
1277             $nvgformat = $Config{uselongdouble} ? '.18Lg' : '.17g';
1278 0 0       0 }
1279 0 0       0 my $sval = sprintf("%${nvgformat}%s", $nvx, $nvx > $dblmax ? "L" : "");
1280 0 0       0 $sval = sprintf("%${nvgformat}%s", $nvx, "L") if $nvx < -$dblmax;
1281 0 0       0 if ($INC{'POSIX.pm'}) {
    0          
1282 0         0 if ($nvx == POSIX::DBL_MIN()) {
1283             $sval = "DBL_MIN";
1284             }
1285 0         0 elsif ($nvx == POSIX::DBL_MAX()) { #1.797693134862316e+308
1286             $sval = "DBL_MAX";
1287             }
1288             }
1289 0 0       0 else {
1290 0         0 if ($nvx == $dblmax) {
1291             $sval = "DBL_MAX";
1292             }
1293             }
1294 0 0       0  
1295 0         0 if ($Config{d_longdbl}) {
1296 0 0       0 my $posix;
1297 0         0 if ($INC{'POSIX.pm'}) {
  0         0  
1298             eval { $posix = POSIX::LDBL_MIN(); };
1299 0 0       0 }
    0          
1300 0 0       0 if ($posix) { # linux does not have these, darwin does
    0          
1301 0         0 if ($nvx == $posix) {
1302             $sval = "NV_MIN";
1303             }
1304 0         0 elsif ($nvx == POSIX::LDBL_MAX()) {
1305             $sval = "NV_MAX";
1306             }
1307 0         0 } elsif ($nvx == $ldblmax) {
1308             $sval = "NV_MAX";
1309             }
1310 0 0       0 }
1311 0 0       0 $sval = '0' if $sval =~ /(NAN|inf)$/i;
1312 0         0 $sval .= '.00' if $sval =~ /^-?\d+$/;
1313             return $sval;
1314             }
1315              
1316 0     0 0 0 sub mg_RC_off {
1317 0 0       0 my ($mg, $sym, $type) = @_;
1318 0 0       0 warn "MG->FLAGS ",$mg->FLAGS," turn off MGf_REFCOUNTED\n" if $debug{mg};
1319 0         0 if (!ref $sym) {
1320             $init->add(sprintf("my_mg_RC_off(aTHX_ (SV*)$sym, %s);", cchar($type)));
1321 0         0 } else {
1322             $init->add(sprintf("my_mg_RC_off(aTHX_ (SV*)s\\_%x, %s);", $$sym, cchar($type)));
1323             }
1324             }
1325              
1326             # for bytes and utf8 only
1327             # TODO: Carp::Heavy, Exporter::Heavy
1328             # special case: warnings::register via -fno-warnings
1329 0     0 0 0 sub force_heavy {
1330 0         0 my $pkg = shift;
1331 55     55   755 my $pkg_heavy = $pkg."_heavy.pl";
  55         166  
  55         158043  
1332 0 0 0     0 no strict 'refs';
1333             if (!$include_package{$pkg_heavy} and !exists $savINC{$pkg_heavy}) {
1334             #eval qq[sub $pkg\::AUTOLOAD {
1335             # require '$pkg_heavy';
1336             # goto &\$AUTOLOAD if defined &\$AUTOLOAD;
1337             # warn("Undefined subroutine \$AUTOLOAD called");
1338             # }];
1339 0 0       0 #warn "Redefined $pkg\::AUTOLOAD to omit Carp\n" if $debug{gv};
1340 0         0 warn "Forcing early $pkg_heavy\n" if $debug{pkg};
1341 0         0 require $pkg_heavy;
1342             mark_package($pkg_heavy, 1);
1343             #walk_syms($pkg); #before we stub unloaded CVs
1344 0         0 }
  0         0  
1345             return svref_2object( \*{$pkg."::AUTOLOAD"} );
1346             }
1347              
1348             # See also init_op_ppaddr below; initializes the ppaddr to the
1349             # OpTYPE; init_op_ppaddr iterates over the ops and sets
1350             # op_ppaddr to PL_ppaddr[op_ppaddr]; this avoids an explicit assignment
1351             # in perl_init ( ~10 bytes/op with GCC/i386 )
1352 0     0   0 sub B::OP::fake_ppaddr {
1353 0 0       0 my $op = shift;
1354 0 0       0 return "NULL" unless $op->can('name');
1355 0 0       0 if ($op->type == $OP_CUSTOM) {
1356             return ( $verbose ? sprintf( "/*XOP %s*/NULL", $op->name) : "NULL" );
1357 0 0       0 }
    0          
1358             return $B::C::optimize_ppaddr
1359             ? sprintf( "INT2PTR(void*,OP_%s)", uc( $op->name ) )
1360             : ( $verbose ? sprintf( "/*OP_%s*/NULL", uc( $op->name ) ) : "NULL" );
1361 0     0   0 }
1362             sub B::FAKEOP::fake_ppaddr { "NULL" }
1363 0     0   0 # XXX HACK! duct-taping around compiler problems
1364 69204     69204   6251345 sub B::OP::isa { UNIVERSAL::isa(@_) } # walkoptree_slow misses that
1365 0     0   0 sub B::OP::can { UNIVERSAL::can(@_) }
1366             sub B::OBJECT::name { "" } # B misses that
1367             $isa_cache{'B::OBJECT::can'} = 'UNIVERSAL';
1368              
1369             # This pair is needed because B::FAKEOP::save doesn't scalar dereference
1370             # $op->next and $op->sibling
1371             my $opsect_common =
1372             "next, sibling, ppaddr, " . ( $MAD ? "madprop, " : "" ) . "targ, type, ";
1373             #$opsect_common =~ s/, sibling/, _OP_SIBPARENT_FIELDNAME/ if $] > 5.021007;
1374             $opsect_common =~ s/, sibling/, sibparent/ if $have_sibparent;
1375             {
1376              
1377             # For 5.8:
1378             # Current workaround/fix for op_free() trying to free statically
1379             # defined OPs is to set op_seq = -1 and check for that in op_free().
1380             # Instead of hardwiring -1 in place of $op->seq, we use $op_seq
1381             # so that it can be changed back easily if necessary. In fact, to
1382             # stop compilers from moaning about a U16 being initialised with an
1383             # uncast -1 (the printf format is %d so we can't tweak it), we have
1384             # to "know" that op_seq is a U16 and use 65535. Ugh.
1385              
1386             # For 5.9 the hard coded text is the values for op_opt and op_static in each
1387             # op. The value of op_opt is irrelevant, and the value of op_static needs to
1388             # be 1 to tell op_free that this is a statically defined op and that is
1389             # shouldn't be freed.
1390              
1391             # For 5.10 op_seq = -1 is gone, the temp. op_static also, but we
1392             # have something better, we can set op_latefree to 1, which frees the children
1393             # (e.g. savepvn), but not the static op.
1394              
1395             # 5.8: U16 op_seq;
1396             # 5.9.4: unsigned op_opt:1; unsigned op_static:1; unsigned op_spare:5;
1397             # 5.10: unsigned op_opt:1; unsigned op_latefree:1; unsigned op_latefreed:1; unsigned op_attached:1; unsigned op_spare:3;
1398             # 5.18: unsigned op_opt:1; unsigned op_slabbed:1; unsigned op_savefree:1; unsigned op_static:1; unsigned op_spare:3;
1399             # 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;
1400             # 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;
1401             # 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;
1402             my $static;
1403             if ( $] < 5.009004 ) {
1404             $static = sprintf "%u", 65535;
1405             $opsect_common .= "seq";
1406             }
1407             elsif ( $] < 5.010 ) {
1408             $static = '0, 1, 0';
1409             $opsect_common .= "opt, static, spare";
1410             }
1411             elsif ($] < 5.017002) {
1412             $static = '0, 1, 0, 0, 0';
1413             $opsect_common .= "opt, latefree, latefreed, attached, spare";
1414             }
1415             elsif ($] < 5.017004) {
1416             $static = '0, 1, 0, 0, 0, 0, 0';
1417             $opsect_common .= "opt, latefree, latefreed, attached, slabbed, savefree, spare";
1418             }
1419             elsif ($] < 5.017006) {
1420             $static = '0, 1, 0, 0, 0, 0, 0';
1421             $opsect_common .= "opt, latefree, latefreed, attached, slabbed, savefree, spare";
1422             }
1423             elsif ($] < 5.019002) { # 90840c5d1d 5.17.6
1424             $static = '0, 0, 0, 1, 0';
1425             $opsect_common .= "opt, slabbed, savefree, static, spare";
1426             }
1427             elsif ($] < 5.021002) {
1428             $static = '0, 0, 0, 1, 0, 0';
1429             $opsect_common .= "opt, slabbed, savefree, static, folded, spare";
1430             }
1431             elsif ($] < 5.0210011) {
1432             $static = '0, 0, 0, 1, 0, %d, 0';
1433             $opsect_common .= "opt, slabbed, savefree, static, folded, lastsib, spare";
1434             }
1435             else {
1436             $static = '0, 0, 0, 1, 0, %d, 0';
1437             $opsect_common .= "opt, slabbed, savefree, static, folded, moresib, spare";
1438             }
1439              
1440 0     0   0 sub B::OP::_save_common_middle {
1441 0 0       0 my $op = shift;
1442 0         0 my $madprop = $MAD ? "0," : "";
1443 0 0       0 my $ret;
1444 0         0 if ($static =~ / %d,/) {
1445 0 0       0 my $has_sib;
    0          
1446 0         0 if (ref($op) eq 'B::FAKEOP') {
1447             $has_sib = 0;
1448 0         0 } elsif ($] < 5.0210011) {
1449             $has_sib = $op->lastsib;
1450 0         0 } else {
1451             $has_sib = $op->moresib;
1452 0         0 }
1453             $ret = sprintf( "%s, %s %u, %u, $static, 0x%x, 0x%x",
1454             $op->fake_ppaddr, $madprop, $op->targ, $op->type,
1455             $has_sib,
1456             $op->flags, $op->private );
1457 0         0 } else {
1458             $ret = sprintf( "%s, %s %u, %u, $static, 0x%x, 0x%x",
1459             $op->fake_ppaddr, $madprop, $op->targ, $op->type,
1460             $op->flags, $op->private );
1461             }
1462 0 0       0 # XXX maybe add a ix=opindex string for debugging if $debug{flags}
1463 0         0 if ($B::C::Config::have_op_rettype) {
1464             $ret .= sprintf(", 0x%x", $op->rettype);
1465 0         0 }
1466             $ret;
1467             }
1468             $opsect_common .= ", flags, private";
1469             if ($B::C::Config::have_op_rettype) {
1470             $opsect_common .= ", rettype";
1471             }
1472             }
1473              
1474 0     0   0 sub B::OP::_save_common {
1475             my $op = shift;
1476             # compile-time method_named packages are always const PV sM/BARE, they should be optimized.
1477             # run-time packages are in gvsv/padsv. This is difficult to optimize.
1478             # my Foo $obj = shift; $obj->bar(); # TODO typed $obj
1479             # entersub -> pushmark -> package -> args...
1480             # See perl -MO=Terse -e '$foo->bar("var")'
1481             # See also http://www.perl.com/pub/2000/06/dougpatch.html
1482             # XXX TODO 5.8 ex-gvsv
1483 0 0 0     0 # XXX TODO Check for method_named as last argument
      0        
      0        
      0        
      0        
      0        
1484             if ($op->type > 0 and
1485             $op->name eq 'entersub' and $op->first and $op->first->can('name') and
1486             $op->first->name eq 'pushmark' and
1487             # Foo->bar() compile-time lookup, 34 = BARE in all versions
1488             (($op->first->next->name eq 'const' and $op->first->next->flags == 34)
1489             or $op->first->next->name eq 'padsv' # or $foo->bar() run-time lookup
1490             or ($] < 5.010 and $op->first->next->name eq 'gvsv' and !$op->first->next->type # 5.8 ex-gvsv
1491             and $op->first->next->next->name eq 'const' and $op->first->next->next->flags == 34))
1492 0         0 ) {
1493 0 0 0     0 my $pkgop = $op->first->next;
1494 0         0 if ($] < 5.010 and !$op->first->next->type) { # 5.8 ex-gvsv
1495             $pkgop = $op->first->next->next;
1496 0 0       0 }
1497 0         0 warn "check package_pv ".$pkgop->name." for method_name\n" if $debug{cv};
1498 0 0 0     0 my $pv = svop_or_padop_pv($pkgop); # 5.13: need to store away the pkg pv
1499 0         0 if ($pv and $pv !~ /[! \(]/) {
1500 0         0 $package_pv = $pv;
1501             push_package($package_pv);
1502             } else {
1503 0 0       0 # mostly optimized-away padsv NULL pads with 5.8
1504             warn "package_pv for method_name not found\n" if $debug{cv};
1505             }
1506 0 0       0 }
1507 0 0       0 if ($op->type == $OP_CUSTOM) {
1508             warn sprintf("CUSTOM OP %s $op\n", $op->name) if $verbose;
1509 0         0 }
1510 0         0 $prev_op = $op;
1511 0 0 0     0 my $sibling;
1512 0         0 if ($have_sibparent and !$op->moresib) { # HAS_SIBLING
1513 0 0 0     0 $sibling = $op->parent;
1514             warn "sibparent ",$op->name," $sibling\n" if $verbose and $debug{op};
1515 0         0 } else {
1516             $sibling = $op->sibling;
1517             }
1518 0         0 return sprintf( "s\\_%x, s\\_%x, %s",
  0         0  
1519             ${ $op->next },
1520             $$sibling,
1521             $op->_save_common_middle
1522             );
1523             }
1524              
1525 0     0   0 sub B::OP::save {
1526 0         0 my ( $op, $level ) = @_;
1527 0 0       0 my $sym = objsym($op);
1528 0 0       0 return $sym if defined $sym;
1529 0         0 $level = 0 unless $level;
1530 0 0       0 my $type = $op->type;
1531 0 0       0 $nullop_count++ unless $type;
1532             if ( $type == $OP_THREADSV ) {
1533 0         0 # saves looking up ppaddr but it's a bit naughty to hard code this
1534             $init->add(sprintf( "(void)find_threadsv(%s);", cstring( $threadsv_names[ $op->targ ])));
1535 0 0       0 }
1536 0         0 if ( $type == $OP_UCFIRST ) {
1537 0 0       0 $B::C::fold = 1;
1538 0 0       0 if ($] >= 5.013009) {
1539 0 0       0 warn "enabling -ffold with ucfirst\n" if $verbose;
1540 0         0 require "utf8.pm" unless $savINC{"utf8.pm"};
1541 0         0 mark_package("utf8");
1542             load_utf8_heavy();
1543             }
1544 0 0       0 }
1545             if (ref($op) eq 'B::OP') { # check wrong BASEOPs
1546             # [perl #80622] Introducing the entrytry hack, needed since 5.12, fixed with 5.13.8 a425677
1547             # ck_eval upgrades the UNOP entertry to a LOGOP, but B gets us just a B::OP (BASEOP).
1548 0 0       0 # op->other points to the leavetry op, which is needed for the eval scope.
1549 0 0       0 if ($op->name eq 'entertry') {
1550 0         0 warn "[perl #80622] Upgrading entertry from BASEOP to LOGOP...\n" if $verbose;
1551 0         0 bless $op, 'B::LOGOP';
1552             return $op->save($level);
1553             }
1554             }
1555              
1556 0 0 0     0 # since 5.10 nullified cops free their additional fields
      0        
1557 0 0       0 if ( $PERL510 and !$type and $OP_COP{ $op->targ } ) {
1558 0         0 warn sprintf( "Null COP: %d\n", $op->targ ) if $debug{cops};
1559             if (0 and $optimize_cop) {
1560             # XXX when is the NULL COP save to skip?
1561             # unsafe after entersub, entereval, anoncode, sort block (pushmark pushmark)
1562             # Rather skip this with CC not with C because we need the context.
1563             # XXX we dont have the prevop, it can be any op type.
1564             if ($verbose or $debug{cops}) {
1565             my $prevop = getsym(sprintf("&op_list[%d]", $opsect->index));
1566             warn sprintf( "Skip Null COP: %d, prev=\\s%x\n",
1567             $op->targ, $prevop);
1568             }
1569             return savesym( $op, $op->next->save );
1570 0 0 0     0 }
    0 0        
    0 0        
    0          
    0          
1571 0         0 if ($ITHREADS and $] >= 5.017) {
1572             $copsect->comment(
1573 0         0 "$opsect_common, line, stashoff, file, hints, seq, warnings, hints_hash");
1574             $copsect->add(sprintf("%s, 0, 0, (char *)NULL, 0, 0, NULL, NULL",
1575             $op->_save_common));
1576             }
1577 0         0 elsif ($ITHREADS and $] >= 5.016) {
1578             $copsect->comment(
1579 0         0 "$opsect_common, line, stashpv, file, stashlen, hints, seq, warnings, hints_hash");
1580             $copsect->add(sprintf("%s, 0, (char *)NULL, NULL, 0, 0, 0, NULL, NULL",
1581             $op->_save_common));
1582             }
1583 0         0 elsif ($ITHREADS and $] >= 5.015004) {
1584             $copsect->comment(
1585 0         0 "$opsect_common, line, stash, file, hints, seq, warnings, hints_hash");
1586             $copsect->add(sprintf("%s, 0, (char *)NULL, NULL, 0, 0, NULL, NULL",
1587             $op->_save_common));
1588             }
1589 0         0 elsif ($PERL512) {
1590             $copsect->comment(
1591 0 0       0 "$opsect_common, line, stash, file, hints, seq, warnings, hints_hash");
1592             $copsect->add(sprintf("%s, 0, %s, NULL, 0, 0, NULL, NULL",
1593             $op->_save_common, $ITHREADS ? "(char *)NULL" : "Nullhv"));
1594             }
1595 0         0 elsif ($PERL510) {
1596 0         0 $copsect->comment("$opsect_common, line, label, seq, warn_int, hints_hash");
1597             $copsect->add(sprintf("%s, %u, NULL, " . "NULL, NULL, 0, " . "%u, %d, NULL",
1598             $op->_save_common, 0, 0, 0));
1599             }
1600 0         0 else {
1601             $copsect->comment(
1602 0         0 "$opsect_common, label, seq, arybase, line, warnings, hints_hash");
1603             $copsect->add(
1604             sprintf( "%s, NULL, NULL, NULL, 0, 0, 0, NULL", $op->_save_common ) );
1605 0         0 }
1606 0 0       0 my $ix = $copsect->index;
1607             $init->add( sprintf( "cop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1608 0         0 unless $B::C::optimize_ppaddr;
1609             savesym( $op, "(OP*)&cop_list[$ix]" );
1610             }
1611 0         0 else {
1612 0         0 $opsect->comment($opsect_common);
1613             $opsect->add( $op->_save_common );
1614 0 0       0  
1615 0         0 $opsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1616 0 0       0 my $ix = $opsect->index;
1617             $init->add( sprintf( "op_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1618             unless $B::C::optimize_ppaddr;
1619 0 0       0 warn( sprintf( " OP=%s targ=%d flags=0x%x private=0x%x\n",
1620 0         0 peekop($op), $op->targ, $op->flags, $op->private ) ) if $debug{op};
1621             savesym( $op, "&op_list[$ix]" );
1622             }
1623             }
1624              
1625             # needed for special GV logic: save only stashes for stashes
1626             package B::STASHGV;
1627             our @ISA = ('B::GV');
1628              
1629             package B::FAKEOP;
1630              
1631             our @ISA = qw(B::OP);
1632              
1633 0     0   0 sub new {
1634 0         0 my ( $class, %objdata ) = @_;
1635             bless \%objdata, $class;
1636             }
1637              
1638 0     0   0 sub save {
1639 0         0 my ( $op, $level ) = @_;
1640             $opsect->add(
1641             sprintf( "%s, %s, %s", $op->next, $op->sibling, $op->_save_common_middle )
1642 0         0 );
1643 0 0       0 my $ix = $opsect->index;
1644             $init->add( sprintf( "op_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1645 0         0 unless $B::C::optimize_ppaddr;
1646             return "&op_list[$ix]";
1647             }
1648              
1649 0 0   0   0 *_save_common_middle = \&B::OP::_save_common_middle;
1650 0 0   0   0 sub next { $_[0]->{"next"} || 0 }
1651 0 0   0   0 sub type { $_[0]->{type} || 0 }
1652 0 0   0   0 sub sibling { $_[0]->{sibling} || 0 }
1653 0 0   0   0 sub moresib { $_[0]->{moresib} || 0 }
1654 0 0   0   0 sub parent { $_[0]->{parent} || 0 }
1655 0 0   0   0 sub ppaddr { $_[0]->{ppaddr} || 0 }
1656 0 0   0   0 sub targ { $_[0]->{targ} || 0 }
1657 0 0   0   0 sub flags { $_[0]->{flags} || 0 }
1658 0 0   0   0 sub private { $_[0]->{private} || 0 }
1659             sub rettype { $_[0]->{rettype} || 0 }
1660              
1661             package B::C;
1662              
1663       0 0   # dummy for B::C, only needed for B::CC
1664             sub label {}
1665              
1666             # save alternate ops if defined, and also add labels (needed for B::CC)
1667 0     0 0 0 sub do_labels ($$@) {
1668 0         0 my $op = shift;
1669 0         0 my $level = shift;
1670 55     55   676 for my $m (@_) {
  55         206  
  55         217975  
1671 0 0       0 no strict 'refs';
1672 0 0 0     0 my $mo = $op->$m if $m;
1673 0         0 if ( $mo and $$mo ) {
1674 0 0 0     0 label($mo);
      0        
      0        
1675             $mo->save($level) if $m ne 'first'
1676             or ($op->flags & 4
1677             and !($op->name eq 'const' and $op->flags & 64)); #OPpCONST_BARE has no first
1678             }
1679             }
1680             }
1681              
1682 0     0   0 sub B::UNOP::save {
1683 0         0 my ( $op, $level ) = @_;
1684 0 0       0 my $sym = objsym($op);
1685 0 0       0 return $sym if defined $sym;
1686 0         0 $level = 0 unless $level;
1687 0         0 $unopsect->comment("$opsect_common, first");
  0         0  
1688 0 0       0 $unopsect->add( sprintf( "%s, s\\_%x", $op->_save_common, ${ $op->first } ) );
1689 0         0 $unopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1690 0 0       0 my $ix = $unopsect->index;
1691             $init->add( sprintf( "unop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1692 0         0 unless $B::C::optimize_ppaddr;
1693 0 0 0     0 $sym = savesym( $op, "(OP*)&unop_list[$ix]" );
      0        
1694 0         0 if ($op->name eq 'method' and $op->first and $op->first->name eq 'const') {
1695 0 0 0     0 my $method = svop_name($op->first);
1696 0         0 if (!$method and $ITHREADS) {
1697             $method = padop_name($op->first, curcv); # XXX (curpad[targ])
1698 0 0 0     0 }
1699             warn "method -> const $method\n" if $debug{pkg} and $ITHREADS;
1700 0 0       0 #324,#326 need to detect ->(maybe::next|maybe|next)::(method|can)
    0          
1701 0 0       0 if ($method =~ /^(maybe::next|maybe|next)::(method|can)$/) {
1702 0         0 warn "mark \"$1\" for method $method\n" if $debug{pkg};
1703 0         0 mark_package($1, 1);
1704             mark_package("mro", 1);
1705             } # and also the old 5.8 NEXT|EVERY with non-fixed method names und subpackages
1706 0 0       0 elsif ($method =~ /^(NEXT|EVERY)::/) {
1707 0         0 warn "mark \"$1\" for method $method\n" if $debug{pkg};
1708 0 0       0 mark_package($1, 1);
1709             mark_package("NEXT", 1) if $1 ne "NEXT";
1710             }
1711 0         0 }
1712 0         0 do_labels ($op, $level+1, 'first');
1713             $sym;
1714             }
1715              
1716 0     0 0 0 sub is_constant {
1717 0 0       0 my $s = shift;
1718 0         0 return 1 if $s =~ /^(&sv_list|\-?\d+|Nullsv)/; # not gv_list, hek
1719             return 0;
1720             }
1721              
1722 0     0   0 sub B::UNOP_AUX::save {
1723 0         0 my ( $op, $level ) = @_;
1724 0 0       0 my $sym = objsym($op);
1725 0 0       0 return $sym if defined $sym;
1726 0 0       0 $level = 0 unless $level;
1727             my @aux_list = $op->name eq 'multideref'
1728             ? $op->aux_list_thr # our own version. GH#283, GH#341
1729 0         0 : $op->aux_list;
1730 0         0 my $auxlen = scalar @aux_list;
1731 0         0 $unopauxsect->comment("$opsect_common, first, aux");
1732             my $ix = $unopauxsect->index + 1;
1733             $unopauxsect->add(
1734 0         0 sprintf("%s, s\\_%x, %s+1",
  0         0  
1735 0 0       0 $op->_save_common, ${ $op->first }, "unopaux_item${ix}"));
1736             $unopauxsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1737 0         0 # This cannot be a section, as the number of elements is variable
1738 0 0       0 my $i = 1;
1739             my $s = "Static UNOP_AUX_item unopaux_item".$ix."[] = { /* ".$op->name." */\n\t"
1740 0         0 .($C99?"{.uv=$auxlen}":$auxlen). " \t/* length prefix */\n";
1741 0         0 my $action = 0;
1742 0 0       0 for my $item (@aux_list) {
1743             unless (ref $item) {
1744 0         0 # symbolize MDEREF and SIGNATURE actions and flags, just for the comments
1745 0 0       0 my $cmt = 'action';
1746 0 0       0 if ($verbose) {
    0          
1747 0         0 if ($op->name eq 'multideref') {
1748 0 0       0 my $act = $item & 0xf; # MDEREF_ACTION_MASK
1749 0 0       0 $cmt = 'AV_pop_rv2av_aelem' if $act == 1;
1750 0 0       0 $cmt = 'AV_gvsv_vivify_rv2av_aelem' if $act == 2;
1751 0 0       0 $cmt = 'AV_padsv_vivify_rv2av_aelem' if $act == 3;
1752 0 0       0 $cmt = 'AV_vivify_rv2av_aelem' if $act == 4;
1753 0 0       0 $cmt = 'AV_padav_aelem' if $act == 5;
1754 0 0       0 $cmt = 'AV_gvav_aelem' if $act == 6;
1755 0 0       0 $cmt = 'HV_pop_rv2hv_helem' if $act == 8;
1756 0 0       0 $cmt = 'HV_gvsv_vivify_rv2hv_helem' if $act == 9;
1757 0 0       0 $cmt = 'HV_padsv_vivify_rv2hv_helem' if $act == 10;
1758 0 0       0 $cmt = 'HV_vivify_rv2hv_helem' if $act == 11;
1759 0 0       0 $cmt = 'HV_padhv_helem' if $act == 12;
1760 0         0 $cmt = 'HV_gvhv_helem' if $act == 13;
1761 0 0       0 my $idx = $item & 0x30; # MDEREF_INDEX_MASK
1762 0 0       0 $cmt .= '' if $idx == 0x0;
1763 0 0       0 $cmt .= ' INDEX_const' if $idx == 0x10;
1764 0 0       0 $cmt .= ' INDEX_padsv' if $idx == 0x20;
1765             $cmt .= ' INDEX_gvsv' if $idx == 0x30;
1766             }
1767 0         0 elsif ($op->name eq 'signature') {
1768 0 0       0 my $act = $item & 0xf; # SIGNATURE_ACTION_MASK
1769 0 0       0 $cmt = 'reload' if $act == 0;
1770 0 0       0 $cmt = 'end' if $act == 1;
1771 0 0       0 $cmt = 'padintro' if $act == 2;
1772 0 0       0 $cmt = 'arg' if $act == 3;
1773 0 0       0 $cmt = 'arg_default_none' if $act == 4;
1774 0 0       0 $cmt = 'arg_default_undef' if $act == 5;
1775 0 0       0 $cmt = 'arg_default_0' if $act == 6;
1776 0 0       0 $cmt = 'arg_default_1' if $act == 7;
1777 0 0       0 $cmt = 'arg_default_iv' if $act == 8;
1778 0 0       0 $cmt = 'arg_default_const' if $act == 9;
1779 0 0       0 $cmt = 'arg_default_padsv' if $act == 10;
1780 0 0       0 $cmt = 'arg_default_gvsv' if $act == 11;
1781 0 0       0 $cmt = 'arg_default_op' if $act == 12;
1782 0 0       0 $cmt = 'array' if $act == 13;
1783 0         0 $cmt = 'hash' if $act == 14;
1784 0 0       0 my $idx = $item & 0x3F; # SIGNATURE_MASK
1785 0 0       0 $cmt .= '' if $idx == 0x0;
1786 0 0       0 $cmt .= ' flag skip' if $idx == 0x10;
1787             $cmt .= ' flag ref' if $idx == 0x20;
1788 0         0 } else {
1789             die "Unknown UNOP_AUX op {$op->name}";
1790             }
1791 0         0 }
1792 0 0       0 $action = $item;
1793 0 0       0 warn "{$op->name} action $action $cmt\n" if $debug{hv};
1794             $s .= ($C99 ? sprintf("\t,{.uv=0x%x} \t/* %s: %u */\n", $item, $cmt, $item)
1795             : sprintf("\t,0x%x \t/* %s: %u */\n", $item, $cmt, $item));
1796             } else {
1797             # const and sv already at compile-time, gv deferred to init-time.
1798             # testcase: $a[-1] -1 as B::IV not as -1
1799             # hmm, if const ensure that candidate CONSTs have been HEKified. (pp_multideref assertion)
1800             # || SvTYPE(keysv) >= SVt_PVMG
1801             # || !SvOK(keysv)
1802             # || SvROK(keysv)
1803 0 0       0 # || SvIsCOW_shared_hash(keysv));
1804 0 0       0 my $constkey = ($action & 0x30) == 0x10 ? 1 : 0;
1805 0 0       0 my $itemsym = $item->save("unopaux_item".$ix."[".$i."]" . ($constkey ? " const" : ""));
1806 0 0       0 if (is_constant($itemsym)) {
    0          
1807 0         0 if (ref $item eq 'B::IV') {
1808 0 0       0 my $iv = $item->IVX;
1809             $s .= ($C99 ? "\t,{.iv=$iv}\n"
1810             : "\t,PTR2IV($iv)\n");
1811 0         0 } elsif (ref $item eq 'B::UV') { # also for PAD_OFFSET
1812 0 0       0 my $uv = $item->UVX;
1813             $s .= ($C99 ? "\t,{.uv=$uv}\n"
1814             : "\t,PTR2IV($uv)\n");
1815 0 0       0 } else { # SV
1816             $s .= ($C99 ? "\t,{.sv=$itemsym}\n"
1817             : "\t,PTR2UV($itemsym)\n");
1818             }
1819             } else {
1820 0 0       0 # gv or other late inits
1821             $s .= ($C99 ? "\t,{.sv=Nullsv} \t/* $itemsym */\n"
1822 0         0 : "\t,0 \t/* $itemsym */\n");
1823             $init->add("unopaux_item".$ix."[".$i."].sv = (SV*)$itemsym;");
1824             }
1825 0         0 }
1826             $i++;
1827 0         0 }
1828 0 0       0 $decl->add($s."};");
1829             $init->add( sprintf( "unopaux_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1830 0         0 unless $B::C::optimize_ppaddr;
1831 0         0 $sym = savesym( $op, "(OP*)&unopaux_list[$ix]" );
1832             push @B::C::static_free, $sym;
1833 0         0 # $free->add(" ($sym)->op_type = OP_NULL;");
1834 0         0 do_labels ($op, $level+1, 'first');
1835             $sym;
1836             }
1837              
1838             # cannot save it statically in a sect. need the class (ref) and the ppaddr
1839             #sub B::XOP::save {
1840             # my ( $op, $level ) = @_;
1841             # my $sym = objsym($op);
1842             # return $sym if defined $sym;
1843             # # which class
1844             # $binopsect->comment("$opsect_common, first, last");
1845             # $binopsect->add(
1846             # sprintf( "%s, s\\_%x, s\\_%x",
1847             # $op->_save_common,
1848             # ${ $op->first },
1849             # ${ $op->last } ));
1850             # $binopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1851             # my $ix = $binopsect->index;
1852             # $init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1853             # unless $B::C::optimize_ppaddr;
1854             # $sym = savesym( $op, "(OP*)&binop_list[$ix]" );
1855             # do_labels ($op, $level+1, 'first', 'last');
1856             # $sym;
1857             #}
1858              
1859 0     0   0 sub B::BINOP::save {
1860 0         0 my ( $op, $level ) = @_;
1861 0 0       0 my $sym = objsym($op);
1862             return $sym if defined $sym;
1863             #return B::XOP::save(@_) if $op->type == $OP_CUSTOM;
1864 0 0       0  
1865 0         0 $level = 0 unless $level;
1866             $binopsect->comment("$opsect_common, first, last");
1867             $binopsect->add(
1868             sprintf( "%s, s\\_%x, s\\_%x",
1869 0         0 $op->_save_common,
1870 0         0 ${ $op->first },
  0         0  
1871 0 0       0 ${ $op->last } ));
1872 0         0 $binopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1873 0         0 my $ix = $binopsect->index;
1874 0 0       0 my $ppaddr = $op->ppaddr;
1875 0         0 if ($op->type == $OP_CUSTOM) {
1876 0 0 0     0 my $ptr = $$op;
      0        
1877 0 0       0 if ($] >= 5.019003 and ($op->name eq 'Devel_Peek_Dump' or $op->name eq 'Dump')){
1878 0 0       0 warn "custom op Devel_Peek_Dump\n" if $verbose;
1879             $decl->add('
1880             static void
1881             S_do_dump(pTHX_ SV *const sv, I32 lim)
1882             {
1883             dVAR;
1884             SV *pv_lim_sv = get_svs("Devel::Peek::pv_limit", 0);
1885             const STRLEN pv_lim = pv_lim_sv ? SvIV(pv_lim_sv) : 0;
1886             SV *dumpop = get_svs("Devel::Peek::dump_ops", 0);
1887             const U16 save_dumpindent = PL_dumpindent;
1888             PL_dumpindent = 2;
1889             do_sv_dump(0, Perl_debug_log, sv, 0, lim,
1890             (bool)(dumpop && SvTRUE(dumpop)), pv_lim);
1891             PL_dumpindent = save_dumpindent;
1892             }
1893             static OP *
1894             S_pp_dump(pTHX)
1895             {
1896             dSP;
1897             const I32 lim = PL_op->op_private == 2 ? (I32)POPi : 4;
1898             dPOPss;
1899             S_do_dump(aTHX_ sv, lim);
1900             RETPUSHUNDEF;
1901 0         0 }') unless $B::C::Devel_Peek_Dump_added;
1902 0         0 $ppaddr = 'S_pp_dump';
1903 0         0 $B::C::Devel_Peek_Dump_added++;
1904             $init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $ppaddr ));
1905 0 0       0 } else {
1906 0         0 warn "Warning: Unknown custom op ".$op->name."\n" if $verbose;
1907 0         0 $ppaddr = sprintf('Perl_custom_op_xop(aTHX_ INT2PTR(OP*, 0x%x))', $$op);
1908             $init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $ppaddr ));
1909             }
1910 0 0       0 } else {
1911             $init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $ppaddr ) )
1912             unless $B::C::optimize_ppaddr;
1913 0         0 }
1914 0         0 $sym = savesym( $op, "(OP*)&binop_list[$ix]" );
1915 0         0 do_labels ($op, $level+1, 'first', 'last');
1916             $sym;
1917             }
1918              
1919 0     0   0 sub B::LISTOP::save {
1920 0         0 my ( $op, $level ) = @_;
1921 0 0       0 my $sym = objsym($op);
1922 0 0       0 return $sym if defined $sym;
1923 0         0 $level = 0 unless $level;
1924             $listopsect->comment("$opsect_common, first, last");
1925             $listopsect->add(
1926             sprintf( "%s, s\\_%x, s\\_%x",
1927 0         0 $op->_save_common,
1928 0         0 ${ $op->first },
  0         0  
1929 0 0       0 ${ $op->last } ));
1930 0         0 $listopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1931 0 0       0 my $ix = $listopsect->index;
1932             $init->add( sprintf( "listop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1933 0         0 unless $B::C::optimize_ppaddr;
1934 0 0 0     0 $sym = savesym( $op, "(OP*)&listop_list[$ix]" );
    0          
1935             if ($op->type == $OP_DBMOPEN) {
1936 0         0 # resolves it at compile-time, not at run-time
1937 0 0       0 mark_package('AnyDBM_File'); # to save $INC{AnyDBM_File}
1938 0         0 require AnyDBM_File unless $savINC{'AnyDBM_File.pm'};
1939 0         0 $curINC{'AnyDBM_File.pm'} = $INC{'AnyDBM_File.pm'};
1940 0         0 AnyDBM_File->import; # strip the @ISA
1941 0         0 my $dbm = $AnyDBM_File::ISA[0]; # take the winner (only)
  0         0  
1942 0         0 svref_2object( \&{"$dbm\::bootstrap"} )->save;
  0         0  
1943 0         0 svref_2object( \&{"$dbm\::TIEHASH"} )->save; # called by pp_dbmopen
1944             $curINC{$dbm.".pm"} = $INC{$dbm.".pm"};
1945             } elsif ($op->type == $OP_FORMLINE and $B::C::const_strings) { # -O3 ~
1946 0         0 # non-static only for all const strings containing ~ #277
1947 0         0 my $sv;
1948 0         0 my $fop = $op;
1949 0   0     0 my $svop = $op->first;
1950 0 0 0     0 while ($svop != $op and ref($svop) ne 'B::NULL') {
1951 0         0 if ($svop->name eq 'const' and $svop->can('sv')) {
1952             $sv = $svop->sv;
1953 0 0 0     0 }
      0        
      0        
1954 0         0 if ($sv and $sv->can("PV") and $sv->PV and $sv->PV =~ /~/m) {
1955 0 0       0 local $B::C::const_strings;
1956 0         0 warn "force non-static formline arg ",cstring($sv->PV),"\n" if $debug{pv};
1957             $svop->save($level, "svop const");
1958 0         0 }
1959             $svop = $svop->next;
1960             }
1961 0         0 }
1962 0         0 do_labels ($op, $level+1, 'first', 'last');
1963             $sym;
1964             }
1965              
1966 0     0   0 sub B::LOGOP::save {
1967 0         0 my ( $op, $level ) = @_;
1968 0 0       0 my $sym = objsym($op);
1969 0 0       0 return $sym if defined $sym;
1970 0         0 $level = 0 unless $level;
1971             $logopsect->comment("$opsect_common, first, other");
1972             $logopsect->add(
1973             sprintf( "%s, s\\_%x, s\\_%x",
1974 0         0 $op->_save_common,
1975 0         0 ${ $op->first },
  0         0  
1976 0 0       0 ${ $op->other } ));
1977 0         0 $logopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
1978 0 0       0 my $ix = $logopsect->index;
1979             $init->add( sprintf( "logop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
1980 0         0 unless $B::C::optimize_ppaddr;
1981 0         0 $sym = savesym( $op, "(OP*)&logop_list[$ix]" );
1982 0         0 do_labels ($op, $level+1, 'first', 'other');
1983             $sym;
1984             }
1985              
1986 0     0   0 sub B::LOOP::save {
1987 0         0 my ( $op, $level ) = @_;
1988 0 0       0 my $sym = objsym($op);
1989             return $sym if defined $sym;
1990 0 0       0  
1991             $level = 0 unless $level;
1992             #warn sprintf("LOOP: redoop %s, nextop %s, lastop %s\n",
1993             # peekop($op->redoop), peekop($op->nextop),
1994 0         0 # peekop($op->lastop)) if $debug{op};
1995             $loopsect->comment("$opsect_common, first, last, redoop, nextop, lastop");
1996             $loopsect->add(
1997             sprintf(
1998             "%s, s\\_%x, s\\_%x, s\\_%x, s\\_%x, s\\_%x",
1999 0         0 $op->_save_common,
2000 0         0 ${ $op->first },
2001 0         0 ${ $op->last },
2002 0         0 ${ $op->redoop },
2003 0         0 ${ $op->nextop },
  0         0  
2004             ${ $op->lastop }
2005             )
2006 0 0       0 );
2007 0         0 $loopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2008 0 0       0 my $ix = $loopsect->index;
2009             $init->add( sprintf( "loop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2010 0         0 unless $B::C::optimize_ppaddr;
2011 0         0 $sym = savesym( $op, "(OP*)&loop_list[$ix]" );
2012 0         0 do_labels($op, $level+1, qw(first last redoop nextop lastop));
2013             $sym;
2014             }
2015              
2016 0     0   0 sub B::METHOP::save {
2017 0         0 my ( $op, $level ) = @_;
2018 0 0       0 my $sym = objsym($op);
2019 0 0       0 return $sym if defined $sym;
2020 0         0 $level = 0 unless $level;
2021 0 0       0 $methopsect->comment("$opsect_common, first, rclass");
2022 0 0       0 my $union = $op->name eq 'method' ? "{.op_first=(OP*)%s}" : "{.op_meth_sv=(SV*)%s}";
2023 0 0       0 $union = "%s" unless $C99;
2024 0         0 my $s = "%s, $union, ". ($ITHREADS ? "(PADOFFSET)%s" : "(SV*)%s"); # rclass
2025 0 0       0 my $ix = $methopsect->index + 1;
2026 0 0       0 my $rclass = $ITHREADS ? $op->rclass : $op->rclass->save("op_rclass_sv");
2027 0         0 if ($rclass =~ /^&sv_list/) {
2028             $init->add( sprintf( "SvREFCNT_inc_simple_NN(%s); /* methop_list[%d].op_rclass_sv */",
2029             $rclass, $ix ));
2030             # Put this simple PV into the PL_stashcache, it has no STASH,
2031             # and initialize the method cache.
2032 0         0 # TODO: backref magic for next, init the next::method cache
2033             $init->add( sprintf( "Perl_mro_method_changed_in(aTHX_ gv_stashsv(%s, GV_ADD));",
2034             $rclass ));
2035 0 0       0 }
2036 0 0       0 my $first = $op->name eq 'method' ? $op->first->save : $op->meth_sv->save;
2037 0         0 if ($first =~ /^&sv_list/) {
2038             $init->add( sprintf( "SvREFCNT_inc_simple_NN(%s); /* methop_list[%d].op_meth_sv */",
2039             $first, $ix ));
2040 0 0 0     0 }
2041 0         0 $first = 'NULL' if !$C99 and $first eq 'Nullsv';
2042 0 0       0 $methopsect->add(sprintf($s, $op->_save_common, $first, $rclass));
2043 0 0       0 $methopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2044             $init->add( sprintf( "methop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2045 0         0 unless $B::C::optimize_ppaddr;
2046 0 0       0 $sym = savesym( $op, "(OP*)&methop_list[$ix]" );
2047 0         0 if ($op->name eq 'method') {
2048             do_labels($op, $level+1, 'first', 'rclass');
2049 0         0 } else {
2050             do_labels($op, $level+1, 'meth_sv', 'rclass');
2051 0         0 }
2052             $sym;
2053             }
2054              
2055 0     0   0 sub B::PVOP::save {
2056 0         0 my ( $op, $level ) = @_;
2057 0 0       0 my $sym = objsym($op);
2058 0 0       0 return $sym if defined $sym;
2059             $level = 0 unless $level;
2060 0         0 # op_pv must be dynamic
2061 0         0 $pvopsect->comment("$opsect_common, pv");
2062 0 0       0 $pvopsect->add( sprintf( "%s, NULL", $op->_save_common ) );
2063 0         0 $pvopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2064 0 0       0 my $ix = $pvopsect->index;
2065             $init->add( sprintf( "pvop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2066 0         0 unless $B::C::optimize_ppaddr;
2067             my ($cstring,$cur,$utf8) = strlen_flags($op->pv); # utf8 in op_private as OPpPV_IS_UTF8 (0x80)
2068 0         0 # do not use savepvn here #362
2069 0         0 $init->add( sprintf( "pvop_list[%d].op_pv = savesharedpvn(%s, %u);", $ix, $cstring, $cur ));
2070             savesym( $op, "(OP*)&pvop_list[$ix]" );
2071             }
2072              
2073             # XXX Until we know exactly the package name for a method_call
2074             # we improve the method search heuristics by maintaining this mru list.
2075 0 0   0 0 0 sub push_package ($) {
2076 0         0 my $p = shift or return;
2077 0 0 0     0 warn "save package_pv \"$package_pv\" for method_name from @{[(caller(1))[3]]}\n"
  0   0     0  
2078 0 0       0 if $debug{cv} or $debug{pkg} and !grep { $p eq $_ } @package_pv;
  0         0  
2079 0         0 @package_pv = grep { $p ne $_ } @package_pv if @package_pv; # remove duplicates at the end
2080 0         0 unshift @package_pv, $p; # prepend at the front
2081             mark_package($p);
2082             }
2083              
2084             # method_named is in 5.6.1
2085 0     0 0 0 sub method_named {
2086 0 0       0 my $name = shift;
2087 0         0 return unless $name;
2088 0 0       0 my $cop = shift;
2089             my $loc = $cop ? " at ".$cop->file." line ".$cop->line : "";
2090             # Note: the pkg PV is unacessible(?) at PL_stack_base+TOPMARK+1.
2091             # But it is also at the const or padsv after the pushmark, before all args.
2092             # See L
2093 0 0       0 # We check it in op->_save_common
2094 0         0 if (ref($name) eq 'B::CV') {
2095 0         0 warn $name;
2096             return $name;
2097 0         0 }
2098 0         0 my $method;
2099 55     55   673 for ($package_pv, @package_pv, 'main') {
  55         164  
  55         1045272  
2100 0 0       0 no strict 'refs';
2101 0         0 next unless defined $_;
2102 0 0       0 $method = $_ . '::' . $name;
2103 0 0       0 if (defined(&$method)) {
2104 0         0 warn sprintf( "Found &%s::%s\n", $_, $name ) if $debug{cv};
2105 0         0 $include_package{$_} = 1; # issue59
2106 0         0 mark_package($_, 1);
2107             last;
2108 0 0       0 } else {
2109 0 0       0 if (my $parent = try_isa($_,$name)) {
2110 0         0 warn sprintf( "Found &%s::%s\n", $parent, $name ) if $debug{cv};
2111 0         0 $method = $parent . '::' . $name;
2112 0         0 $include_package{$parent} = 1;
2113             last;
2114 0 0       0 }
2115             warn "no definition for method_name \"$method\"\n" if $debug{cv};
2116             }
2117             }
2118             #my $b = $Config{archname}."/B\.pm";
2119             #if ($name !~ /^tid|can|isa|pmreplroot$/ and $loc !~ m/$b line / and $package_pv !~ /^B::/) {
2120             # return undef if $ITHREADS;
2121 0 0       0 #}
2122 0 0       0 $method = $name unless $method;
2123 0 0       0 if (exists &$method) { # Do not try to save non-existing methods
2124 0         0 warn "save method_name \"$method\"$loc\n" if $debug{cv};
  0         0  
2125             return svref_2object( \&{$method} );
2126 0         0 } else {
2127             return 0;
2128             }
2129             }
2130              
2131              
2132             # scalar: pv. list: (stash,pv,sv)
2133             # pads are not named, but may be typed
2134 0     0 0 0 sub padop_name {
2135 0         0 my $op = shift;
2136 0 0 0     0 my $cv = shift;
      0        
2137             if ($op->can('name')
2138             and ($op->name eq 'padsv' or $op->name eq 'method_named'
2139             or ref($op) eq 'B::SVOP')) #threaded
2140 0 0 0     0 {
2141 0 0 0     0 return () if $cv and ref($cv->PADLIST) eq 'B::SPECIAL';
2142             my @c = ($cv and ref($cv) eq 'B::CV' and ref($cv->PADLIST) ne 'B::NULL')
2143 0         0 ? $cv->PADLIST->ARRAY : comppadlist->ARRAY;
2144 0         0 my @types = $c[0]->ARRAY;
2145 0 0       0 my @pad = $c[1]->ARRAY;
2146 0         0 my $ix = $op->can('padix') ? $op->padix : $op->targ;
2147 0         0 my $sv = $pad[$ix];
2148 0 0 0     0 my $t = $types[$ix];
    0          
2149 0 0       0 if (defined($t) and ref($t) ne 'B::SPECIAL') {
    0          
2150             my $pv = $sv->can("PV") ? $sv->PV : ($t->can('PVX') ? $t->PVX : '');
2151 0 0 0     0 # need to fix B for SVpad_TYPEDI without formal STASH
2152 0 0       0 my $stash = (ref($t) eq 'B::PVMG' and ref($t->SvSTASH) ne 'B::SPECIAL') ? $t->SvSTASH->NAME : '';
2153             return wantarray ? ($stash,$pv,$sv) : $pv;
2154 0 0       0 } elsif ($sv) {
2155 0 0       0 my $pv = $sv->PV if $sv->can("PV");
2156 0 0       0 my $stash = $sv->STASH->NAME if $sv->can("STASH");
2157             return wantarray ? ($stash,$pv,$sv) : $pv;
2158             }
2159             }
2160             }
2161              
2162 0     0 0 0 sub svop_name {
2163 0         0 my $op = shift;
2164 0         0 my $cv = shift;
2165 0 0 0     0 my $sv;
2166 0         0 if ($op->can('name') and $op->name eq 'padsv') {
2167 0 0       0 my @r = padop_name($op, $cv);
    0          
2168             return wantarray ? @r : ($r[1] ? $r[1] : $r[0]);
2169 0 0       0 } else {
2170 0 0 0     0 if (!$op->can("sv")) {
2171 0         0 if (ref($op) eq 'B::PMOP' and $op->pmreplroot->can("sv")) {
2172             $sv = $op->pmreplroot->sv;
2173 0 0 0     0 } else {
      0        
      0        
2174             $sv = $op->first->sv unless $op->flags & 4
2175             or ($op->name eq 'const' and $op->flags & 34) or $op->first->can("sv");
2176             }
2177 0         0 } else {
2178             $sv = $op->sv;
2179 0 0 0     0 }
2180 0 0       0 if ($sv and $$sv) {
2181 0 0       0 if ($sv->FLAGS & SVf_ROK) {
2182 0         0 return '' if $sv->isa("B::NULL");
2183 0 0       0 my $rv = $sv->RV;
2184 0         0 if ($rv->isa("B::PVGV")) {
2185 0 0       0 my $o = $rv->IO;
2186             return $o->STASH->NAME if $$o;
2187 0 0       0 }
2188 0         0 return '' if $rv->isa("B::PVMG");
2189             return $rv->STASH->NAME;
2190 0 0       0 } else {
    0          
2191 0 0       0 if ($op->name eq 'gvsv') {
2192             return wantarray ? ($sv->STASH->NAME, $sv->NAME) : $sv->STASH->NAME.'::'.$sv->NAME;
2193 0 0       0 } elsif ($op->name eq 'gv') {
2194             return wantarray ? ($sv->STASH->NAME, $sv->NAME) : $sv->STASH->NAME.'::'.$sv->NAME;
2195 0 0       0 } else {
    0          
2196             return $sv->can('STASH') ? $sv->STASH->NAME
2197             : $sv->can('NAME') ? $sv->NAME : $sv->PV;
2198             }
2199             }
2200             }
2201             }
2202             }
2203              
2204             # return the next COP for file and line info
2205 0     0 0 0 sub nextcop {
2206 0   0     0 my $op = shift;
  0   0     0  
2207 0 0 0     0 while ($op and ref($op) ne 'B::COP' and ref($op) ne 'B::NULL') { $op = $op->next; }
2208             return ($op and ref($op) eq 'B::COP') ? $op : undef;
2209             }
2210              
2211 0     0 0 0 sub svimmortal {
2212 0 0       0 my $sym = shift;
2213 0         0 if ($sym =~ /\(SV\*\)?\&PL_sv_(yes|no|undef|placeholder)/) {
2214             return 1;
2215 0         0 }
2216             return undef;
2217             }
2218              
2219 0     0   0 sub B::SVOP::save {
2220 0         0 my ( $op, $level, $fullname ) = @_;
2221 0 0       0 my $sym = objsym($op);
2222 0 0       0 return $sym if defined $sym;
2223 0         0 $level = 0 unless $level;
2224             my $svsym = 'Nullsv';
2225 0 0 0     0 # XXX moose1 crash with 5.8.5-nt, Cwd::_perl_abs_path also
    0 0        
      0        
      0        
      0        
2226 0         0 if ($op->name eq 'aelemfast' and $op->flags & 128) { #OPf_SPECIAL
2227 0 0       0 $svsym = '&PL_sv_undef'; # pad does not need to be saved
2228             warn sprintf("SVOP->sv aelemfast pad %d\n", $op->flags) if $debug{sv};
2229             } elsif ($op->name eq 'gv' and $op->next and $op->next->name eq 'rv2cv'
2230             and $op->next->next and $op->next->next->name eq 'defined' ) {
2231 0         0 # 96 do not save a gvsv->cv if just checked for defined'ness
2232 0         0 my $gv = $op->sv;
2233 0 0       0 my $gvsv = svop_name($op);
2234 0 0       0 if ($gvsv !~ /^DynaLoader::/) {
2235 0         0 warn "skip saving defined(&$gvsv)\n" if $debug{gv}; # defer to run-time
2236             $svsym = '(SV*)' . $gv->save( 8 ); # ~Save_CV in B::GV::save
2237 0         0 } else {
2238             $svsym = '(SV*)' . $gv->save();
2239             }
2240 0         0 } else {
2241 0         0 my $sv = $op->sv;
2242 0 0       0 $svsym = $sv->save("svop ".$op->name);
    0          
2243 0         0 if ($svsym =~ /^(gv_|PL_.*gv)/) {
2244             $svsym = '(SV*)' . $svsym;
2245 0         0 } elsif ($svsym =~ /^\([SAHC]V\*\)\&sv_list/) {
2246             $svsym =~ s/^\([SAHC]V\*\)//;
2247 0         0 } else {
2248             $svsym =~ s/^\([GAPH]V\*\)/(SV*)/;
2249 0 0       0 }
2250             warn "Error: SVOP: ".$op->name." $sv $svsym" if $svsym =~ /^\(SV\*\)lexwarn/; #322
2251 0 0       0 }
2252 0         0 if ($op->name eq 'method_named') {
2253 0 0       0 my $cv = method_named(svop_or_padop_pv($op), nextcop($op));
2254             $cv->save if $cv;
2255 0         0 }
2256 0 0 0     0 my $is_const_addr = $svsym =~ m/Null|\&/;
2257 0         0 if ($MULTI and svimmortal($svsym)) { # t/testm.sh Test::Pod
2258             $is_const_addr = 0;
2259 0         0 }
2260 0 0       0 $svopsect->comment("$opsect_common, sv");
2261             $svopsect->add(sprintf( "%s, %s",
2262             $op->_save_common, ( $is_const_addr ? $svsym : "Nullsv /* $svsym */" ) )
2263 0 0       0 );
2264 0         0 $svopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2265 0 0       0 my $ix = $svopsect->index;
2266             $init->add( sprintf( "svop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2267 0 0       0 unless $B::C::optimize_ppaddr;
2268             $init->add("svop_list[$ix].op_sv = $svsym;")
2269 0         0 unless $is_const_addr;
2270             savesym( $op, "(OP*)&svop_list[$ix]" );
2271             }
2272              
2273 0     0   0 sub B::PADOP::save {
2274 0         0 my ( $op, $level ) = @_;
2275 0 0       0 my $sym = objsym($op);
2276 0 0       0 return $sym if defined $sym;
2277 0         0 $level = 0 unless $level;
2278 0 0 0     0 my $skip_defined;
    0 0        
      0        
      0        
2279 0         0 if ($op->name eq 'method_named') {
2280 0 0       0 my $cv = method_named(svop_or_padop_pv($op), nextcop($op));
2281             $cv->save if $cv;
2282             } elsif ($op->name eq 'gv' and $op->next and $op->next->name eq 'rv2cv'
2283             and $op->next->next and $op->next->next->name eq 'defined' ) {
2284 0         0 # 96 do not save a gvsv->cv if just checked for defined'ness
2285             $skip_defined++;
2286             }
2287 0 0 0     0 # This is saved by curpad syms at the end. But with __DATA__ handles it is better to save earlier
      0        
2288 0         0 if ($op->name eq 'padsv' or $op->name eq 'gvsv' or $op->name eq 'gv') {
2289 0         0 my @c = comppadlist->ARRAY;
2290 0 0       0 my @pad = $c[1]->ARRAY;
2291 0         0 my $ix = $op->can('padix') ? $op->padix : $op->targ;
2292 0 0 0     0 my $sv = $pad[$ix];
2293 0         0 if ($sv and $$sv) {
2294 0 0 0     0 my $name = padop_name($op, curcv);
2295 0 0       0 if ($skip_defined and $name !~ /^DynaLoader::/) {
2296             warn "skip saving defined(&$name)\n" if $debug{gv}; # defer to run-time
2297 0 0       0 } else {
2298             $sv->save("padop ". ($name ? $name : ''));
2299             }
2300             }
2301 0         0 }
2302 0         0 $padopsect->comment("$opsect_common, padix");
2303 0 0       0 $padopsect->add( sprintf( "%s, %d", $op->_save_common, $op->padix ) );
2304 0         0 $padopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2305 0 0       0 my $ix = $padopsect->index;
2306             $init->add( sprintf( "padop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2307 0         0 unless $B::C::optimize_ppaddr;
2308             savesym( $op, "(OP*)&padop_list[$ix]" );
2309             }
2310              
2311 0     0   0 sub B::COP::save {
2312 0         0 my ( $op, $level ) = @_;
2313 0 0       0 my $sym = objsym($op);
2314             return $sym if defined $sym;
2315 0 0       0  
2316             $level = 0 unless $level;
2317             # we need to keep CvSTART cops, so check $level == 0
2318 0 0 0     0 # what a COP needs to do is to reset the stack, and restore locals
      0        
      0        
2319             if ($optimize_cop and $level and !$op->label
2320 0         0 and ref($prev_op) ne 'B::LISTOP') { # XXX very unsafe!
2321             my $sym = savesym( $op, $op->next->save );
2322 0 0       0 warn sprintf( "Skip COP (0x%x) => %s (0x%x), line %d file %s\n",
2323 0         0 $$op, $sym, $op->next, $op->line, $op->file ) if $debug{cops};
2324             return $sym;
2325             }
2326              
2327             # TODO: if it is a nullified COP we must save it with all cop fields!
2328 0 0       0 warn sprintf( "COP: line %d file %s\n", $op->line, $op->file )
2329             if $debug{cops};
2330              
2331 0         0 # shameless cut'n'paste from B::Deparse
2332 0         0 my ($warn_sv, $isint);
2333 0         0 my $warnings = $op->warnings;
2334 0 0       0 my $is_special = ref($warnings) eq 'B::SPECIAL';
2335 0 0 0     0 my $warnsvcast = $PERL510 ? "(STRLEN*)" : "(SV*)";
    0 0        
    0          
2336 0         0 if ( $is_special && $$warnings == 4 ) { # use warnings 'all';
2337             $warn_sv = 'pWARN_ALL';
2338             }
2339 0         0 elsif ( $is_special && $$warnings == 5 ) { # no warnings 'all';
2340             $warn_sv = 'pWARN_NONE';
2341             }
2342 0         0 elsif ($is_special) { # use warnings;
2343             $warn_sv = 'pWARN_STD';
2344             }
2345             else {
2346             # LEXWARN_on: Original $warnings->save from 5.8.9 was wrong,
2347 0         0 # DUP_WARNINGS copied length PVX bytes.
2348             my $warn = bless $warnings, "B::LEXWARN";
2349 0         0 # TODO: isint here misses already seen lexwarn symbols
2350 0         0 ($warn_sv, $isint) = $warn->save;
2351             my $ix = $copsect->index + 1;
2352 0 0       0 # XXX No idea how a &sv_list[] came up here, a re-used object. Anyway.
2353 0         0 $warn_sv = substr($warn_sv,1) if substr($warn_sv,0,3) eq '&sv';
2354 0 0 0     0 $warn_sv = $warnsvcast.'&'.$warn_sv;
2355             $free->add( sprintf( " cop_list[%d].cop_warnings = NULL;", $ix ) )
2356             if !$B::C::optimize_warn_sv or !$PERL510;
2357             #push @B::C::static_free, sprintf("cop_list[%d]", $ix);
2358             }
2359 0 0 0     0  
2360             my $dynamic_copwarn = ($PERL510 and !$is_special) ? 1 : !$B::C::optimize_warn_sv;
2361 0 0 0     0 # branch feature/gh70-static-lexwarn with PERL_SUPPORT_STATIC_COP
2362             $dynamic_copwarn = 0 if $Config{usecperl} and $] >= 5.022002;
2363              
2364 0         0 # Trim the .pl extension, to print the executable name only.
2365             my $file = $op->file;
2366 0         0 # $file =~ s/\.pl$/.c/;
2367 0 0       0 my $add_label = 0;
    0          
2368 0 0 0     0 if ($PERL512) {
    0 0        
    0 0        
      0        
2369 0         0 if ($ITHREADS and $] >= 5.017) {
2370             $copsect->comment(
2371 0 0       0 "$opsect_common, line, stashoff, file, hints, seq, warnings, hints_hash");
2372             $copsect->add(
2373             sprintf( "%s, %u, " . "%d, %s, %u, " . "%s, %s, NULL",
2374             $op->_save_common, $op->line,
2375             $op->stashoff, "NULL", #hints=0
2376             $op->hints,
2377             ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL'
2378             ));
2379             } elsif ($ITHREADS and $] >= 5.016) {
2380 0         0 # [perl #113034] [PATCH] 2d8d7b1 replace B::COP::stashflags by B::COP::stashlen (5.16.0 only)
2381             $copsect->comment(
2382 0 0       0 "$opsect_common, line, stashpv, file, stashlen, hints, seq, warnings, hints_hash");
    0          
2383             $copsect->add(
2384             sprintf( "%s, %u, " . "%s, %s, %d, %u, " . "%s, %s, NULL",
2385             $op->_save_common, $op->line,
2386             "NULL", "NULL",
2387             # XXX at broken 5.16.0 with B-1.34 we do non-utf8, non-null only (=> negative len),
2388             # 5.16.0 B-1.35 has stashlen, 5.16.1 we will see.
2389             $op->can('stashlen') ? $op->stashlen : length($op->stashpv),
2390             $op->hints,
2391             ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL'
2392             ));
2393 0         0 } elsif ($ITHREADS and $] >= 5.015004 and $] < 5.016) {
2394             $copsect->comment(
2395 0 0       0 "$opsect_common, line, stashpv, file, stashflags, hints, seq, warnings, hints_hash");
2396             $copsect->add(
2397             sprintf( "%s, %u, " . "%s, %s, %d, %u, " . "%s, %s, NULL",
2398             $op->_save_common, $op->line,
2399             "NULL", "NULL",
2400             $op->stashflags, $op->hints,
2401             ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL'
2402             ));
2403             } else {
2404 0         0 # cop_label now in hints_hash (Change #33656)
2405             $copsect->comment(
2406 0 0       0 "$opsect_common, line, stash, file, hints, seq, warn_sv, hints_hash");
    0          
    0          
2407             $copsect->add(
2408             sprintf( "%s, %u, " . "%s, %s, %u, " . "%s, %s, NULL",
2409             $op->_save_common, $op->line,
2410             $ITHREADS ? "NULL" : "Nullhv",# we cannot store this static (attribute exit)
2411             $ITHREADS ? "NULL" : "Nullgv",
2412             $op->hints, ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL'
2413             ));
2414 0 0       0 }
2415 0         0 if ( $op->label ) {
2416             $add_label = 1;
2417             }
2418             }
2419 0         0 elsif ($PERL510) {
2420 0 0       0 $copsect->comment("$opsect_common, line, label, stash, file, hints, seq, warnings, hints_hash");
2421             $copsect->add(sprintf("%s, %u, %s, " . "%s, %s, %u, " . "%u, %s, NULL",
2422             $op->_save_common, $op->line, 'NULL',
2423             "NULL", "NULL",
2424             $op->hints, $op->cop_seq, !$dynamic_copwarn ? $warn_sv : 'NULL'
2425 0 0       0 ));
2426 0         0 if ($op->label) {
2427             $init->add(sprintf( "CopLABEL_set(&cop_list[%d], CopLABEL_alloc(%s));",
2428             $copsect->index, cstring( $op->label ) ));
2429             }
2430             }
2431             else {
2432 0         0 # 5.8 misses cop_io
2433 0 0       0 $copsect->comment("$opsect_common, label, stash, file, seq, arybase, line, warn_sv, io");
    0          
2434             $copsect->add(
2435             sprintf( "%s, %s, %s, %s, %s, %d, %u, %s %s",
2436             $op->_save_common, cstring( $op->label ),
2437             "NULL", "NULL",
2438             ivx($op->cop_seq), $op->arybase,
2439             $op->line, !$dynamic_copwarn ? $warn_sv : 'NULL',
2440             ( $PERL56 ? "" : ", 0" )
2441             ));
2442 0 0       0 }
2443 0         0 $copsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2444 0 0       0 my $ix = $copsect->index;
2445             $init->add( sprintf( "cop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) )
2446             unless $B::C::optimize_ppaddr;
2447 0         0  
2448 0 0 0     0 my $i = 0;
2449 0         0 if ($PERL510 and $op->hints_hash) {
2450 0 0       0 my $hints = $op->hints_hash;
2451 0 0       0 if ($$hints) {
2452 0         0 if (exists $cophhtable{$$hints}) {
2453 0         0 my $cophh = $cophhtable{$$hints};
2454             $init->add(sprintf("CopHINTHASH_set(&cop_list[%d], %s);", $ix, $cophh));
2455 0 0       0 } else {
2456 0         0 my $hint_hv = $hints->HASH if ref $hints eq 'B::RHE';
2457 0         0 my $cophh = sprintf( "cophh%d", scalar keys %cophhtable );
2458 0         0 $cophhtable{$$hints} = $cophh;
2459 0         0 $decl->add(sprintf("Static COPHH *%s;", $cophh));
2460 0         0 for my $k (keys %$hint_hv) {
2461 0         0 my ($ck, $kl, $utf8) = strlen_flags($k);
2462 0 0       0 my $v = $hint_hv->{$k};
2463 0         0 next if $k eq ':'; #skip label, see below
2464 0 0       0 my $val = B::svref_2object( \$v )->save("\$^H{$k}");
2465 0 0       0 if ($utf8) {
2466             $init->add(sprintf("%s = cophh_store_pvn(%s, %s, %d, 0, %s, COPHH_KEY_UTF8);",
2467             $cophh, $i ? $cophh : 'NULL', $ck, $kl, $val));
2468 0 0       0 } else {
2469             $init->add(sprintf("%s = cophh_store_pvs(%s, %s, %s, 0);",
2470             $cophh, $i ? $cophh : 'NULL', $ck, $val));
2471             }
2472             #$init->add(sprintf("%s->refcounted_he_refcnt--;", $cophh));
2473             #if (!$ITHREADS) {
2474             # $init->add(sprintf("HEK_FLAGS(%s->refcounted_he_hek) |= HVhek_STATIC;", $cophh));
2475             #}
2476             #if ($PERL522 and !$ITHREADS) { # breaks issue220
2477             # $init->add(sprintf("unshare_hek_hek(%s->refcounted_he_hek);", $cophh));
2478 0         0 #}
2479             $i++;
2480 0         0 }
2481             $init->add(sprintf("CopHINTHASH_set(&cop_list[%d], %s);", $ix, $cophh));
2482             }
2483             }
2484 0 0       0 }
2485             if ($add_label) {
2486 0         0 # test 29 and 15,16,21. 44,45
2487 0 0 0     0 my ($cstring, $cur, $utf8) = strlen_flags($op->label);
    0          
    0          
2488 0 0 0     0 if ($] >= 5.015001) { # officially added with 5.15.1 aebc0cbee
2489 0         0 warn "utf8 label $cstring" if $utf8 and $verbose;
2490             $init->add(sprintf("Perl_cop_store_label(aTHX_ &cop_list[%d], %s, %u, %s);",
2491             $copsect->index, $cstring, $cur, $utf8));
2492 0         0 } elsif ($] > 5.013004) {
2493             $init->add(sprintf("Perl_store_cop_label(aTHX_ &cop_list[%d], %s, %u, %s);",
2494             $copsect->index, $cstring, $cur, $utf8));
2495 0 0       0 } elsif (!($^O =~ /^(MSWin32|AIX)$/ or $ENV{PERL_DL_NONLAZY})) {
2496 0         0 warn "Warning: Overwrote hints_hash with label\n" if $i;
2497 0         0 my $ix = $copsect->index;
2498             $init->add(
2499             sprintf("cop_list[%d].cop_hints_hash = Perl_store_cop_label(aTHX_ cop_list[%d].cop_hints_hash, %s);",
2500             $ix, $ix, $cstring));
2501             }
2502             }
2503 0 0 0     0  
      0        
2504 0         0 if ($PERL510 and !$is_special and !$isint) {
2505 0         0 my $copw = $warn_sv;
2506             $copw =~ s/^\(STRLEN\*\)&//;
2507             # on cv_undef (scope exit, die, Attribute::Handlers, ...) CvROOT and kids are freed.
2508 0 0       0 # so lexical cop_warnings need to be dynamic.
2509 0         0 if ($copw) {
2510             my $dest = "cop_list[$ix].cop_warnings";
2511             # with DEBUGGING savepvn returns ptr + PERL_MEMORY_DEBUG_HEADER_SIZE
2512             # which is not the address which will be freed in S_cop_free.
2513             # Need to use old-style PerlMemShared_, see S_cop_free in op.c (#362)
2514 0         0 # lexwarn might be also be STRLEN* 0
2515 0         0 $init->no_split;
2516             $init->add("#ifdef PERL_SUPPORT_STATIC_COP /* so far cperl only */",
2517             "$dest = $warn_sv;",
2518             "#else",
2519             sprintf("%s = (STRLEN*)savesharedpvn((const char*)%s, sizeof(%s));",
2520             $dest, $copw, $copw),
2521 0         0 "#endif");
2522             $init->split;
2523             }
2524 0 0       0 } else {
2525             $init->add( sprintf( "cop_list[%d].cop_warnings = %s;", $ix, $warn_sv ) )
2526             unless $B::C::optimize_warn_sv;
2527             }
2528 0 0       0 #push @B::C::static_free, "cop_list[$ix]" if $ITHREADS;
2529 0         0 if (!$B::C::optimize_cop) {
2530 0         0 my $stash = savestashpv($op->stashpv);
2531 0 0       0 $init->add(sprintf( "CopSTASH_set(&cop_list[%d], %s);", $ix, $stash ));
2532 0 0       0 if (!$ITHREADS) {
2533 0         0 if ($B::C::const_strings) {
2534             my $constpv = constpv($file);
2535             # define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv))
2536 0 0       0 # cache gv_fetchfile
2537 0         0 if ( !$copgvtable{$constpv} ) {
2538 0         0 $copgvtable{$constpv} = $gv_index++;
2539             $init->add( sprintf( "gv_list[%d] = gv_fetchfile(%s);", $copgvtable{$constpv}, $constpv ) );
2540             }
2541 0         0 $init->add( sprintf( "CopFILEGV_set(&cop_list[%d], gv_list[%d]); /* %s */",
2542             $ix, $copgvtable{$constpv}, cstring($file) ) );
2543             #$init->add(sprintf( "CopFILE_set(&cop_list[%d], %s);", $ix, constpv($file) ));
2544 0         0 } else {
2545             $init->add(sprintf( "CopFILE_set(&cop_list[%d], %s);", $ix, cstring($file) ));
2546             }
2547 0         0 } else { # cv_undef e.g. in bproto.t and many more core tests with threads
2548             $init->add(sprintf( "CopFILE_set(&cop_list[%d], %s);", $ix, cstring($file) ));
2549             }
2550             }
2551              
2552 0 0       0 # our root: store all packages from this file
2553 0 0       0 if (!$mainfile) {
2554             $mainfile = $op->file if $op->stashpv eq 'main';
2555 0 0 0     0 } else {
2556             mark_package($op->stashpv) if $mainfile eq $op->file and $op->stashpv ne 'main';
2557 0         0 }
2558             savesym( $op, "(OP*)&cop_list[$ix]" );
2559             }
2560              
2561             # if REGCOMP can be called in init or deferred in init1
2562 0     0 0 0 sub re_does_swash {
2563             my ($qstr, $pmflags) = @_;
2564 0 0 0     0 # SWASHNEW, now needing a multideref GV. 0x5000000 is just a hack. can be more
      0        
2565             if (($] >= 5.021006 and ($pmflags & 0x5000000 == 0x5000000))
2566             # or any unicode property (#253). Note: \p{} breaks #242
2567             or ($qstr =~ /\\P\{/)
2568             )
2569 0         0 {
2570             return 1;
2571 0         0 } else {
2572             return 0;
2573             }
2574             }
2575              
2576 0     0   0 sub B::PMOP::save {
2577 0         0 my ( $op, $level, $fullname ) = @_;
2578 0         0 my ($replrootfield, $replstartfield, $gvsym) = ('NULL', 'NULL');
2579 0 0       0 my $sym = objsym($op);
2580             return $sym if defined $sym;
2581 0 0       0 # 5.8.5-thr crashes here (7) at pushre
2582 0 0 0     0 my $pushre = $PERL5257 ? "split" : "pushre";
      0        
2583 0         0 if ($] < 5.008008 and $ITHREADS and $$op < 256) { # B bug. split->first->pmreplroot = 0x1
2584 0         0 die "Internal B::walkoptree error: invalid PMOP for pushre\n";
2585             return;
2586 0 0       0 }
2587 0         0 $level = 0 unless $level;
2588 0         0 my $replroot = $op->pmreplroot;
2589 0         0 my $replstart = $op->pmreplstart;
2590             my $ppaddr = $op->ppaddr;
2591              
2592 0 0       0 # under ithreads, OP_PUSHRE.op_replroot is an integer. multi not.
2593 0 0 0     0 $replrootfield = sprintf( "s\\_%x", $$replroot ) if ref $replroot;
    0 0        
2594 0 0       0 if ( $ITHREADS && $op->name eq $pushre ) {
2595 0         0 warn "PMOP::save saving a pp_$pushre as int ${replroot}\n" if $debug{gv};
2596             $replrootfield = "INT2PTR(OP*,${replroot})";
2597             }
2598             elsif (ref $replroot && $$replroot) {
2599             # OP_PUSHRE (a mutated version of OP_MATCH for the regexp
2600             # argument to a split) stores a GV in op_pmreplroot instead
2601 0 0       0 # of a substitution syntax tree. We don't want to walk that...
2602 0 0       0 if ( $op->name eq $pushre ) {
2603 0         0 warn "PMOP::save saving a pp_$pushre with GV $gvsym\n" if $debug{gv};
2604 0         0 $gvsym = $replroot->save;
2605 0 0       0 $replrootfield = "NULL";
2606             $replstartfield = $replstart->save if $replstart;
2607             }
2608 0 0       0 else {
2609 0         0 $replstart->save if $replstart;
2610 0         0 $replstartfield = saveoptree( "*ignore*", $replroot, $replstart );
2611             $replstartfield =~ s/^hv/(OP*)hv/;
2612             }
2613             }
2614              
2615             # pmnext handling is broken in perl itself, we think. Bad op_pmnext
2616             # fields aren't noticed in perl's runtime (unless you try reset) but we
2617 0 0       0 # segfault when trying to dereference it to find op->op_pmnext->op_type
    0          
2618 0         0 if ($PERL510) {
2619             $pmopsect->comment(
2620             "$opsect_common, first, last, pmoffset, pmflags, pmreplroot, pmreplstart"
2621             );
2622             $pmopsect->add(
2623 0         0 sprintf( "%s, s\\_%x, s\\_%x, %u, 0x%x, {%s}, {%s}",
2624 0 0       0 $op->_save_common, ${ $op->first },
  0         0  
2625             ${ $op->last }, ( $ITHREADS ? $op->pmoffset : 0 ),
2626             $op->pmflags, $replrootfield, $replstartfield
2627 0 0       0 ));
2628 0         0 if ($] >= 5.017) {
2629 0 0 0     0 my $code_list = $op->code_list;
2630             if ($code_list and $$code_list) {
2631 0 0       0 warn sprintf("saving pmop_list[%d] code_list $code_list (?{})\n", $pmopsect->index)
2632 0         0 if $debug{gv};
2633 0 0       0 my $code_op = $code_list->save;
2634             $init->add(sprintf("pmop_list[%d].op_code_list = %s;", # (?{}) code blocks
2635             $pmopsect->index, $code_op)) if $code_op;
2636 0 0       0 warn sprintf("done saving pmop_list[%d] code_list $code_list (?{})\n", $pmopsect->index)
2637             if $debug{gv};
2638             }
2639             }
2640             }
2641             elsif ($PERL56) {
2642             # pmdynflags does not exist as B method. It is only used for PMdf_UTF8 dynamically,
2643 0         0 # if static we set this already in pmflags.
2644             $pmopsect->comment(
2645             "$opsect_common, first, last, pmreplroot, pmreplstart, pmnext, pmregexp, pmflags, pmpermflags, pmdynflags"
2646             );
2647             $pmopsect->add(
2648             sprintf( "%s, s\\_%x, s\\_%x, %s, %s, 0, 0, 0x%x, 0x%x",
2649 0         0 $op->_save_common,
  0         0  
  0         0  
2650             ${ $op->first }, ${ $op->last },
2651             $replrootfield, $replstartfield,
2652             $op->pmflags, $op->pmpermflags, 0 # XXX original 5.6 B::C misses pmdynflags
2653             ));
2654 0         0 } else { # perl5.8.x
2655             $pmopsect->comment(
2656             "$opsect_common, first, last, pmreplroot, pmreplstart, pmoffset, pmflags, pmpermflags, pmdynflags, pmstash"
2657             );
2658             $pmopsect->add(
2659 0         0 sprintf( "%s, s\\_%x, s\\_%x, %s, %s, 0, %u, 0x%x, 0x%x, 0x%x, %s",
2660 0 0       0 $op->_save_common, ${ $op->first },
  0 0       0  
2661             ${ $op->last }, $replrootfield,
2662             $replstartfield, $ITHREADS ? $op->pmoffset : 0,
2663             $op->pmflags, $op->pmpermflags,
2664             $op->pmdynflags, $MULTI ? cstring($op->pmstashpv) : "0"
2665 0 0 0     0 ));
2666 0         0 if (!$MULTI and $op->pmstash) {
2667 0         0 my $stash = $op->pmstash->save;
2668             $init->add( sprintf( "pmop_list[%d].op_pmstash = %s;", $pmopsect->index, $stash ) );
2669             }
2670 0 0       0 }
2671 0         0 $pmopsect->debug( $op->name, $op->flagspv ) if $debug{flags};
2672 0 0       0 my $pm = sprintf( "pmop_list[%d]", $pmopsect->index );
2673             $init->add( sprintf( "%s.op_ppaddr = %s;", $pm, $ppaddr ) )
2674 0         0 unless $B::C::optimize_ppaddr;
2675 0 0       0 my $re = $op->precomp;
2676 0         0 if ( defined($re) ) {
2677 0         0 my $initpm = $init;
2678 0 0       0 $Regexp{$$op} = $op;
    0          
2679             if ($PERL510) {
2680             # TODO minor optim: fix savere( $re ) to avoid newSVpvn;
2681 0         0 # precomp did not set the utf8 flag (#333, #338), fixed with 1.52_01
2682 0         0 my ($qre, $relen, $utf8) = strlen_flags($re);
2683             my $pmflags = $op->pmflags;
2684 0 0 0     0 warn "pregcomp $pm $qre:$relen:$utf8".sprintf(" 0x%x\n",$pmflags)
2685             if $debug{pv} or $debug{gv};
2686 0 0 0     0 # Since 5.13.10 with PMf_FOLD (i) we need to swash_init("utf8::Cased").
2687             if ($] >= 5.013009 and $pmflags & 4) {
2688 0         0 # Note: in CORE utf8::SWASHNEW is demand-loaded from utf8 with Perl_load_module()
2689 0 0 0     0 load_utf8_heavy();
      0        
2690 0         0 if ($PERL518 and !$swash_init and $swash_ToCf) {
2691 0         0 $init->add("PL_utf8_tofold = $swash_ToCf;");
2692             $swash_init++;
2693             }
2694             }
2695             # some pm need early init (242), SWASHNEW needs some late GVs (GH#273)
2696             # esp with 5.22 multideref init. i.e. all \p{} \N{}, \U, /i, ...
2697 0 0 0     0 # But XSLoader and utf8::SWASHNEW itself needs to be early.
      0        
      0        
2698             if (($utf8 and $] >= 5.013009 and ($pmflags & 4 == 4)) # needs SWASHNEW (case fold)
2699             or re_does_swash($qre, $pmflags))
2700 0         0 {
2701 0 0       0 $initpm = $init1;
2702             warn sprintf("deferred PMOP %s %s 0x%x\n", $qre, $fullname, $pmflags) if $debug{sv};
2703 0 0       0 } else {
2704             warn sprintf("normal PMOP %s %s 0x%x\n", $qre, $fullname, $pmflags) if $debug{sv};
2705 0 0 0     0 }
2706 0         0 if ($PERL518 and $op->reflags & RXf_EVAL_SEEN) { # set HINT_RE_EVAL on
2707 0         0 $pmflags |= PMf_EVAL;
2708 0         0 $initpm->no_split;
2709             $initpm->add("{",
2710             " U32 hints_sav = PL_hints;",
2711             " PL_hints |= HINT_RE_EVAL;");
2712 0 0       0 }
2713 0         0 if ($] > 5.008008) { # can do utf8 qr
2714             $initpm->add( # XXX Modification of a read-only value attempted. use DateTime - threaded
2715             sprintf("PM_SETRE(&%s, CALLREGCOMP(newSVpvn_flags(%s, %s, SVs_TEMP|$utf8), 0x%x));",
2716             $pm, $qre, $relen, $pmflags),
2717             sprintf("RX_EXTFLAGS(PM_GETRE(&%s)) = 0x%x;", $pm, $op->reflags ));
2718 0         0 } else {
2719             $initpm->add
2720             ("PM_SETRE(&$pm,",
2721             " CALLREGCOMP(newSVpvn($qre, $relen), ".sprintf("0x%x));", $pmflags),
2722 0 0       0 sprintf("RX_EXTFLAGS(PM_GETRE(&%s)) = 0x%x;", $pm, $op->reflags ));
2723             $initpm->add("SvUTF8_on(PM_GETRE(&$pm));") if $utf8;
2724 0 0 0     0 }
2725 0         0 if ($] >= 5.018 and $op->reflags & RXf_EVAL_SEEN) { # set HINT_RE_EVAL off
2726             $initpm->add(" PL_hints = hints_sav;",
2727 0         0 "}");
2728             $initpm->split();
2729             }
2730             # See toke.c:8964
2731 0 0 0     0 # set in the stash the PERL_MAGIC_symtab PTR to the PMOP: ((PMOP**)mg->mg_ptr) [elements++] = pm;
2732 0 0       0 if ($PERL510 and $op->pmflags & PMf_ONCE()) {
    0          
2733             my $stash = $MULTI ? $op->pmstashpv
2734 0         0 : ref $op->pmstash eq 'B::HV' ? $op->pmstash->NAME : '__ANON__';
2735             $Regexp{$$op} = $op; #188: restore PMf_ONCE, set PERL_MAGIC_symtab in $stash
2736             }
2737             }
2738 0         0 elsif ($PERL56) {
2739 0         0 my ( $resym, $relen ) = savere( $re, 0 );
2740             $init->add(
2741             "$pm.op_pmregexp = pregcomp((char*)$resym, (char*)$resym + $relen, &$pm);"
2742             );
2743             }
2744 0         0 else { # 5.8
2745 0         0 my ( $resym, $relen ) = savere( $re, 0 );
2746             $init->add(
2747             "PM_SETRE(&$pm, CALLREGCOMP(aTHX_ (char*)$resym, (char*)$resym + $relen, &$pm));"
2748             );
2749             }
2750 0 0       0 }
2751 0 0       0 if ( $gvsym ) {
2752             if ($PERL510) {
2753 0         0 # XXX need that for subst
2754             $init->add("$pm.op_pmreplrootu.op_pmreplroot = (OP*)$gvsym;");
2755 0         0 } else {
2756             $init->add("$pm.op_pmreplroot = (OP*)$gvsym;");
2757             }
2758 0         0 }
2759             savesym( $op, "(OP*)&$pm" );
2760             }
2761              
2762 0     0   0 sub B::SPECIAL::save {
2763             my ($sv, $fullname) = @_;
2764             # special case: $$sv is not the address but an index into specialsv_list
2765 0 0       0 # warn "SPECIAL::save specialsv $$sv\n"; # debug
2766             @specialsv_name = qw(Nullsv &PL_sv_undef &PL_sv_yes &PL_sv_no pWARN_ALL pWARN_NONE)
2767 0         0 unless @specialsv_name; # 5.6.2 Exporter quirks. pWARN_STD was added to B with 5.8.9
2768 0 0       0 my $sym = $specialsv_name[$$sv];
2769 0         0 if ( !defined($sym) ) {
2770             warn "unknown specialsv index $$sv passed to B::SPECIAL::save";
2771 0         0 }
2772             return $sym;
2773             }
2774       0      
2775             sub B::OBJECT::save { }
2776              
2777 0     0   0 sub B::NULL::save {
2778 0         0 my ($sv, $fullname) = @_;
2779 0 0       0 my $sym = objsym($sv);
2780             return $sym if defined $sym;
2781              
2782 0 0       0 # debug
2783 0 0       0 if ( $$sv == 0 ) {
  0         0  
2784 0         0 warn "NULL::save for sv = 0 called from @{[(caller(1))[3]]}\n" if $verbose;
2785             return savesym( $sv, "(void*)Nullsv" );
2786             }
2787 0         0  
2788 0 0       0 my $i = $svsect->index + 1;
2789 0 0       0 warn "Saving SVt_NULL sv_list[$i]\n" if $debug{sv};
2790             $svsect->add( sprintf( "NULL, $u32fmt, 0x%x".($PERL510?", {0}":''),
2791             $sv->REFCNT, $sv->FLAGS ) );
2792 0 0 0     0 #$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; # XXX where is this possible?
      0        
      0        
2793             if ($debug{flags} and (!$ITHREADS or $PERL514) and $DEBUG_LEAKING_SCALARS) { # add index to sv_debug_file to easily find the Nullsv
2794 0         0 # $svsect->debug( "ix added to sv_debug_file" );
2795             $init->add(sprintf(qq(sv_list[%d].sv_debug_file = savesharedpv("NULL sv_list[%d] 0x%x");),
2796             $svsect->index, $svsect->index, $sv->FLAGS));
2797 0         0 }
2798             savesym( $sv, sprintf( "&sv_list[%d]", $svsect->index ) );
2799             }
2800              
2801 0     0   0 sub B::UV::save {
2802 0         0 my ($sv, $fullname) = @_;
2803 0 0       0 my $sym = objsym($sv);
2804 0         0 return $sym if defined $sym;
2805 0         0 my $uvuformat = $Config{uvuformat};
2806 0         0 $uvuformat =~ s/["\0]//g; #" poor editor
2807 0         0 $uvuformat =~ s/".$/"/; # cperl bug 5.22.2 #61
2808 0         0 my $uvx = $sv->UVX;
2809 0 0       0 my $suff = 'U';
2810 0         0 $suff .= 'L' if $uvx > 2147483647;
2811 0 0       0 my $i = $svsect->index + 1;
    0          
    0          
2812             if ($PERL524) {
2813             # since 5.24 we need to point the xpvuv to the head
2814             } elsif ($PERL514) {
2815 0         0 # issue 145 warn $sv->UVX, " ", sprintf($u32fmt, $sv->UVX);
2816 0         0 $xpvuvsect->comment( "stash, magic, cur, len, xuv_u" );
2817             $xpvuvsect->add( sprintf( "Nullhv, {0}, 0, 0, {%".$uvuformat."$suff}", $uvx ) );
2818 0         0 } elsif ($PERL510) {
2819 0         0 $xpvuvsect->comment( "stash, magic, cur, len, xuv_u" );
2820             $xpvuvsect->add( sprintf( "{0}, 0, 0, {%".$uvuformat."$suff}", $uvx ) );
2821 0         0 } else {
2822 0         0 $xpvuvsect->comment( "pv, cur, len, uv" );
2823             $xpvuvsect->add( sprintf( "0, 0, 0, %".$uvuformat.$suff, $uvx ) );
2824 0 0       0 }
2825 0 0       0 if ($PERL524) {
    0          
2826             $svsect->add(sprintf( "NULL, $u32fmt, 0x%x".
2827             ($PERL510?', {'.($C99?".svu_uv=":"").$uvx."$suff}":''),
2828             $sv->REFCNT, $sv->FLAGS));
2829 0 0 0     0 #32bit - sizeof(void*), 64bit: - 2*ptrsize
2830 0         0 if ($Config{ptrsize} == 4 and !IS_MSVC) {
2831             $init->add(sprintf( "sv_list[%d].sv_any = (void*)&sv_list[%d] - sizeof(void*);", $i, $i));
2832             } else {
2833 0         0 $init->add(sprintf( "sv_list[%d].sv_any = (char*)&sv_list[%d] - %d;", $i, $i,
2834             2*$Config{ptrsize}));
2835             }
2836 0 0       0 } else {
    0          
2837             $svsect->add(sprintf( "&xpvuv_list[%d], $u32fmt, 0x%x".
2838             ($PERL510?', {'.($C99?".svu_uv=":"").$uvx."$suff}":''),
2839             $xpvuvsect->index, $sv->REFCNT, $sv->FLAGS));
2840 0 0       0 }
2841             $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
2842 0         0 warn sprintf( "Saving IV(UV) 0x%x to xpvuv_list[%d], sv_list[%d], called from %s:%s\n",
  0         0  
2843 0 0       0 $sv->UVX, $xpvuvsect->index, $i, @{[(caller(1))[3]]}, @{[(caller(0))[2]]} )
2844 0         0 if $debug{sv};
2845             savesym( $sv, sprintf( "&sv_list[%d]", $i ) );
2846             }
2847              
2848 0     0   0 sub B::IV::save {
2849 0         0 my ($sv, $fullname) = @_;
2850 0 0       0 my $sym = objsym($sv);
2851             return $sym if defined $sym;
2852 0         0 # Since 5.11 the RV is no special SV object anymore, just a IV (test 16)
2853 0 0 0     0 my $svflags = $sv->FLAGS;
2854 0         0 if ($PERL512 and $svflags & SVf_ROK) {
2855             return $sv->B::RV::save($fullname);
2856 0 0       0 }
2857 0         0 if ($svflags & SVf_IVisUV) {
2858             return $sv->B::UV::save;
2859 0         0 }
2860 0         0 my $ivx = ivx($sv->IVX);
2861 0 0 0     0 my $i = $svsect->index + 1;
2862 0 0 0     0 if ($svflags & 0xff and !($svflags & (SVf_IOK|SVp_IOK))) { # Not nullified
      0        
      0        
      0        
      0        
2863             unless (($PERL510 and $svflags & 0x00010000) # PADSTALE - out of scope lexical is !IOK
2864             or (!$PERL510 and $svflags & 0x00000100) # PADBUSY
2865 0         0 or ($] > 5.015002 and $svflags & 0x60002)) { # 5.15.3 changed PAD bits
2866             warn sprintf("Internal warning: IV !IOK $fullname sv_list[$i] 0x%x\n",$svflags);
2867             }
2868 0 0       0 }
    0          
    0          
2869             if ($PERL524) {
2870             # since 5.24 we need to point the xpviv to the head
2871 0         0 } elsif ($PERL514) {
2872 0         0 $xpvivsect->comment( "stash, magic, cur, len, xiv_u" );
2873             $xpvivsect->add( sprintf( "Nullhv, {0}, 0, 0, {%s}", $ivx ) );
2874 0         0 } elsif ($PERL510) {
2875 0         0 $xpvivsect->comment( "stash, magic, cur, len, xiv_u" );
2876             $xpvivsect->add( sprintf( "{0}, 0, 0, {%s}", $ivx ) );
2877 0         0 } else {
2878 0         0 $xpvivsect->comment( "pv, cur, len, iv" );
2879             $xpvivsect->add( sprintf( "0, 0, 0, %s", $ivx ) );
2880 0 0       0 }
2881 0 0       0 if ($PERL524) {
2882             $svsect->add(sprintf( "NULL, $u32fmt, 0x%x, {".($C99?".svu_iv=":"").$ivx.'}',
2883             $sv->REFCNT, $svflags ));
2884 0 0 0     0 #32bit - sizeof(void*), 64bit: - 2*ptrsize
2885 0         0 if ($Config{ptrsize} == 4 and !IS_MSVC) {
2886             $init->add(sprintf( "sv_list[%d].sv_any = (void*)&sv_list[%d] - sizeof(void*);", $i, $i));
2887             } else {
2888 0         0 $init->add(sprintf( "sv_list[%d].sv_any = (char*)&sv_list[%d] - %d;", $i, $i,
2889             2*$Config{ptrsize}));
2890             }
2891 0 0       0 } else {
    0          
2892             $svsect->add(sprintf( "&xpviv_list[%d], $u32fmt, 0x%x".($PERL510?', {'.($C99?".svu_iv=":"").$ivx.'}':''),
2893             $xpvivsect->index, $sv->REFCNT, $svflags ));
2894 0 0       0 }
2895             $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
2896 0         0 warn sprintf( "Saving IV 0x%x to xpviv_list[%d], sv_list[%d], called from %s:%s\n",
  0         0  
2897 0 0       0 $sv->IVX, $xpvivsect->index, $i, @{[(caller(1))[3]]}, @{[(caller(0))[2]]} )
2898 0         0 if $debug{sv};
2899             savesym( $sv, sprintf( "&sv_list[%d]", $i ) );
2900             }
2901              
2902 0     0   0 sub B::NV::save {
2903 0         0 my ($sv, $fullname) = @_;
2904 0 0       0 my $sym = objsym($sv);
2905 0         0 return $sym if defined $sym;
2906 0 0       0 my $nv = nvx($sv->NV);
2907             $nv .= '.00' if $nv =~ /^-?\d+$/;
2908 0 0       0 # IVX is invalid in B.xs and unused
2909 0 0 0     0 my $iv = $sv->FLAGS & SVf_IOK ? $sv->IVX : 0;
2910 0 0       0 $nv = '0.00' if IS_MSVC and !$nv;
    0          
2911 0         0 if ($PERL514) {
2912 0         0 $xpvnvsect->comment('STASH, MAGIC, cur, len, IVX, NVX');
2913             $xpvnvsect->add( sprintf( "Nullhv, {0}, 0, 0, {%ld}, {%s}", $iv, $nv ) );
2914 0         0 } elsif ($PERL510) { # not fixed by NV isa IV >= 5.8
2915 0         0 $xpvnvsect->comment('NVX, cur, len, IVX');
2916             $xpvnvsect->add( sprintf( "{%s}, 0, 0, {%ld}", $nv, $iv ) );
2917             }
2918 0         0 else {
2919 0         0 $xpvnvsect->comment('PVX, cur, len, IVX, NVX');
2920             $xpvnvsect->add( sprintf( "0, 0, 0, %ld, %s", $iv, $nv ) );
2921 0 0       0 }
2922             $svsect->add(
2923             sprintf( "&xpvnv_list[%d], $u32fmt, 0x%x %s",
2924 0 0       0 $xpvnvsect->index, $sv->REFCNT, $sv->FLAGS, $PERL510 ? ', {0}' : '' ));
2925             $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
2926             warn sprintf( "Saving NV %s to xpvnv_list[%d], sv_list[%d]\n",
2927 0 0       0 $nv, $xpvnvsect->index, $svsect->index )
2928 0         0 if $debug{sv};
2929             savesym( $sv, sprintf( "&sv_list[%d]", $svsect->index ) );
2930             }
2931              
2932 0     0 0 0 sub savepvn {
2933 0         0 my ( $dest, $pv, $sv, $cur ) = @_;
2934             my @init;
2935              
2936 0 0       0 # work with byte offsets/lengths
2937 0 0 0     0 $pv = pack "a*", $pv if defined $pv;
2938 0         0 if ( defined $max_string_len && length($pv) > $max_string_len ) {
2939 0         0 push @init, sprintf( "Newx(%s, %u, char);", $dest, length($pv) + 2 );
2940 0         0 my $offset = 0;
2941 0         0 while ( length $pv ) {
2942 0         0 my $str = substr $pv, 0, $max_string_len, '';
2943             push @init,
2944             sprintf( "Copy(%s, %s+%d, %u, char);",
2945 0         0 cstring($str), $dest, $offset, length($str) );
2946             $offset += length $str;
2947 0         0 }
2948             push @init, sprintf( "%s[%u] = '\\0';", $dest, $offset );
2949 0 0 0     0 warn sprintf( "Copying overlong PV %s to %s\n", cstring($pv), $dest )
2950             if $debug{sv} or $debug{pv};
2951             }
2952             else {
2953             # If READONLY and FAKE use newSVpvn_share instead. (test 75)
2954 0 0 0     0 # XXX IsCOW forgotten here. rather use a helper is_shared_hek()
      0        
2955 0 0       0 if ($PERL510 and $sv and (($sv->FLAGS & 0x09000000) == 0x09000000)) {
2956 0         0 warn sprintf( "Saving shared HEK %s to %s\n", cstring($pv), $dest ) if $debug{sv};
2957 0 0       0 my $hek = save_hek($pv,'',1);
2958 0 0       0 push @init, sprintf( "%s = HEK_KEY(%s);", $dest, $hek ) unless $hek eq 'NULL';
2959 0         0 if ($DEBUGGING) { # we have to bypass a wrong HE->HEK assert in hv.c
2960             push @B::C::static_free, $dest;
2961             }
2962 0         0 } else {
2963 0 0 0     0 my $cstr = cstring($pv);
2964 0         0 if (!$cstr and $cstr == 0) {
2965             $cstr = '""';
2966 0 0 0     0 }
2967             if ($sv and IsCOW($sv)) { # and ($B::C::cow or IsCOW_hek($sv)))
2968 0 0       0 # This cannot be savepvn allocated. TODO: READONLY COW => static hek?
2969 0         0 if ($cstr !~ /\\000\\00\d"$/) {
2970 0         0 $cstr = substr($cstr,0,-1) . '\0\001"';
2971             $cur += 2;
2972 0 0       0 }
2973 0         0 warn sprintf( "Saving COW PV %s to %s\n", $cstr, $dest ) if $debug{sv};
2974             return (sprintf( "Newx(%s, sizeof(%s)-1, char);", $dest, $cstr ),
2975             sprintf( "Copy(%s, %s, sizeof(%s)-1, char);", $cstr, $dest, $cstr ));
2976 0 0       0 }
2977 0         0 warn sprintf( "Saving PV %s to %s\n", $cstr, $dest ) if $debug{sv};
2978             push @init, sprintf( "%s = Perl_savepvn(aTHX_ STR_WITH_LEN(%s));", $dest, $cstr );
2979             }
2980 0         0 }
2981             return @init;
2982             }
2983              
2984 0     0   0 sub B::PVLV::save {
2985 0         0 my ($sv, $fullname) = @_;
2986 0 0       0 my $sym = objsym($sv);
2987 0 0       0 if (defined $sym) {
2988 0 0       0 if ($in_endav) {
2989 0         0 warn "in_endav: static_free without $sym\n" if $debug{av};
  0         0  
2990             @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
2991 0         0 }
2992             return $sym;
2993 0         0 }
2994 0         0 my ($pvsym, $cur, $len, $pv, $static, $flags) = save_pv_or_rv ($sv, $fullname);
2995 0         0 my ( $lvtarg, $lvtarg_sym ); # XXX missing
2996 0 0       0 my $tmp_pvsym = $pvsym;
    0          
2997 0         0 if ($PERL514) {
2998 0         0 $xpvlvsect->comment('STASH, MAGIC, CUR, LEN, GvNAME, xnv_u, TARGOFF, TARGLEN, TARG, TYPE');
2999             $xpvlvsect->add(
3000             sprintf("Nullhv, {0}, %u, %d, 0/*GvNAME later*/, %s, %u, %u, Nullsv, %s",
3001             $cur, $len, nvx($sv->NVX),
3002 0 0 0     0 $sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) ));
3003 0         0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3004             $svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x, {(char*)%s}",
3005             $xpvlvsect->index, $sv->REFCNT, $sv->FLAGS, $tmp_pvsym));
3006 0         0 } elsif ($PERL510) {
3007 0         0 $xpvlvsect->comment('xnv_u, CUR, LEN, GvNAME, MAGIC, STASH, TARGOFF, TARGLEN, TARG, TYPE');
3008             $xpvlvsect->add(
3009             sprintf("%s, %u, %d, 0/*GvNAME later*/, 0, Nullhv, %u, %u, Nullsv, %s",
3010             nvx($sv->NVX), $cur, $len,
3011 0 0       0 $sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) ));
3012             $svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x, {%s}",
3013             $xpvlvsect->index, $sv->REFCNT, $flags,
3014             ($C99?".svu_pv = (char*)":"(char*)").$tmp_pvsym));
3015 0         0 } else {
3016 0         0 $xpvlvsect->comment('PVX, CUR, LEN, IVX, NVX, TARGOFF, TARGLEN, TARG, TYPE');
3017             $xpvlvsect->add(
3018             sprintf("(char*)%s, %u, %u, %s, %s, 0, 0, %u, %u, Nullsv, %s",
3019             $pvsym, $cur, $len, ivx($sv->IVX), nvx($sv->NVX),
3020 0         0 $sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) ));
3021             $svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x",
3022             $xpvlvsect->index, $sv->REFCNT, $flags));
3023 0 0       0 }
3024 0         0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3025 0 0 0     0 my $s = "sv_list[".$svsect->index."]";
    0          
3026 0 0       0 if ( !$static ) {
3027 0         0 if ($PERL510) {
3028             $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3029             }
3030 0         0 else {
3031             $init->add( savepvn( sprintf( "xpvlv_list[%d].xpv_pv", $xpvlvsect->index ), $pv, $cur ) );
3032             }
3033 0         0 } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3034             $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3035 0         0 }
3036 0         0 $sv->save_magic($fullname);
3037             savesym( $sv, "&".$s );
3038             }
3039              
3040 0     0   0 sub B::PVIV::save {
3041 0         0 my ($sv, $fullname) = @_;
3042 0 0       0 my $sym = objsym($sv);
3043 0 0       0 if (defined $sym) {
3044 0 0       0 if ($in_endav) {
3045 0         0 warn "in_endav: static_free without $sym\n" if $debug{av};
  0         0  
3046             @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
3047 0         0 }
3048             return $sym;
3049 0         0 }
3050 0         0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3051 0 0       0 my $tmp_pvsym = $pvsym;
    0          
3052 0         0 if ($PERL514) {
3053 0         0 $xpvivsect->comment('STASH, MAGIC, cur, len, IVX');
3054 0 0 0     0 $xpvivsect->add( sprintf( "Nullhv, {0}, %u, %u, {%s}", $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long
3055             $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3056 0         0 } elsif ($PERL510) {
3057 0         0 $xpvivsect->comment('xnv_u, cur, len, IVX');
3058             $xpvivsect->add( sprintf( "{0}, %u, %u, {%s}", $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long
3059             } else {
3060 0         0 #$iv = 0 if $sv->FLAGS & (SVf_IOK|SVp_IOK);
3061 0         0 $xpvivsect->comment('PVX, cur, len, IVX');
3062             $xpvivsect->add( sprintf( "(char*)%s, %u, %u, %s",
3063             $pvsym, $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long
3064 0 0       0 }
    0          
3065             $svsect->add(
3066             sprintf("&xpviv_list[%d], $u32fmt, 0x%x %s",
3067             $xpvivsect->index, $sv->REFCNT, $flags,
3068 0 0       0 $PERL510 ? ", {".($C99?".svu_pv=":"")."(char*)$tmp_pvsym}" : '' ) );
3069 0         0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3070 0 0       0 my $s = "sv_list[".$svsect->index."]";
3071 0 0 0     0 if ( defined($pv) ) {
    0          
3072 0 0       0 if ( !$static ) {
3073 0         0 if ($PERL510) {
3074             $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3075 0         0 } else {
3076             $init->add( savepvn( sprintf( "xpviv_list[%d].xpv_pv", $xpvivsect->index ), $pv, $cur ) );
3077             }
3078 0         0 } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3079             $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3080             }
3081 0         0 }
3082             savesym( $sv, "&".$s );
3083             }
3084              
3085 0     0   0 sub B::PVNV::save {
3086 0         0 my ($sv, $fullname) = @_;
3087 0 0       0 my $sym = objsym($sv);
3088 0 0       0 if (defined $sym) {
3089 0 0       0 if ($in_endav) {
3090 0         0 warn "in_endav: static_free without $sym\n" if $debug{av};
  0         0  
3091             @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
3092 0         0 }
3093             return $sym;
3094 0         0 }
3095 0         0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3096 0         0 my $tmp_pvsym = $pvsym;
3097 0         0 my $nvx = '0.0';
3098 0 0       0 my $ivx = ivx($sv->IVX); # here must be IVX!
3099             if ($flags & (SVf_NOK|SVp_NOK)) {
3100 0         0 # it could be a double, or it could be 2 ints - union xpad_cop_seq
3101             $nvx = nvx($sv->NV);
3102 0 0 0     0 } else {
    0 0        
3103 0         0 if ($PERL510 and $C99 and !$PERL522) {
3104             $nvx = sprintf(".xpad_cop_seq.xlow = %s, .xpad_cop_seq.xhigh = %s",
3105             ivx($sv->COP_SEQ_RANGE_LOW), ivx($sv->COP_SEQ_RANGE_HIGH),
3106             );
3107 0         0 } elsif (!$PERL522) {
3108             $nvx = nvx($sv->NVX);
3109             }
3110 0 0       0 }
3111             if ($PERL510) {
3112 0 0       0 # For some time the stringification works of NVX double to two ints worked ok.
3113 0 0 0     0 if ($PERL514) {
3114 0         0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3115 0         0 $xpvnvsect->comment('STASH, MAGIC, cur, len, IVX, NVX');
3116             $xpvnvsect->add(sprintf( "Nullhv, {0}, %u, %u, {%s}, {%s}", $cur, $len, $ivx, $nvx) );
3117 0         0 } else {
3118 0         0 $xpvnvsect->comment('NVX, cur, len, IVX');
3119             $xpvnvsect->add(sprintf( "{%s}, %u, %u, {%s}", $nvx, $cur, $len, $ivx ) );
3120 0 0 0     0 }
3121 0 0       0 if (!($sv->FLAGS & (SVf_NOK|SVp_NOK)) and !$PERL522) {
3122 0         0 warn "NV => run-time union xpad_cop_seq init\n" if $debug{sv};
3123             $init->add(sprintf("xpvnv_list[%d].xnv_u.xpad_cop_seq.xlow = %s;",
3124             $xpvnvsect->index, ivx($sv->COP_SEQ_RANGE_LOW)),
3125             # pad.c: PAD_MAX = I32_MAX (4294967295)
3126             # U suffix <= "warning: this decimal constant is unsigned only in ISO C90"
3127             sprintf("xpvnv_list[%d].xnv_u.xpad_cop_seq.xhigh = %s;",
3128             $xpvnvsect->index, ivx($sv->COP_SEQ_RANGE_HIGH)));
3129             }
3130             }
3131 0         0 else {
3132 0         0 $xpvnvsect->comment('PVX, cur, len, IVX, NVX');
3133             $xpvnvsect->add(sprintf( "(char*)%s, %u, %u, %s, %s", $pvsym, $cur, $len, $ivx, $nvx ) );
3134 0 0       0 }
    0          
3135             $svsect->add(
3136             sprintf("&xpvnv_list[%d], $u32fmt, 0x%x %s",
3137             $xpvnvsect->index, $sv->REFCNT, $flags,
3138 0 0       0 $PERL510 ? ", {".($C99?".svu_pv=":"")."(char*)$tmp_pvsym}" : '' ) );
3139 0         0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3140 0 0       0 my $s = "sv_list[".$svsect->index."]";
3141 0 0 0     0 if ( defined($pv) ) {
    0          
3142 0 0       0 if ( !$static ) {
3143 0         0 if ($PERL510) {
3144             $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3145             }
3146 0         0 else {
3147             $init->add( savepvn( sprintf( "xpvnv_list[%d].xpv_pv", $xpvnvsect->index ), $pv, $cur ) );
3148             }
3149 0         0 } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3150             $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3151             }
3152 0 0 0     0 }
3153 0         0 push @B::C::static_free, "&".$s if $PERL518 and $sv->FLAGS & SVs_OBJECT;
3154             savesym( $sv, "&".$s );
3155             }
3156              
3157 0     0   0 sub B::BM::save {
3158 0         0 my ($sv, $fullname) = @_;
3159 0 0 0     0 my $sym = objsym($sv);
3160 0 0       0 return $sym if !$PERL510 and defined $sym;
3161 0         0 $sv = bless $sv, "B::BM" if $PERL510;
3162 0         0 my $pv = pack "a*", ( $sv->PV . "\0" . $sv->TABLE );
3163 0         0 my $cur = $sv->CUR;
3164 0         0 my $len = $cur + length($sv->TABLE) + 1;
3165 0 0       0 my $s;
3166 0 0       0 if ($PERL510) {
3167 0         0 warn "Saving FBM for GV $sym\n" if $debug{gv};
3168             $init->add( sprintf( "%s = (GV*)newSV_type(SVt_PVGV);", $sym ),
3169             sprintf( "SvFLAGS(%s) = 0x%x;", $sym, $sv->FLAGS),
3170             sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $sv->REFCNT + 1 ),
3171             sprintf( "SvPVX(%s) = %s;", $sym, cstring($pv) ),
3172             sprintf( "SvCUR_set(%s, %d);", $sym, $cur ),
3173             sprintf( "SvLEN_set(%s, %d);", $sym, $len ),
3174             sprintf( "BmRARE(%s) = %d;", $sym, $sv->RARE ),
3175             sprintf( "BmPREVIOUS(%s) = %d;", $sym, $sv->PREVIOUS ),
3176             sprintf( "BmUSEFUL(%s) = %d;", $sym, $sv->USEFUL )
3177             );
3178 0         0 } else {
3179 0         0 my $static;
3180 0 0 0     0 $xpvbmsect->comment('pvx,cur,len(+258),IVX,NVX,MAGIC,STASH,USEFUL,PREVIOUS,RARE');
3181             $xpvbmsect->add(
3182             sprintf("%s, %u, %u, %s, %s, 0, 0, %d, %u, 0x%x",
3183             defined($pv) && $static ? cstring($pv) : "NULL",
3184             $cur, $len, ivx($sv->IVX), nvx($sv->NVX),
3185             $sv->USEFUL, $sv->PREVIOUS, $sv->RARE
3186 0         0 ));
3187             $svsect->add(sprintf("&xpvbm_list[%d], $u32fmt, 0x%x",
3188 0 0       0 $xpvbmsect->index, $sv->REFCNT, $sv->FLAGS));
3189 0         0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3190 0 0       0 $s = "sv_list[".$svsect->index."]";
3191 0         0 if (!$static) {
3192             $init->add(savepvn( sprintf( "xpvbm_list[%d].xpv_pv", $xpvbmsect->index ), $pv, 0, $len ) );
3193 0 0 0     0 } else {
3194             push @B::C::static_free, $s if defined($pv) and !$in_endav;
3195             }
3196             }
3197 0         0 # Restore possible additional magic. fbm_compile adds just 'B'.
3198             $sv->save_magic($fullname);
3199 0 0       0  
3200 0         0 if ($PERL510) {
3201             return $sym;
3202 0 0       0 } else {
3203 0         0 if ($] == 5.008009) { # XXX 5.8.9 needs more. TODO test 5.8.0 - 5.8.7
3204             $init->add( sprintf( "fbm_compile(&sv_list[%d], 0);", $svsect->index ) );
3205             }
3206             # cur+len was broken on all B::C versions
3207 0         0 #$init->add(sprintf( "xpvbm_list[%d].xpv_cur = %u;", $xpvbmsect->index, $len ) );
3208             return savesym( $sv, "&".$s );
3209             }
3210             }
3211              
3212 0     0   0 sub B::PV::save {
3213 0         0 my ($sv, $fullname) = @_;
3214 0 0       0 my $sym = objsym($sv);
3215 0 0       0 if (defined $sym) {
3216 0 0       0 if ($in_endav) {
3217 0         0 warn "in_endav: static_free without $sym\n" if $debug{av};
  0         0  
3218             @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
3219 0         0 }
3220             return $sym;
3221             }
3222 0         0 #my $flags = $sv->FLAGS;
3223 0 0       0 my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3224 0 0 0     0 my $shared_hek = $PERL510 ? (($flags & 0x09000000) == 0x09000000) : undef;
      0        
3225 0         0 if (!$shared_hek and (IsCOW_hek($sv) or ($len==0 and $flags & SVf_IsCOW))) {
3226             $shared_hek = 1;
3227 0         0 }
3228             my $tmp_pvsym = $pvsym;
3229 0         0 # $static = 0 if !($flags & SVf_ROK) and $sv->PV and $sv->PV =~ /::bootstrap$/;
3230 0         0 my $refcnt = $sv->REFCNT;
3231             my $svix;
3232             # sv_free2 problem with !SvIMMORTAL and del_SV
3233 0 0 0     0 # repro with -O0 .. -O2 for all testcases
      0        
3234 0 0       0 if ($PERL518 and $fullname && $fullname eq 'svop const') {
3235             $refcnt = $DEBUGGING ? 1000 : 0x7fffffff;
3236             }
3237             #if (!$shared_hek and !$B::C::cow and IsCOW($sv)) {
3238             # $flags &= ~SVf_IsCOW;
3239             # warn sprintf("turn off SVf_IsCOW %s %s %s\n", $sym, cstring($pv), $fullname)
3240             # if $debug{pv};
3241 0 0       0 #}
3242             if ($PERL510) {
3243 0 0 0     0 # static pv, do not destruct. test 13 with pv0 "3".
      0        
      0        
3244 0         0 if ($B::C::const_strings and !$shared_hek and $flags & SVf_READONLY and !$len) {
3245             $flags &= ~0x01000000;
3246 0 0       0 warn sprintf("constpv turn off SVf_FAKE %s %s %s\n", $sym, cstring($pv), $fullname)
3247             if $debug{pv};
3248 0 0 0     0 }
3249 0 0       0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3250 0 0       0 $xpvsect->comment( $PERL514 ? "stash, magic, cur, len" : "xnv_u, cur, len");
3251 0         0 $xpvsect->add( sprintf( "%s{0}, %u, %u", $PERL514 ? "Nullhv, " : "", $cur, $len ) );
3252 0 0       0 $svsect->comment( "any, refcnt, flags, sv_u" );
    0          
3253             $svsect->add( sprintf( "&xpv_list[%d], $u32fmt, 0x%x, {%s}",
3254             $xpvsect->index, $refcnt, $flags,
3255             $tmp_pvsym eq 'NULL' ? '0' :
3256 0         0 ($C99?".svu_pv=(char*)":"(char*)").$pvsym ));
3257 0 0 0     0 $svix = $svsect->index;
    0 0        
      0        
3258 0 0       0 if ( defined($pv) and !$static ) {
3259 0         0 if ($shared_hek) {
3260 0 0       0 my $hek = save_hek($pv, $fullname, 1);
3261             $init->add( sprintf( "sv_list[%d].sv_u.svu_pv = HEK_KEY(%s);", $svix, $hek ))
3262             unless $hek eq 'NULL';
3263 0         0 } else {
3264             $init->add( savepvn( sprintf( "sv_list[%d].sv_u.svu_pv", $svix ), $pv, $sv, $cur ) );
3265             }
3266 0         0 } elsif ($shared_hek and $static and $pvsym =~ /^hek/) {
3267             $init->add( sprintf( "sv_list[%d].sv_u.svu_pv = %s.hek_key;", $svix, $pvsym ));
3268 0 0 0     0 }
      0        
      0        
3269 0 0       0 if ($debug{flags} and (!$ITHREADS or $PERL514) and $DEBUG_LEAKING_SCALARS) { # add sv_debug_file
3270             $init->add(sprintf(qq(sv_list[%d].sv_debug_file = %s" sv_list[%d] 0x%x";),
3271             $svix, cstring($pv) eq '0' ? '"NULL"' : cstring($pv),
3272             $svix, $flags));
3273             }
3274             }
3275 0         0 else {
3276 0         0 $xpvsect->comment( "pv, cur, len");
3277 0         0 $xpvsect->add(sprintf( "(char*)%s, %u, %u", $pvsym, $cur, $len ) );
3278 0         0 $svsect->comment( "any, refcnt, flags" );
3279             $svsect->add(sprintf( "&xpv_list[%d], $u32fmt, 0x%x",
3280 0         0 $xpvsect->index, $refcnt, $flags));
3281 0 0 0     0 $svix = $svsect->index;
3282 0         0 if ( defined($pv) and !$static ) {
3283             $init->add( savepvn( sprintf( "xpv_list[%d].xpv_pv", $xpvsect->index ), $pv, 0, $cur ) );
3284             }
3285 0         0 }
3286 0 0       0 my $s = "sv_list[$svix]";
3287 0 0 0     0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3288 0         0 push @B::C::static_free, "&".$s if $PERL518 and $flags & SVs_OBJECT;
3289             savesym( $sv, "&".$s );
3290             }
3291              
3292             # 5.18-5.20 => PV::save, since 5.22 native using this method
3293 0     0   0 sub B::PADNAME::save {
3294 0         0 my ($pn, $fullname) = @_;
3295 0 0       0 my $sym = objsym($pn);
3296 0 0       0 if (defined $sym) {
3297 0 0       0 if ($in_endav) {
3298 0         0 warn "in_endav: static_free without $sym\n" if $debug{av};
  0         0  
3299             @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
3300 0         0 }
3301             return $sym;
3302 0         0 }
3303 0         0 my $flags = $pn->FLAGS; # U8 + FAKE if OUTER. OUTER,STATE,LVALUE,TYPED,OUR
3304 0         0 $flags = $flags & 0xff;
3305 0         0 my $gen = $pn->GEN;
3306 0         0 my $stash = $pn->OURSTASH;
3307 0         0 my $type = $pn->TYPE;
3308 0         0 my $sn = $stash->save($fullname);
3309 0         0 my $tn = $type->save($fullname);
3310 0 0       0 my $refcnt = $pn->REFCNT;
3311 0         0 $refcnt++ if $refcnt < 1000; # XXX protect from free, but allow SvREFCOUNT_IMMORTAL
3312 0         0 my $str = $pn->PVX;
3313 0         0 my $cstr = cstring($str); # a 5.22 padname is always utf8
3314 0         0 my $len = $pn->LEN;
3315 0         0 my $alignedlen = 8*(int($len / 8)+1); # 5 -> 8, 9 -> 16
3316 0         0 my $struct_name = "my_padname_with_str_".$alignedlen;
3317 0 0       0 my $pnsect = $padnamesect{$alignedlen};
3318 0         0 if (!$pnsect) {
3319 0 0       0 my $name = "padname_$alignedlen";
3320 0         0 warn "dynamically created oversized $name section\n" if $verbose;
3321             $padnamesect{$alignedlen} = new B::C::Section $name, \%symtable, 0;
3322 0         0 }
3323 0         0 my $ix = $pnsect->index + 1;
3324 0         0 my $name = $pnsect->name;
3325             my $s = "&".$name."_list[$ix]";
3326             # 5.22 needs the buffer to be at the end, and the pv pointing to it.
3327 0         0 # We allocate a static buffer of different sizes.
3328 0         0 $pnsect->comment( "pv, ourstash, type, low, high, refcnt, gen, len, flags, str");
3329 0 0       0 my $pnstr = "((char*)$s)+STRUCT_OFFSET(struct $struct_name, xpadn_str[0])";
3330 0         0 if (IS_MSVC) {
3331             $pnstr = sprintf("((char*)$s)+%d", $Config{ptrsize} * 3 + 5);
3332 0 0 0     0 }
    0          
    0          
    0          
3333             $pnsect->add( sprintf
3334             ( "%s, %s, {%s}, %u, %u, %s, %i, %u, 0x%x, %s",
3335             ($ix or $len) ? $pnstr : 'NULL',
3336             is_constant($sn) ? "(HV*)$sn" : 'Nullhv',
3337             is_constant($tn) ? "(HV*)$tn" : 'Nullhv',
3338             $pn->COP_SEQ_RANGE_LOW,
3339             $pn->COP_SEQ_RANGE_HIGH,
3340             $refcnt >= 1000 ? sprintf("0x%x", $refcnt) : "$refcnt /* +1 */",
3341             $gen, $len, $flags, $cstr));
3342             #if ( $len > 64 ) {
3343             # Houston we have a problem, need to allocate this padname dynamically. Not done yet
3344             # either dynamic or seperate structs per size MyPADNAME(5)
3345             # die "Internal Error: Overlong name of lexical variable $cstr for $fullname [#229]";
3346 0 0       0 #}
3347 0 0       0 $pnsect->debug( $fullname." ".$str, $pn->flagspv ) if $debug{flags};
3348 0 0       0 $init->add("SvOURSTASH_set($s, $sn);") unless is_constant($sn);
3349 0         0 $init->add("PadnameTYPE($s) = (HV*)$tn;") unless is_constant($tn);
3350 0         0 push @B::C::static_free, $s;
3351             savesym( $pn, $s );
3352             }
3353              
3354 0     0 0 0 sub lexwarnsym {
3355 0 0       0 my $pv = shift;
3356 0         0 if ($lexwarnsym{$pv}) {
  0         0  
3357             return @{$lexwarnsym{$pv}};
3358 0         0 } else {
3359 0         0 my $sym = sprintf( "lexwarn%d", $pv_index++ );
3360 0         0 my ($cstring, $cur, $utf8) = strlen_flags($pv);
3361 0 0       0 my $isint = 0;
3362 0         0 if ($] < 5.009) { # need a SV->PV
3363 0         0 $decl->add( sprintf( "Static SV* %s;", $sym ));
3364             $init->add( sprintf( "%s = newSVpvn(%s, %u);", $sym, $cstring, $cur));
3365             } else {
3366 0 0       0 # if 8 use UVSIZE, if 4 use LONGSIZE
3367 0         0 my $t = ($Config{longsize} == 8) ? "J" : "L";
3368 0 0 0     0 my ($iv) = unpack($t, $pv); # unsigned longsize
3369 0         0 if ($iv >= 0 and $iv <= 2) { # specialWARN: single STRLEN
3370 0         0 $decl->add( sprintf( "Static const STRLEN* %s = %d;", $sym, $iv ));
3371             $isint = 1;
3372 0         0 } else { # sizeof(STRLEN) + (WARNsize)
3373 0         0 my $packedpv = pack("$t a*",length($pv), $pv);
3374             $decl->add( sprintf( "Static const char %s[] = %s;", $sym, cstring($packedpv) ));
3375             }
3376 0         0 }
3377 0         0 $lexwarnsym{$pv} = [$sym,$isint];
3378             return ($sym, $isint);
3379             }
3380             }
3381              
3382             # pre vs. post 5.8.9/5.9.4 logic for lexical warnings
3383             @B::LEXWARN::ISA = qw(B::PV B::IV);
3384 0     0   0 sub B::LEXWARN::save {
3385 0 0       0 my ($sv, $fullname) = @_;
3386 0         0 my $pv = $] >= 5.008009 ? $sv->PV : $sv->IV;
3387             return lexwarnsym($pv); # look for shared const int's
3388             }
3389              
3390             # post 5.11: When called from save_rv not from PMOP::save precomp
3391 0     0   0 sub B::REGEXP::save {
3392 0         0 my ($sv, $fullname) = @_;
3393 0 0       0 my $sym = objsym($sv);
3394 0         0 return $sym if defined $sym;
3395 0         0 my $pv = $sv->PV;
3396             my $cur = $sv->CUR;
3397 0         0 # construct original PV
3398 0         0 $pv =~ s/^(\(\?\^[adluimsx-]*\:)(.*)\)$/$2/;
3399 0         0 $cur -= length($sv->PV) - length($pv);
3400             my $cstr = cstring($pv);
3401 0 0       0 # Unfortunately this XPV is needed temp. Later replaced by struct regexp.
3402 0 0       0 $xpvsect->add( sprintf( "%s{0}, %u, %u", $PERL514 ? "Nullhv, " : "", $cur, 0 ) );
3403             $svsect->add(sprintf("&xpv_list[%d], $u32fmt, 0x%x, {%s}",
3404 0         0 $xpvsect->index, $sv->REFCNT, $sv->FLAGS, $] > 5.017006 ? "NULL" : $cstr));
3405 0 0 0     0 my $ix = $svsect->index;
3406 0 0       0 warn "Saving RX $cstr to sv_list[$ix]\n" if $debug{rx} or $debug{sv};
3407 0 0       0 if ($] > 5.011) {
3408 0 0       0 my $pmflags = $PERL522 ? $sv->compflags : $sv->EXTFLAGS;
3409 0 0 0     0 my $initpm = re_does_swash($cstr, $pmflags) ? $init1 : $init;
3410 0         0 if ($PERL518 and $sv->EXTFLAGS & RXf_EVAL_SEEN) {
3411             $initpm->add("PL_hints |= HINT_RE_EVAL;");
3412             }
3413 0         0 $initpm->add(# replace sv_any->XPV with struct regexp. need pv and extflags
3414             sprintf("SvANY(&sv_list[%d]) = SvANY(CALLREGCOMP(newSVpvn(%s, %d), 0x%x));",
3415 0 0 0     0 $ix, $cstr, $cur, $pmflags));
3416 0         0 if ($PERL518 and $sv->EXTFLAGS & RXf_EVAL_SEEN) {
3417             $initpm->add("PL_hints &= ~HINT_RE_EVAL;");
3418             }
3419 0 0       0 }
3420             if ($] < 5.017006) {
3421 0         0 # since 5.17.6 the SvLEN stores RX_WRAPPED(rx)
3422             $init->add(sprintf("SvCUR(&sv_list[%d]) = %d;", $ix, $cur),
3423             "SvLEN(&sv_list[$ix]) = 0;");
3424 0         0 } else {
3425             $init->add("sv_list[$ix].sv_u.svu_rx = (struct regexp*)sv_list[$ix].sv_any;");
3426 0 0       0 }
3427 0         0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3428 0         0 $sym = savesym( $sv, sprintf( "&sv_list[%d]", $ix ) );
3429 0         0 $sv->save_magic($fullname);
3430             return $sym;
3431             }
3432              
3433 0     0 0 0 sub save_remap {
3434 0         0 my ($key, $pkg, $name, $ivx, $mandatory) = @_;
3435             my $id = $xpvmgsect->index + 1;
3436 0 0       0 #my $svid = $svsect->index + 1;
3437 0         0 warn "init remap for $key\: $name $ivx in xpvmg_list[$id]\n" if $verbose;
3438 0 0       0 my $props = { NAME => $name, ID => $id, MANDATORY => $mandatory };
3439 0         0 $init2_remap{$key}{MG} = [] unless $init2_remap{$key}{'MG'};
  0         0  
3440             push @{$init2_remap{$key}{MG}}, $props;
3441             }
3442              
3443 0     0 0 0 sub patch_dlsym {
3444 0         0 my ($sv, $fullname, $ivx) = @_;
3445 0 0       0 my $pkg = '';
3446 0         0 if (ref($sv) eq 'B::PVMG') {
3447 0 0       0 my $stash = $sv->SvSTASH;
3448             $pkg = $stash->can('NAME') ? $stash->NAME : '';
3449 0 0       0 }
3450 0         0 my $name = $sv->FLAGS & SVp_POK ? $sv->PVX : "";
3451 0         0 my $ivx_s = $ivx;
3452 0         0 $ivx_s =~ s/U?L?$//g;
3453             my $ivxhex = sprintf("0x%x", $ivx_s);
3454 0 0 0     0 # Encode RT #94221
    0 0        
    0 0        
    0 0        
    0          
3455 0         0 if ($name =~ /encoding$/ and $name =~ /^(ascii|ascii_ctrl|iso8859_1|null)/ and $Encode::VERSION eq '2.58') {
3456 0 0       0 $name =~ s/-/_/g;
3457 0 0 0     0 $pkg = 'Encode' if $pkg eq 'Encode::XS'; # TODO foreign classes
3458 0 0       0 mark_package($pkg) if $fullname eq '(unknown)' and $ITHREADS;
3459             warn "$pkg $Encode::VERSION with remap support for $name\n" if $verbose;
3460             }
3461 0         0 elsif ($pkg eq 'Encode::XS') {
3462 0 0       0 $pkg = 'Encode';
    0          
    0          
    0          
3463 0         0 if ($fullname eq 'Encode::Encoding{iso-8859-1}') {
3464             $name = "iso8859_1_encoding";
3465             }
3466 0         0 elsif ($fullname eq 'Encode::Encoding{null}') {
3467             $name = "null_encoding";
3468             }
3469 0         0 elsif ($fullname eq 'Encode::Encoding{ascii-ctrl}') {
3470             $name = "ascii_ctrl_encoding";
3471             }
3472 0         0 elsif ($fullname eq 'Encode::Encoding{ascii}') {
3473             $name = "ascii_encoding";
3474             }
3475 0 0 0     0  
      0        
3476 0         0 if ($name and $name =~ /^(ascii|ascii_ctrl|iso8859_1|null)/ and $Encode::VERSION gt '2.58') {
3477 0 0       0 my $enc = Encode::find_encoding($name);
3478 0         0 $name .= "_encoding" unless $name =~ /_encoding$/;
3479 0 0       0 $name =~ s/-/_/g;
3480 0         0 warn "$pkg $Encode::VERSION with remap support for $name (find 1)\n" if $verbose;
3481 0 0       0 mark_package($pkg);
3482 0         0 if ($pkg ne 'Encode') {
  0         0  
3483 0         0 svref_2object( \&{"$pkg\::bootstrap"} )->save;
3484             mark_package('Encode');
3485             }
3486             }
3487 0         0 else {
3488 0         0 for my $n (Encode::encodings()) { # >=5.16 constsub without name
3489 0 0 0     0 my $enc = Encode::find_encoding($n);
3490 0         0 if ($enc and ref($enc) ne 'Encode::XS') { # resolve alias such as Encode::JP::JIS7=HASH(0x292a9d0)
3491 0         0 $pkg = ref($enc);
3492 0         0 $pkg =~ s/^(Encode::\w+)(::.*)/$1/; # collapse to the @dl_module name
3493             $enc = Encode->find_alias($n);
3494 0 0 0     0 }
      0        
3495 0         0 if ($enc and ref($enc) eq 'Encode::XS' and $sv->IVX == $$enc) {
3496 0         0 $name = $n;
3497 0 0       0 $name =~ s/-/_/g;
3498 0         0 $name .= "_encoding" if $name !~ /_encoding$/;
3499 0 0       0 mark_package($pkg) ;
3500 0         0 if ($pkg ne 'Encode') {
  0         0  
3501 0         0 svref_2object( \&{"$pkg\::bootstrap"} )->save;
3502             mark_package('Encode');
3503 0         0 }
3504             last;
3505             }
3506 0 0       0 }
3507 0 0       0 if ($name) {
3508             warn "$pkg $Encode::VERSION remap found for constant $name\n" if $verbose;
3509 0         0 } else {
3510             warn "Warning: Possible missing remap for compile-time XS symbol in $pkg $fullname $ivxhex [#305]\n";
3511             }
3512             }
3513             }
3514             # Encode-2.59 uses a different name without _encoding
3515 0         0 elsif ($Encode::VERSION ge '2.58' and Encode::find_encoding($name)) {
3516 0 0       0 my $enc = Encode::find_encoding($name);
3517 0         0 $pkg = ref($enc) if ref($enc) ne 'Encode::XS';
3518 0         0 $name .= "_encoding";
3519 0 0       0 $name =~ s/-/_/g;
3520 0 0       0 $pkg = 'Encode' unless $pkg;
3521             warn "$pkg $Encode::VERSION with remap support for $name (find 2)\n" if $verbose;
3522             }
3523             # now that is a weak heuristic, which misses #305
3524             elsif (defined ($Net::DNS::VERSION)
3525 0 0       0 and $Net::DNS::VERSION =~ /^0\.(6[789]|7[1234])/) {
3526 0         0 if ($fullname eq 'svop const') {
3527 0 0       0 $name = "ascii_encoding";
3528 0         0 $pkg = 'Encode' unless $pkg;
3529             warn "Warning: Patch Net::DNS external XS symbol $pkg\::$name $ivxhex [RT #94069]\n";
3530             }
3531             }
3532 0         0 elsif ($pkg eq 'Net::LibIDN') {
3533             $name = "idn_to_ascii"; # ??
3534             }
3535              
3536 0 0 0     0 # new API (only Encode so far)
      0        
3537 0 0       0 if ($pkg and $name and $name =~ /^[a-zA-Z_0-9-]+$/) { # valid symbol name
3538 0         0 warn "Remap IOK|POK $pkg with $name\n" if $verbose;
3539 0         0 save_remap($pkg, $pkg, $name, $ivxhex, 0);
3540 0 0       0 $ivx = "0UL /* $ivxhex => $name */";
3541             mark_package($pkg, 1) if $fullname =~ /^(svop const|padop)/;
3542             }
3543 0         0 else {
3544             warn "Warning: Possible missing remap for compile-time XS symbol in $pkg $fullname $ivxhex [#305]\n";
3545 0         0 }
3546             return $ivx;
3547             }
3548              
3549 0     0   0 sub B::PVMG::save {
3550 0         0 my ($sv, $fullname) = @_;
3551 0 0       0 my $sym = objsym($sv);
3552 0 0       0 if (defined $sym) {
3553 0 0       0 if ($in_endav) {
3554 0         0 warn "in_endav: static_free without $sym\n" if $debug{av};
  0         0  
3555             @B::C::static_free = grep {$_ ne $sym} @B::C::static_free;
3556 0         0 }
3557             return $sym;
3558 0         0 }
3559             my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname);
3560             #warn sprintf( "PVMG %s (0x%x) $pvsym, $len, $cur, $pv\n", $sym, $$sv ) if $debug{mg};
3561 0         0  
3562             my ($ivx,$nvx);
3563 0 0 0     0 # since 5.11 REGEXP isa PVMG, but has no IVX and NVX methods
3564 0         0 if ($] >= 5.011 and ref($sv) eq 'B::REGEXP') {
3565             return B::REGEXP::save($sv, $fullname);
3566             }
3567 0         0 else {
3568 0         0 $ivx = ivx($sv->IVX); # XXX How to detect HEK* namehek?
3569             $nvx = nvx($sv->NVX); # it cannot be xnv_u.xgv_stash ptr (BTW set by GvSTASH later)
3570              
3571             # See #305 Encode::XS: XS objects are often stored as SvIV(SvRV(obj)). The real
3572             # address needs to be patched after the XS object is initialized.
3573             # But how detect them properly?
3574             # Detect ptr to extern symbol in shared library and remap it in init2
3575             # Safe and mandatory currently only Net-DNS-0.67 - 0.74.
3576 0 0 0     0 # svop const or pad OBJECT,IOK
      0        
      0        
3577             if (((!$ITHREADS
3578             and $fullname
3579             and $fullname =~ /^svop const|^padop|^Encode::Encoding| :pad\[1\]/)
3580             or $ITHREADS)
3581             and $sv->IVX > LOWEST_IMAGEBASE # some crazy heuristic for a sharedlibrary ptr in .data (> image_base)
3582             and ref($sv->SvSTASH) ne 'B::SPECIAL')
3583 0         0 {
3584             $ivx = patch_dlsym($sv, $fullname, $ivx);
3585             }
3586             }
3587 0         0  
3588 0 0       0 my $tmp_pvsym = $pvsym;
3589 0 0       0 if ($PERL510) {
3590 0 0       0 if ($sv->FLAGS & SVf_ROK) { # sv => sv->RV cannot be initialized static.
3591             $init->add(sprintf("SvRV_set(&sv_list[%d], (SV*)%s);", $svsect->index+1, $pvsym))
3592 0         0 if $pvsym ne '';
3593 0         0 $pvsym = 'NULL';
3594             $static = 1;
3595 0 0       0 }
3596 0 0 0     0 if ($PERL514) {
3597 0         0 $tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static
3598 0         0 $xpvmgsect->comment("STASH, MAGIC, cur, len, xiv_u, xnv_u");
3599             $xpvmgsect->add(sprintf("Nullhv, {0}, %u, %u, {%s}, {%s}",
3600             $cur, $len, $ivx, $nvx));
3601 0         0 } else {
3602 0         0 $xpvmgsect->comment("xnv_u, cur, len, xiv_u, xmg_u, xmg_stash");
3603             $xpvmgsect->add(sprintf("{%s}, %u, %u, {%s}, {0}, Nullhv",
3604             $nvx, $cur, $len, $ivx));
3605 0 0       0 }
    0          
3606             $svsect->add(sprintf("&xpvmg_list[%d], $u32fmt, 0x%x, {%s}",
3607             $xpvmgsect->index, $sv->REFCNT, $flags,
3608             $tmp_pvsym eq 'NULL' ? '0' :
3609             ($C99?".svu_pv=(char*)":"(char*)").$tmp_pvsym));
3610             }
3611 0 0 0     0 else {
3612 0         0 if ($pvsym =~ /PL_sv_undef/ and $ITHREADS) {
3613             $pvsym = 'NULL'; # Moose 5.8.9d
3614 0         0 }
3615             $xpvmgsect->add(sprintf("(char*)%s, %u, %u, %s, %s, 0, 0",
3616 0         0 $pvsym, $cur, $len, $ivx, $nvx));
3617             $svsect->add(sprintf("&xpvmg_list[%d], $u32fmt, 0x%x",
3618             $xpvmgsect->index, $sv->REFCNT, $flags));
3619 0 0       0 }
3620 0         0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3621 0 0 0     0 my $s = "sv_list[".$svsect->index."]";
    0          
3622             if ( !$static ) { # do not overwrite RV slot (#273)
3623 0 0       0 # XXX comppadnames need &PL_sv_undef instead of 0 (?? which testcase?)
3624 0         0 if ($PERL510) {
3625             $init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) );
3626 0         0 } else {
3627             $init->add( savepvn( sprintf( "xpvmg_list[%d].xpv_pv", $xpvmgsect->index ),
3628             $pv, $sv, $cur ) );
3629             }
3630 0         0 } elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) {
3631             $init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym ));
3632 0         0 }
3633 0         0 $sym = savesym( $sv, "&".$s );
3634 0         0 $sv->save_magic($fullname);
3635             return $sym;
3636             }
3637              
3638             # mark threads::shared to be xs-loaded
3639 0 0   0 0 0 sub mark_threads {
3640 0         0 if ( $INC{'threads.pm'} ) {
3641 0         0 my $stash = 'threads';
3642 0         0 mark_package($stash);
3643 0         0 $use_xsloader = 1;
3644 0 0       0 $xsub{$stash} = 'Dynamic-' . $INC{'threads.pm'};
3645             warn "mark threads for 'P' magic\n" if $debug{mg};
3646 0 0       0 } else {
3647             warn "ignore to mark threads for 'P' magic\n" if $debug{mg};
3648 0 0       0 }
3649 0         0 if ( $INC{'threads/shared.pm'} ) {
3650 0         0 my $stash = 'threads::shared';
3651             mark_package($stash);
3652 0         0 # XXX why is this needed? threads::shared should be initialized automatically
3653 0         0 $use_xsloader = 1; # ensure threads::shared is initialized
3654 0 0       0 $xsub{$stash} = 'Dynamic-' . $INC{'threads/shared.pm'};
3655             warn "mark threads::shared for 'P' magic\n" if $debug{mg};
3656 0 0       0 } else {
3657             warn "ignore to mark threads::shared for 'P' magic\n" if $debug{mg};
3658             }
3659             }
3660              
3661 0     0   0 sub B::PVMG::save_magic {
3662 0         0 my ($sv, $fullname) = @_;
3663 0         0 my $sv_flags = $sv->FLAGS;
3664 0 0 0     0 my $pkg;
3665 0 0       0 return if $fullname and $fullname eq '%B::C::';
3666 0         0 if ($debug{mg}) {
3667 0 0       0 my $flagspv = "";
3668 0 0 0     0 $fullname = '' unless $fullname;
      0        
3669             $flagspv = $sv->flagspv if $debug{flags} and $PERL510 and !$sv->MAGICAL;
3670             warn sprintf( "saving magic for %s %s (0x%x) flags=0x%x%s - called from %s:%s\n",
3671 0 0       0 B::class($sv), $fullname, $$sv, $sv_flags, $debug{flags} ? "(".$flagspv.")" : "",
  0         0  
  0         0  
3672             @{[(caller(1))[3]]}, @{[(caller(1))[2]]});
3673             }
3674              
3675             # crashes on STASH=0x18 with HV PERL_MAGIC_overload_table stash %version:: flags=0x3280000c
3676             # issue267 GetOpt::Long SVf_AMAGIC|SVs_RMG|SVf_OOK
3677 0 0 0     0 # crashes with %Class::MOP::Instance:: flags=0x2280000c also
    0 0        
      0        
      0        
      0        
3678 0 0       0 if (ref($sv) eq 'B::HV' and $] > 5.018 and $sv->MAGICAL and $fullname =~ /::$/) {
3679             warn sprintf("skip SvSTASH for overloaded HV %s flags=0x%x\n", $fullname, $sv_flags)
3680             if $verbose;
3681             # [cperl #60] not only overloaded, version also
3682 0 0       0 } elsif (ref($sv) eq 'B::HV' and $] > 5.018 and $fullname =~ /(version|File)::$/) {
3683             warn sprintf("skip SvSTASH for %s flags=0x%x\n", $fullname, $sv_flags)
3684             if $verbose;
3685 0         0 } else {
3686 0         0 my $pkgsym;
3687 0 0 0     0 $pkg = $sv->SvSTASH;
3688 0 0       0 if ($pkg and $$pkg) {
3689             my $pkgname = $pkg->can('NAME') ? $pkg->NAME : $pkg->NAME_HEK."::DESTROY";
3690 0 0 0     0 warn sprintf("stash isa class \"%s\" (%s)\n", $pkgname, ref $pkg)
3691             if $debug{mg} or $debug{gv};
3692             # 361 do not force dynaloading IO via IO::Handle upon us
3693 0 0 0     0 # core already initialized this stash for us
3694 0 0       0 unless ($fullname eq 'main::STDOUT' and $] >= 5.018) {
3695 0 0 0     0 if (ref $pkg eq 'B::HV') {
3696 0         0 if ($fullname !~ /::$/ or $B::C::stash) {
3697             $pkgsym = $pkg->save($fullname);
3698 0         0 } else {
3699             $pkgsym = savestashpv($pkgname);
3700             }
3701 0         0 } else {
3702             $pkgsym = 'NULL';
3703             }
3704              
3705 0 0 0     0 warn sprintf( "xmg_stash = \"%s\" as %s\n", $pkgname, $pkgsym )
3706             if $debug{mg} or $debug{gv};
3707             # Q: Who is initializing our stash from XS? ->save is missing that.
3708             # A: We only need to init it when we need a CV
3709 0 0       0 # defer for XS loaded stashes with AMT magic
3710 0         0 if (ref $pkg eq 'B::HV') {
3711 0         0 $init->add( sprintf( "SvSTASH_set(s\\_%x, (HV*)s\\_%x);", $$sv, $$pkg ) );
3712 0 0       0 $init->add( sprintf( "SvREFCNT((SV*)s\\_%x) += 1;", $$pkg ) );
3713             $init->add("++PL_sv_objcount;") unless ref($sv) eq "B::IO";
3714             # XXX
3715             #push_package($pkg->NAME); # correct code, but adds lots of new stashes
3716             }
3717             }
3718             }
3719 0 0 0     0 }
3720             $init->add(sprintf("SvREADONLY_off((SV*)s\\_%x);", $$sv))
3721             if $sv_flags & SVf_READONLY and ref($sv) ne 'B::HV';
3722              
3723 0 0 0     0 # Protect our SVs against non-magic or SvPAD_OUR. Fixes tests 16 and 14 + 23
      0        
3724             if ($PERL510 and !($sv->MAGICAL or $sv_flags & SVf_AMAGIC)) {
3725             warn sprintf("Skipping non-magical PVMG type=%d, flags=0x%x%s\n",
3726 0 0 0     0 $sv_flags && 0xff, $sv_flags, $debug{flags} ? "(".$sv->flagspv.")" : "")
    0          
3727 0         0 if $debug{mg};
3728             return '';
3729             }
3730              
3731 0         0 # disabled. testcase: t/testm.sh Path::Class
3732             if (0 and $PERL518 and $sv_flags & SVf_AMAGIC) {
3733             my $name = $fullname;
3734             $name =~ s/^%(.*)::$/$1/;
3735             $name = $pkg->NAME if $pkg and $$pkg;
3736             warn sprintf("initialize overload cache for %s\n", $fullname )
3737             if $debug{mg} or $debug{gv};
3738             # This is destructive, it removes the magic instead of adding it.
3739             #$init1->add(sprintf("Gv_AMG(%s); /* init overload cache for %s */", savestashpv($name),
3740             # $fullname));
3741             }
3742 0         0  
3743 0         0 my @mgchain = $sv->MAGIC;
3744 0         0 my ( $mg, $type, $obj, $ptr, $len, $ptrsv );
3745 0         0 my $magic = '';
3746 0         0 foreach $mg (@mgchain) {
3747 0         0 $type = $mg->TYPE;
3748 0         0 $ptr = $mg->PTR;
3749 0         0 $len = $mg->LENGTH;
3750 0 0       0 $magic .= $type;
3751 0         0 if ( $debug{mg} ) {
3752             warn sprintf( "%s %s magic 0x%x\n", $fullname, cchar($type), $mg->FLAGS );
3753             #eval {
3754             # warn sprintf( "magic %s (0x%x), obj %s (0x%x), type %s, ptr %s\n",
3755             # B::class($sv), $$sv, B::class($obj), $$obj, cchar($type),
3756             # cstring($ptr) );
3757             #};
3758             }
3759 0 0       0  
3760             unless ( $type =~ /^[rDn]$/ ) { # r - test 23 / D - Getopt::Long
3761             # 5.10: Can't call method "save" on unblessed reference
3762             #warn "Save MG ". $obj . "\n" if $PERL510;
3763 0         0 # 5.11 'P' fix in B::IV::save, IV => RV
3764 0 0 0     0 $obj = $mg->OBJ;
3765             $obj->save($fullname)
3766 0 0       0 unless $PERL510 and ref $obj eq 'SCALAR';
3767             mark_threads if $type eq 'P';
3768             }
3769 0 0       0  
    0          
    0          
    0          
    0          
    0          
3770             if ( $len == HEf_SVKEY ) {
3771             # The pointer is an SV* ('s' sigelem e.g.)
3772 0 0 0     0 # XXX On 5.6 ptr might be a SCALAR ref to the PV, which was fixed later
    0          
3773 0         0 if (ref($ptr) eq 'SCALAR') {
3774             $ptrsv = svref_2object($ptr)->save($fullname);
3775 0         0 } elsif ($ptr and ref $ptr) {
3776             $ptrsv = $ptr->save($fullname);
3777 0         0 } else {
3778             $ptrsv = 'NULL';
3779 0 0       0 }
3780 0         0 warn "MG->PTR is an SV*\n" if $debug{mg};
3781             $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, (char *)%s, %d);",
3782 0 0       0 $$sv, $$obj, cchar($type), $ptrsv, $len));
3783 0         0 if (!($mg->FLAGS & 2)) {
3784             mg_RC_off($mg, $sv, $type);
3785             }
3786             }
3787             # coverage $Template::Stash::PRIVATE
3788 0 0       0 elsif ( $type eq 'r' ) { # qr magic, for 5.6 done in C.xs. test 20
  0         0  
3789             my $rx = $PERL56 ? ${$mg->OBJ} : $mg->REGEX;
3790 0         0 # stored by some PMOP *pm = cLOGOP->op_other (pp_ctl.c) in C.xs
3791 0 0       0 my $pmop = $Regexp{$rx};
3792 0         0 if (!$pmop) {
3793             warn "Warning: C.xs PMOP missing for QR\n";
3794 0         0 } else {
3795 0 0       0 my ($resym, $relen);
3796 0         0 if ($PERL56) {
3797 0 0       0 ($resym, $relen) = savere( $pmop->precomp ); # 5.6 has precomp only in PMOP
3798             ($resym, $relen) = savere( $mg->precomp ) unless $relen;
3799 0         0 } else {
3800             ($resym, $relen) = savere( $mg->precomp );
3801 0         0 }
3802 0 0       0 my $pmsym = $pmop->save(0, $fullname);
3803 0         0 if ($PERL510) {
3804 0         0 push @B::C::static_free, $resym;
3805             $init->add( split /\n/,
3806             sprintf <pmflags, $$sv, cchar($type), cstring($ptr), $len );
3807             {
3808             REGEXP* rx = CALLREGCOMP((SV* const)%s, %d);
3809             sv_magic((SV*)s\\_%x, (SV*)rx, %s, %s, %d);
3810             }
3811             CODE1
3812             }
3813 0         0 else {
3814 0         0 $pmsym =~ s/\(OP\*\)\&pmop_list/&pmop_list/;
3815             $init->add( split /\n/,
3816             sprintf <
3817             {
3818             REGEXP* rx = pregcomp((char*)$resym,(char*)($resym + $relen), (PMOP*)$pmsym);
3819             sv_magic((SV*)s\\_%x, (SV*)rx, %s, %s, %d);
3820             }
3821             CODE2
3822             }
3823             }
3824             }
3825             elsif ( $type eq 'D' ) { # XXX regdata AV - coverage? i95, 903
3826 0 0       0 # see Perl_mg_copy() in mg.c
3827             $init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
3828             $$sv, $fullname eq 'main::-' ? 0 : $$sv, "'D'", cstring($ptr), $len ));
3829             }
3830             elsif ( $type eq 'n' ) { # shared_scalar is from XS dist/threads-shared
3831 0         0 # XXX check if threads is loaded also? otherwise it is only stubbed
3832 0         0 mark_threads;
3833             $init->add(sprintf("sv_magic((SV*)s\\_%x, Nullsv, %s, %s, %d);",
3834             $$sv, "'n'", cstring($ptr), $len ));
3835             }
3836 0         0 elsif ( $type eq 'c' ) { # and !$PERL518
3837             $init->add(sprintf(
3838             "/* AMT overload table for the stash %s s\\_%x is generated dynamically */",
3839             $fullname, $$sv ));
3840             }
3841             elsif ( $type eq ':' ) { # symtab magic
3842 0         0 # search $ptr in list of pmops and replace it. e.g. (char*)&pmop_list[0]
3843 0         0 my $pmop_ptr = unpack("J", $mg->PTR);
3844 0 0       0 my $pmop;
3845 0 0       0 $pmop = $B::C::Regexp{$pmop_ptr} if defined $pmop_ptr;
3846             my $pmsym = $pmop ? $pmop->save(0, $fullname)
3847 0 0 0     0 : ''; #sprintf('&pmop_list[%u]', $pmopsect->index);
      0        
3848             warn sprintf("pmop 0x%x not found in our B::C Regexp hash\n", $pmop_ptr || 'undef')
3849 0 0       0 if !$pmop and $verbose;
    0          
3850             $init->add("{\tU32 elements;", # toke.c: PL_multi_open == '?'
3851             sprintf("\tMAGIC *mg = sv_magicext((SV*)s\\_%x, 0, ':', 0, 0, 0);", $$sv),
3852             "\telements = mg->mg_len / sizeof(PMOP**);",
3853             "\tRenewc(mg->mg_ptr, elements + 1, PMOP*, char);",
3854             ($pmop
3855             ? (sprintf("\t((OP**)mg->mg_ptr) [elements++] = (OP*)%s;", $pmsym))
3856             : ( defined $pmop_ptr
3857             ? sprintf( "\t((OP**)mg->mg_ptr) [elements++] = (OP*)s\\_%x;", $pmop_ptr ) : '' )),
3858             "\tmg->mg_len = elements * sizeof(PMOP**);", "}");
3859             }
3860 0         0 else {
3861             $init->add(sprintf(
3862             "sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);",
3863 0 0       0 $$sv, $$obj, cchar($type), cstring($ptr), $len));
3864 0         0 if (!($mg->FLAGS & 2)) {
3865             mg_RC_off($mg, $sv, $type);
3866             }
3867             }
3868 0 0 0     0 }
3869             $init->add(sprintf("SvREADONLY_on((SV*)s\\_%x);", $$sv))
3870 0         0 if $sv_flags & SVf_READONLY and ref($sv) ne 'B::HV';
3871             $magic;
3872             }
3873              
3874             # Since 5.11 also called by IV::save (SV -> IV)
3875 0     0   0 sub B::RV::save {
3876 0         0 my ($sv, $fullname) = @_;
3877 0 0       0 my $sym = objsym($sv);
3878             return $sym if defined $sym;
3879 0         0 warn sprintf( "Saving RV %s (0x%x) - called from %s:%s\n",
  0         0  
3880 0 0       0 B::class($sv), $$sv, @{[(caller(1))[3]]}, @{[(caller(1))[2]]})
3881             if $debug{sv};
3882 0         0  
3883 0 0       0 my $rv = save_rv($sv, $fullname);
3884 0 0       0 return '0' unless $rv;
3885 0         0 if ($PERL510) {
3886             $svsect->comment( "any, refcnt, flags, sv_u" );
3887 0         0 # 5.22 has a wrong RV->FLAGS (https://github.com/perl11/cperl/issues/63)
3888 0 0 0     0 my $flags = $sv->FLAGS;
3889             $flags = 0x801 if $flags & 9 and $PERL522; # not a GV but a ROK IV (21)
3890             # 5.10 has no struct xrv anymore, just sv_u.svu_rv. static or dynamic?
3891 0 0 0     0 # initializer element is computable at load time
3892             $svsect->add( sprintf( "ptr_undef, $u32fmt, 0x%x, {%s}", $sv->REFCNT, $flags,
3893 0 0       0 (($C99 && is_constant($rv)) ? ".svu_rv=$rv" : "0 /*-> $rv */")));
3894 0         0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3895             my $s = "sv_list[".$svsect->index."]";
3896 0 0 0     0 # 354 defined needs SvANY
3897             $init->add( sprintf("$s.sv_any = (char*)&$s - %d;", $Config{ptrsize}))
3898 0 0 0     0 if $] > 5.019 or $ITHREADS;
3899 0 0       0 unless ($C99 && is_constant($rv)) {
3900 0         0 if ( $rv =~ /get_cv/ ) {
3901             $init2->add( "$s.sv_u.svu_rv = (SV*)$rv;" ) ;
3902 0         0 } else {
3903             $init->add( "$s.sv_u.svu_rv = (SV*)$rv;" ) ;
3904             }
3905 0         0 }
3906             return savesym( $sv, "&".$s );
3907             }
3908             else {
3909 0 0 0     0 # GVs need to be handled at runtime
    0 0        
    0          
3910 0         0 if ( ref( $sv->RV ) eq 'B::GV' or $rv =~ /^gv_list/) {
3911 0         0 $xrvsect->add("Nullsv /* $rv */");
3912             $init->add(
3913             sprintf( "xrv_list[%d].xrv_rv = (SV*)%s;", $xrvsect->index, $rv ) );
3914             }
3915             # and stashes, too
3916 0         0 elsif ( $sv->RV->isa('B::HV') && $sv->RV->NAME ) {
3917 0         0 $xrvsect->add("Nullsv /* $rv */");
3918             $init->add(
3919             sprintf( "xrv_list[%d].xrv_rv = (SV*)%s;", $xrvsect->index, $rv ) );
3920             }
3921             # one more: bootstrapped XS CVs (test Class::MOP, no simple testcase yet)
3922             # dynamic; so we need to inc it
3923 0         0 elsif ( $rv =~ /get_cv/ ) {
3924 0         0 $xrvsect->add("Nullsv /* $rv */");
3925             $init2->add(
3926             sprintf( "xrv_list[%d].xrv_rv = (SV*)SvREFCNT_inc(%s);", $xrvsect->index, $rv ) );
3927             }
3928             else {
3929 0         0 #$xrvsect->add($rv); # not static initializable (e.g. cv160 for ExtUtils::Install)
3930 0         0 $xrvsect->add("Nullsv /* $rv */");
3931             $init->add(
3932             sprintf( "xrv_list[%d].xrv_rv = (SV*)SvREFCNT_inc(%s);", $xrvsect->index, $rv ) );
3933 0         0 }
3934 0         0 $svsect->comment( "any, refcnt, flags" );
3935             $svsect->add(sprintf("&xrv_list[%d], $u32fmt, 0x%x",
3936 0 0       0 $xrvsect->index, $sv->REFCNT, $sv->FLAGS));
3937 0         0 $svsect->debug( $fullname, $sv->flagspv ) if $debug{flags};
3938 0         0 my $s = "sv_list[".$svsect->index."]";
3939             return savesym( $sv, "&".$s );
3940             }
3941             }
3942              
3943 0     0 0 0 sub get_isa ($) {
3944 0 0       0 my $name = shift;
3945 0 0       0 if ($PERL510) {
3946 0         0 if (is_using_mro()) { # mro.xs loaded. c3 or dfs
  0         0  
3947             return @{mro::get_linear_isa($name)};
3948 0         0 } else { # dfs only, without loading mro
  0         0  
3949             return @{B::C::get_linear_isa($name)};
3950             }
3951 55     55   930 } else {
  55         179  
  55         10991  
3952 0         0 no strict 'refs';
3953 0 0       0 my $s = "$name\::";
  0         0  
3954 0 0       0 if (exists(${$s}{ISA})) {
  0         0  
3955 0         0 if (exists(${$s}{ISA}{ARRAY})) {
  0         0  
3956             return @{ "$s\::ISA" };
3957             }
3958             }
3959             }
3960             }
3961              
3962             # try_isa($pkg,$name) returns the found $pkg for the method $pkg::$name
3963             # If a method can be called (via UNIVERSAL::can) search the ISA's. No AUTOLOAD needed.
3964             # XXX issue 64, empty @ISA if a package has no subs. in Bytecode ok
3965 0     0 0 0 sub try_isa {
3966 0 0 0     0 my ( $cvstashname, $cvname ) = @_;
3967 0 0       0 return 0 unless defined $cvstashname && defined $cvname;
3968 0         0 if (my $found = $isa_cache{"$cvstashname\::$cvname"}) {
3969             return $found;
3970 55     55   477 }
  55         165  
  55         37345  
3971             no strict 'refs';
3972             # XXX theoretically a valid shortcut. In reality it fails when $cvstashname is not loaded.
3973 0         0 # return 0 unless $cvstashname->can($cvname);
3974             my @isa = get_isa($cvstashname);
3975             warn sprintf( "No definition for sub %s::%s. Try \@%s::ISA=(%s)\n",
3976 0 0       0 $cvstashname, $cvname, $cvstashname, join(",",@isa))
3977 0         0 if $debug{cv};
3978 0 0       0 for (@isa) { # global @ISA or in pad
3979 0 0       0 next if $_ eq $cvstashname;
3980 0 0       0 warn sprintf( "Try &%s::%s\n", $_, $cvname ) if $debug{cv};
  0         0  
3981 0 0       0 if (defined(&{$_ .'::'. $cvname})) {
  0         0  
3982 0         0 if (exists(${$cvstashname.'::'}{ISA})) {
  0         0  
3983             svref_2object( \@{$cvstashname . '::ISA'} )->save("$cvstashname\::ISA");
3984 0         0 }
3985 0         0 $isa_cache{"$cvstashname\::$cvname"} = $_;
3986 0         0 mark_package($_, 1); # force
3987             return $_;
3988 0         0 } else {
3989 0 0       0 $isa_cache{"$_\::$cvname"} = 0;
3990 0         0 if (get_isa($_)) {
3991 0 0       0 my $parent = try_isa($_, $cvname);
3992 0         0 if ($parent) {
3993 0         0 $isa_cache{"$_\::$cvname"} = $parent;
3994 0 0       0 $isa_cache{"$cvstashname\::$cvname"} = $parent;
3995 0 0       0 warn sprintf( "Found &%s::%s\n", $parent, $cvname ) if $debug{gv};
  0         0  
3996 0 0       0 if (exists(${$parent.'::'}{ISA})) {
3997 0         0 warn "save \@$parent\::ISA\n" if $debug{pkg};
  0         0  
3998             svref_2object( \@{$parent . '::ISA'} )->save("$parent\::ISA");
3999 0 0       0 }
  0         0  
4000 0 0       0 if (exists(${$_.'::'}{ISA})) {
4001 0         0 warn "save \@$_\::ISA\n" if $debug{pkg};
  0         0  
4002             svref_2object( \@{$_ . '::ISA'} )->save("$_\::ISA");
4003 0         0 }
4004             return $parent;
4005             }
4006             }
4007             }
4008 0         0 }
4009             return 0; # not found
4010             }
4011              
4012 0 0   0 0 0 sub load_utf8_heavy {
4013             return if $savINC{"utf8_heavy.pl"};
4014 0         0  
4015 0         0 require 'utf8_heavy.pl';
4016 0         0 mark_package('utf8_heavy.pl');
4017 0         0 $curINC{'utf8_heavy.pl'} = $INC{'utf8_heavy.pl'};
4018 0         0 $savINC{"utf8_heavy.pl"} = 1;
4019             add_hashINC("utf8");
4020              
4021             # FIXME: we want to use add_hashINC for utf8_heavy, inc_packname should return an array
4022             # add_hashINC("utf8_heavy.pl");
4023              
4024             # In CORE utf8::SWASHNEW is demand-loaded from utf8 with Perl_load_module()
4025 0         0 # It adds about 1.6MB exe size 32-bit.
  0         0  
4026             svref_2object( \&{"utf8\::SWASHNEW"} )->save;
4027 0         0  
4028             return 1;
4029             }
4030              
4031             # If the sub or method is not found:
4032             # 1. try @ISA, mark_package and return.
4033             # 2. try UNIVERSAL::method
4034             # 3. try compile-time expansion of AUTOLOAD to get the goto &sub addresses
4035 0     0 0 0 sub try_autoload {
4036 55     55   550 my ( $cvstashname, $cvname ) = @_;
  55         147  
  55         3674  
4037 0 0 0     0 no strict 'refs';
4038 0 0       0 return unless defined $cvstashname && defined $cvname;
4039             return 1 if try_isa($cvstashname, $cvname);
4040 55     55   399  
  55         135  
  55         86724  
4041 0 0       0 no strict 'refs';
  0         0  
4042 0 0       0 if (defined(*{'UNIVERSAL::'. $cvname}{CODE})) {
4043 0         0 warn "Found UNIVERSAL::$cvname\n" if $debug{cv};
  0         0  
4044             return svref_2object( \&{'UNIVERSAL::'.$cvname} );
4045 0         0 }
4046             my $fullname = $cvstashname . '::' . $cvname;
4047 0 0       0 warn sprintf( "No definition for sub %s. Try %s::AUTOLOAD\n",
4048 0 0       0 $fullname, $cvstashname ) if $debug{cv};
4049             if ($fullname eq 'utf8::SWASHNEW') {
4050             # utf8_heavy was loaded so far, so defer to a demand-loading stub
4051 0     0   0 # always require utf8_heavy, do not care if it s already in
  0         0  
  0         0  
4052 0         0 my $stub = sub { require 'utf8_heavy.pl'; goto &utf8::SWASHNEW };
4053             return svref_2object( $stub );
4054             }
4055              
4056             # Handle AutoLoader classes. Any more general AUTOLOAD
4057 0         0 # use should be handled by the class itself.
4058 0 0 0     0 my @isa = get_isa($cvstashname);
      0        
4059 0         0 if ( $cvstashname =~ /^POSIX|Storable|DynaLoader|Net::SSLeay|Class::MethodMaker$/
4060             or (exists ${$cvstashname.'::'}{AUTOLOAD} and grep( $_ eq "AutoLoader", @isa ) ) )
4061             {
4062 0         0 # Tweaked version of AutoLoader::AUTOLOAD
4063 0         0 my $dir = $cvstashname;
4064 0 0       0 $dir =~ s(::)(/)g;
4065 0 0       0 warn "require \"auto/$dir/$cvname.al\"\n" if $debug{cv};
  0         0  
  0         0  
4066 0 0       0 eval { local $SIG{__DIE__}; require "auto/$dir/$cvname.al" unless $INC{"auto/$dir/$cvname.al"} };
4067 0 0       0 unless ($@) {
4068 0 0       0 warn "Forced load of \"auto/$dir/$cvname.al\"\n" if $verbose;
4069             return svref_2object( \&$fullname )
4070             if defined &$fullname;
4071             }
4072             }
4073              
4074             # XXX Still not found, now it's getting dangerous (until 5.10 only)
4075             # Search and call ::AUTOLOAD (=> ROOT and XSUB) (test 27, 5.8)
4076 0 0 0     0 # Since 5.10 AUTOLOAD xsubs are already resolved
  0         0  
4077 0         0 if (exists ${$cvstashname.'::'}{AUTOLOAD} and !$PERL510) {
  0         0  
4078             my $auto = \&{$cvstashname.'::AUTOLOAD'};
4079 0         0 # Tweaked version of __PACKAGE__::AUTOLOAD
  0         0  
4080             $AutoLoader::AUTOLOAD = ${$cvstashname.'::AUTOLOAD'} = "$cvstashname\::$cvname";
4081              
4082             # Prevent eval from polluting STDOUT,STDERR and our c code.
4083 0         0 # With a debugging perl STDERR is written
4084 0 0       0 local *REALSTDOUT;
4085 0         0 local *REALSTDERR unless $DEBUGGING;
4086 0 0       0 open(REALSTDOUT,">&STDOUT");
4087 0         0 open(REALSTDERR,">&STDERR") unless $DEBUGGING;
4088 0 0       0 open(STDOUT,">","/dev/null");
4089 0 0       0 open(STDERR,">","/dev/null") unless $DEBUGGING;
4090 0         0 warn "eval \&$cvstashname\::AUTOLOAD\n" if $debug{cv};
  0         0  
4091 0         0 eval { &$auto };
4092 0 0       0 open(STDOUT,">&REALSTDOUT");
4093             open(STDERR,">&REALSTDERR") unless $DEBUGGING;
4094 0 0       0  
4095             unless ($@) {
4096             # we need just the empty auto GV, $cvname->ROOT and $cvname->XSUB,
4097 0         0 # but not the whole CV optree. XXX This still fails with 5.8
  0         0  
4098 0         0 my $cv = svref_2object( \&{$fullname} );
4099             return $cv;
4100             }
4101             }
4102              
4103 0         0 # XXX TODO Check Selfloader (test 31?)
4104 0 0 0     0 svref_2object( \*{$cvstashname.'::AUTOLOAD'} )->save
  0         0  
4105 0         0 if $cvstashname and exists ${$cvstashname.'::'}{AUTOLOAD};
4106 0 0 0     0 svref_2object( \*{$cvstashname.'::CLONE'} )->save
  0         0  
4107             if $cvstashname and exists ${$cvstashname.'::'}{CLONE};
4108       0 0   }
4109             sub Dummy_initxs { }
4110              
4111             # A lexical sub contains no CvGV, just a NAME_HEK, thus the name CvNAMED.
4112             # More problematically $cv->GV vivifies the GV of a NAMED cv from an RV, so avoid !$cv->GV
4113             # See https://github.com/perl11/cperl/issues/63
4114 0     0   0 sub B::CV::is_named {
4115 0 0       0 my ($cv) = @_;
4116 0 0       0 return 0 unless $PERL518;
4117 0         0 return $cv->NAME_HEK if $cv->can('NAME_HEK');
4118             return 0;
4119             # my $gv = $cv->GV;
4120             # return (!$gv or ref($gv) eq 'B::SPECIAL')) ? 1 : 0;
4121             }
4122              
4123 0 0   0 0 0 sub is_phase_name {
4124             $_[0] =~ /^(BEGIN|INIT|UNITCHECK|CHECK|END)$/ ? 1 : 0;
4125             }
4126              
4127 0     0   0 sub B::CV::save {
4128 0         0 my ($cv, $origname) = @_;
4129 0 0       0 my $sym = objsym($cv);
4130 0 0 0     0 if ( defined($sym) ) {
4131 0         0 warn sprintf( "CV 0x%x already saved as $sym\n", $$cv ) if $$cv and $debug{cv};
4132             return $sym;
4133 0 0       0 }
4134 0         0 my $gv = $cv->is_named ? undef : $cv->GV;
4135 0         0 my ( $cvname, $cvstashname, $fullname, $isutf8 );
4136 0         0 $fullname = '';
4137 0 0 0     0 my $CvFLAGS = $cv->CvFLAGS;
    0 0        
4138 0         0 if (!$gv and $cv->is_named) {
4139 0 0       0 $fullname = $cv->NAME_HEK;
4140 0         0 $fullname = '' unless defined $fullname;
4141 0 0       0 $isutf8 = $cv->FLAGS & SVf_UTF8;
4142 0 0       0 warn sprintf( "CV lexsub NAME_HEK $fullname\n") if $debug{cv};
4143 0         0 if ($fullname =~ /^(.*)::(.*?)$/) {
4144 0         0 $cvstashname = $1;
4145             $cvname = $2;
4146             }
4147             }
4148 0         0 elsif ($gv and $$gv) {
4149 0         0 $cvstashname = $gv->STASH->NAME;
4150 0   0     0 $cvname = $gv->NAME;
4151 0         0 $isutf8 = ($gv->FLAGS & SVf_UTF8) || ($gv->STASH->FLAGS & SVf_UTF8);
4152             $fullname = $cvstashname.'::'.$cvname;
4153 0 0 0     0 # XXX gv->EGV does not really help here
4154 0 0       0 if ($PERL522 and $cvname eq '__ANON__') {
4155             if ($origname) {
4156 0 0       0 warn sprintf( "CV with empty PVGV %s -> %s\n",
4157 0         0 $fullname, $origname) if $debug{cv};
4158 0 0       0 $cvname = $fullname = $origname;
4159 0         0 $cvname =~ s/^\Q$cvstashname\E::(.*)( :pad\[.*)?$/$1/ if $cvstashname;
4160 0 0       0 $cvname =~ s/^.*:://;
4161 0         0 if ($cvname =~ m/ :pad\[.*$/) {
4162 0 0       0 $cvname =~ s/ :pad\[.*$//;
4163 0         0 $cvname = '__ANON__' if is_phase_name($cvname);
4164             $fullname = $cvstashname.'::'.$cvname;
4165 0 0       0 }
4166             warn sprintf( "empty -> %s\n", $cvname) if $debug{cv};
4167 0         0 } else {
4168             $cvname = $gv->EGV->NAME;
4169 0 0       0 warn sprintf( "CV with empty PVGV %s -> %s::%s\n",
4170 0         0 $fullname, $cvstashname, $cvname) if $debug{cv};
4171             $fullname = $cvstashname.'::'.$cvname;
4172             }
4173             }
4174 0 0       0 warn sprintf( "CV 0x%x as PVGV 0x%x %s CvFLAGS=0x%x\n",
4175             $$cv, $$gv, $fullname, $CvFLAGS ) if $debug{cv};
4176             # XXX not needed, we already loaded utf8_heavy
4177 0 0 0     0 #return if $fullname eq 'utf8::AUTOLOAD';
4178 0 0       0 return '0' if $all_bc_subs{$fullname} or skip_pkg($cvstashname);
4179 0 0       0 $CvFLAGS &= ~0x400 if $PERL514; # no CVf_CVGV_RC otherwise we cannot set the GV
4180             mark_package($cvstashname, 1) unless $include_package{$cvstashname};
4181 0 0       0 }
4182             $cvstashname = '' unless defined $cvstashname;
4183              
4184 0         0 # XXX TODO need to save the gv stash::AUTOLOAD if exists
4185 0         0 my $root = $cv->ROOT;
4186 0         0 my $cvxsub = $cv->XSUB;
4187 55     55   567 my $isconst;
  55         147  
  55         37436  
  0         0  
4188 0 0       0 { no strict 'subs';
4189             $isconst = $PERL56 ? 0 : $CvFLAGS & CVf_CONST;
4190             }
4191 0 0 0     0  
      0        
4192 0         0 if ( !$isconst && $cvxsub && ( $cvname ne "INIT" ) ) {
4193 0         0 my $egv = $gv->EGV;
4194 0         0 my $stashname = $egv->STASH->NAME;
4195 0 0 0     0 $fullname = $stashname.'::'.$cvname;
4196 0         0 if ( $cvname eq "bootstrap" and !$xsub{$stashname} ) {
4197 0         0 my $file = $gv->FILE;
4198 0 0       0 $decl->add("/* bootstrap $file */");
4199 0         0 warn "Bootstrap $stashname $file\n" if $verbose;
4200             mark_package($stashname);
4201              
4202 0 0 0     0 # Without DynaLoader we must boot and link static
    0 0        
4203 0         0 if ( !$Config{usedl} ) {
4204             $xsub{$stashname} = 'Static';
4205             }
4206             # if it not isa('DynaLoader'), it should hopefully be XSLoaded
4207             # ( attributes being an exception, of course )
4208             elsif ( !UNIVERSAL::isa( $stashname, 'DynaLoader' )
4209             and ($stashname ne 'attributes' || $] >= 5.011))
4210 0         0 {
4211 0         0 my $stashfile = $stashname;
4212 0 0       0 $stashfile =~ s/::/\//g;
4213 0         0 if ($file =~ /XSLoader\.pm$/) { # almost always the case
4214             $file = $INC{$stashfile . ".pm"};
4215 0 0       0 }
4216 0         0 unless ($file) { # do the reverse as DynaLoader: soname => pm
4217 0 0       0 my ($laststash) = $stashname =~ /::([^:]+)$/;
4218 0         0 $laststash = $stashname unless $laststash;
4219 0         0 my $sofile = "auto/" . $stashfile . '/' . $laststash . '\.' . $Config{dlext};
4220 0 0       0 for (@DynaLoader::dl_shared_objects) {
4221 0         0 if (m{^(.+/)$sofile$}) {
  0         0  
4222             $file = $1. $stashfile.".pm"; last;
4223             }
4224             }
4225 0         0 }
4226 0         0 $xsub{$stashname} = 'Dynamic-'.$file;
4227             force_saving_xsloader();
4228             }
4229 0         0 else {
4230             $xsub{$stashname} = 'Dynamic';
4231             # DynaLoader was for sure loaded, before so we execute the branch which
4232 0         0 # does walk_syms and add_hashINC
4233             mark_package('DynaLoader', 1);
4234             }
4235              
4236             # INIT is removed from the symbol table, so this call must come
4237             # from PL_initav->save. Re-bootstrapping will push INIT back in,
4238 0 0       0 # so nullop should be sent.
4239 0         0 warn $fullname."\n" if $debug{sub};
4240             return qq/NULL/;
4241             }
4242             else {
4243             # XSUBs for IO::File, IO::Handle, IO::Socket, IO::Seekable and IO::Poll
4244 0         0 # are defined in IO.xs, so let's bootstrap it
4245 0 0       0 my @IO = qw(IO::File IO::Handle IO::Socket IO::Seekable IO::Poll);
  0         0  
4246             if (grep { $stashname eq $_ } @IO) {
4247             # mark_package('IO', 1);
4248 0         0 # $xsub{IO} = 'Dynamic-'. $INC{'IO.pm'}; # XSLoader (issue59)
4249 0         0 svref_2object( \&IO::bootstrap )->save;
4250 0         0 mark_package('IO::Handle', 1);
4251             mark_package('SelectSaver', 1);
4252             #for (@IO) { # mark all IO packages
4253             # mark_package($_, 1);
4254             #}
4255             }
4256 0 0       0 }
4257 0 0       0 warn $fullname."\n" if $debug{sub};
4258 55     55   560 unless ( in_static_core($stashname, $cvname) ) {
  55         138  
  55         9016  
4259             no strict 'refs';
4260 0 0       0 warn sprintf( "XSUB $fullname CV 0x%x\n", $$cv )
4261 0 0       0 if $debug{cv};
  0         0  
4262             svref_2object( \*{"$stashname\::bootstrap"} )->save
4263             if $stashname;# and defined ${"$stashname\::bootstrap"};
4264 0         0 # delsym($cv);
4265             return get_cv($fullname, 0);
4266             } else { # Those cvs are already booted. Reuse their GP.
4267 0 0       0 # Esp. on windows it is impossible to get at the XS function ptr
4268 0         0 warn sprintf( "core XSUB $fullname CV 0x%x\n", $$cv ) if $debug{cv};
4269             return get_cv($fullname, 0);
4270             }
4271 0 0 0     0 }
      0        
4272 55     55   469 if ( !$isconst && $cvxsub && $cvname eq "INIT" ) {
  55         177  
  55         85911  
4273 0 0       0 no strict 'refs';
4274 0         0 warn $fullname."\n" if $debug{sub};
4275             return svref_2object( \&Dummy_initxs )->save;
4276             }
4277              
4278 0 0 0     0 # XXX how is ANON with CONST handled? CONST uses XSUBANY [GH #246]
      0        
      0        
      0        
4279             if ($isconst and $cvxsub and !is_phase_name($cvname) and
4280             (
4281             (
4282             $PERL522
4283             and !( $CvFLAGS & SVs_PADSTALE )
4284             and !( $CvFLAGS & CVf_WEAKOUTSIDE )
4285             and !( $fullname && $fullname =~ qr{^File::Glob::GLOB}
4286             and ( $CvFLAGS & (CVf_ANONCONST|CVf_CONST) ) )
4287             )
4288             or (!$PERL522 and !($CvFLAGS & CVf_ANON)) )
4289             ) # skip const magic blocks (Attribute::Handlers)
4290 0         0 {
4291             my $stash = $gv->STASH;
4292 0         0 #warn sprintf("$cvstashname\::$cvname 0x%x -> XSUBANY", $CvFLAGS) if $debug{cv};
4293             my $sv = $cv->XSUBANY;
4294 0 0       0 warn sprintf( "CV CONST 0x%x %s::%s -> 0x%x as %s\n", $$gv, $cvstashname, $cvname,
4295             $sv, ref $sv) if $debug{cv};
4296 0         0 # warn sprintf( "%s::%s\n", $cvstashname, $cvname) if $debug{sub};
4297 0         0 my $stsym = $stash->save;
4298 0 0       0 my $name = cstring($cvname);
4299             if ($] >= 5.016) { # need to check 'Encode::XS' constant encodings
4300 0 0 0     0 # warn "$sv CONSTSUB $name";
      0        
4301 0         0 if ((ref($sv) eq 'B::IV' or ref($sv) eq 'B::PVMG') and $sv->FLAGS & SVf_ROK) {
4302 0 0 0     0 my $rv = $sv->RV;
4303 0         0 if ($rv->FLAGS & (SVp_POK|SVf_IOK) and $rv->IVX > LOWEST_IMAGEBASE) {
4304             patch_dlsym($rv, $fullname, $rv->IVX);
4305             }
4306             }
4307             }
4308             # scalarref: t/CORE/v5.22/t/op/const-optree.t at curpad_syms[6]
4309             # main::__ANON__ -> CxPOPSUB_DONE=SCALAR
4310 0 0 0     0 # TODO Attribute::Handlers #171, test 176
    0 0        
      0        
4311             if ($sv and ref($sv) and ref($sv) =~ /^(SCALAR|ARRAY|HASH|CODE|REF)$/) {
4312 0 0       0 # Save XSUBANY, maybe ARRAY or HASH also?
4313 0         0 warn "SCALAR const sub $cvstashname\::$cvname -> $sv\n" if $debug{cv};
4314 0         0 my $vsym = svref_2object( \$sv )->save;
4315 0         0 my $cvi = "cv".$cv_index++;
4316 0         0 $decl->add("Static CV* $cvi;");
4317 0         0 $init->add("$cvi = newCONSTSUB( $stsym, $name, (SV*)$vsym );");
4318             return savesym( $cv, $cvi );
4319             }
4320 0         0 elsif ($sv and ref($sv) =~ /^B::[ANRPI]/) { # use constant => ()
4321 0         0 my $vsym = $sv->save;
4322 0         0 my $cvi = "cv".$cv_index++;
4323 0         0 $decl->add("Static CV* $cvi;");
4324 0         0 $init->add("$cvi = newCONSTSUB( $stsym, $name, (SV*)$vsym );");
4325             return savesym( $cv, $cvi );
4326 0 0       0 } else {
4327             warn "Warning: Undefined const sub $cvstashname\::$cvname -> $sv\n" if $verbose;
4328             }
4329             }
4330              
4331             # This define is forwarded to the real sv below
4332 0         0 # The new method, which saves a SV only works since 5.10 (? Does not work in newer perls)
4333 0         0 my $sv_ix = $svsect->index + 1;
4334 0         0 my $xpvcv_ix;
4335 0 0       0 my $new_cv_fw = 0;#$PERL510; # XXX this does not work yet
4336 0         0 if ($new_cv_fw) {
4337             $sym = savesym( $cv, "CVIX$sv_ix" );
4338 0         0 } else {
4339 0 0       0 $svsect->add("CVIX$sv_ix");
4340 0         0 $svsect->debug( "&".$fullname, $cv->flagspv ) if $debug{flags};
4341 0         0 $xpvcv_ix = $xpvcvsect->index + 1;
4342             $xpvcvsect->add("XPVCVIX$xpvcv_ix");
4343 0         0 # Save symbol now so that GvCV() doesn't recurse back to us via CvGV()
4344             $sym = savesym( $cv, "&sv_list[$sv_ix]" );
4345             }
4346              
4347 0 0       0 warn sprintf( "saving %s CV 0x%x as %s\n", $fullname, $$cv, $sym )
4348 0 0 0     0 if $debug{cv};
4349 0         0 if (!$$root and $] < 5.010) {
4350 0         0 $package_pv = $cvstashname;
4351             push_package($package_pv);
4352 0 0       0 }
4353 0         0 if ($fullname eq 'utf8::SWASHNEW') { # bypass utf8::AUTOLOAD, a new 5.13.9 mess
4354             load_utf8_heavy();
4355             }
4356 0 0       0  
4357 0 0 0     0 if ($fullname eq 'IO::Socket::SSL::SSL_Context::new') {
4358             if ($IO::Socket::SSL::VERSION ge '1.956' and $IO::Socket::SSL::VERSION lt '1.995') {
4359             # See https://code.google.com/p/perl-compiler/issues/detail?id=317
4360 0         0 # https://rt.cpan.org/Ticket/Display.html?id=95452
4361             warn "Warning: Your IO::Socket::SSL version $IO::Socket::SSL::VERSION is unsupported to create\n".
4362             " a server. You need to upgrade IO::Socket::SSL to at least 1.995 [CPAN #95452]\n";
4363             }
4364             }
4365 0 0 0     0  
4366 0         0 if (!$$root && !$cvxsub) {
4367 0 0       0 my $reloaded;
    0          
4368 0         0 if ($cvstashname =~ /^(bytes|utf8)$/) { # no autoload, force compile-time
4369 0         0 force_heavy($cvstashname);
  0         0  
4370 0         0 $cv = svref_2object( \&{$cvstashname."::".$cvname} );
4371             $reloaded = 1;
4372             } elsif ($fullname eq 'Coro::State::_jit') { # 293
4373 0         0 # need to force reload the jit src
  0         0  
4374 0 0       0 my ($pl) = grep { m|^Coro/jit-| } keys %INC;
4375 0         0 if ($pl) {
4376 0         0 delete $INC{$pl};
4377 0         0 require $pl;
  0         0  
4378 0         0 $cv = svref_2object( \&{$fullname} );
4379             $reloaded = 1;
4380             }
4381 0 0       0 }
4382 0 0       0 if ($reloaded) {
4383 0         0 if (!$cv->is_named) {
4384             $gv = $cv->GV;
4385 0 0       0 warn sprintf( "Redefined CV 0x%x as PVGV 0x%x %s CvFLAGS=0x%x\n",
4386             $$cv, $$gv, $fullname, $CvFLAGS ) if $debug{cv};
4387 0         0 } else {
4388 0 0       0 $fullname = $cv->NAME_HEK;
4389 0 0       0 $fullname = '' unless defined $fullname;
4390 0         0 if ($fullname =~ /^(.*)::(.*?)$/) {
4391 0         0 $cvstashname = $1;
4392             $cvname = $2;
4393             }
4394 0 0       0 warn sprintf( "Redefined CV 0x%x as NAMED %s CvFLAGS=0x%x\n",
4395             $$cv, $fullname, $CvFLAGS ) if $debug{cv};
4396 0         0 }
4397 0         0 $sym = savesym( $cv, $sym );
4398 0         0 $root = $cv->ROOT;
4399             $cvxsub = $cv->XSUB;
4400             }
4401 0 0 0     0 }
4402 0 0       0 if ( !$$root && !$cvxsub ) {
4403 0 0       0 if ( my $auto = try_autoload( $cvstashname, $cvname ) ) {
4404 0         0 if (ref $auto eq 'B::CV') { # explicit goto or UNIVERSAL
4405 0         0 $root = $auto->ROOT;
4406 0 0       0 $cvxsub = $auto->XSUB;
4407             if ($$auto) {
4408 0         0 # XXX This has now created a wrong GV name!
4409 0         0 my $oldcv = $cv;
4410 0         0 $cv = $auto ; # This is new. i.e. via AUTOLOAD or UNIVERSAL, in another stash
4411 0 0       0 my $gvnew = $cv->GV;
4412 0 0 0     0 if ($$gvnew) {
4413 0         0 if ($cvstashname ne $gvnew->STASH->NAME or $cvname ne $gvnew->NAME) { # UNIVERSAL or AUTOLOAD
4414 0 0       0 my $newname = $gvnew->STASH->NAME."::".$gvnew->NAME;
4415 0 0       0 warn " New $newname autoloaded. remove old cv\n" if $debug{sub}; # and wrong GV?
4416 0         0 unless ($new_cv_fw) {
4417 0         0 $svsect->remove;
4418             $xpvcvsect->remove;
4419 0         0 }
4420 0 0       0 delsym($oldcv);
4421             return $cv->save($newname) if !$PERL510;
4422 55     55   526  
  55         132  
  55         432811  
4423 0         0 no strict 'refs';
  0         0  
4424 0 0       0 my $newsym = svref_2object( \*{$newname} )->save;
4425 0 0       0 my $cvsym = defined objsym($cv) ? objsym($cv) : $cv->save($newname);
4426 0 0       0 if (my $oldsym = objsym($gv)) {
4427 0         0 warn "Alias polluted $oldsym to $newsym\n" if $debug{gv};
4428 0         0 $init->add("$oldsym = $newsym;");
4429             delsym($gv);
4430             }# else {
4431             #$init->add("GvCV_set(gv_fetchpv(\"$fullname\", GV_ADD, SVt_PV), (CV*)NULL);");
4432 0         0 #}
4433             return $cvsym;
4434             }
4435 0         0 }
4436 0 0       0 $sym = savesym( $cv, "&sv_list[$sv_ix]" ); # GOTO
4437             warn "$fullname GOTO\n" if $verbose;
4438             }
4439             } else {
4440 0         0 # Recalculated root and xsub
4441 0         0 $root = $cv->ROOT;
4442 0         0 $cvxsub = $cv->XSUB;
4443 0 0       0 my $gv = $cv->GV;
4444 0 0 0     0 if ($$gv) {
4445 0         0 if ($cvstashname ne $gv->STASH->NAME or $cvname ne $gv->NAME) { # UNIVERSAL or AUTOLOAD
4446 0 0       0 my $newname = $gv->STASH->NAME."::".$gv->NAME;
4447 0         0 warn "Recalculated root and xsub $newname. remove old cv\n" if $verbose;
4448 0         0 $svsect->remove;
4449 0         0 $xpvcvsect->remove;
4450 0         0 delsym($cv);
4451             return $cv->save($newname);
4452             }
4453             }
4454 0 0 0     0 }
4455 0 0 0     0 if ( $$root || $cvxsub ) {
4456             warn "Successful forced autoload\n" if $verbose and $debug{cv};
4457             }
4458             }
4459 0 0       0 }
4460 0 0 0     0 if (!$$root) {
      0        
      0        
4461             if ($fullname ne 'threads::tid'
4462 0         0 and $fullname ne 'main::main::'
4463             and ($PERL510 and !defined(&{$cvstashname."::AUTOLOAD"})))
4464             {
4465             # XXX What was here?
4466 0 0       0 }
    0          
4467 0 0       0 if (exists &$fullname) {
4468 0 0 0     0 warn "Warning: Empty &".$fullname."\n" if $debug{sub};
4469             $init->add( "/* empty CV $fullname */" ) if $verbose or $debug{sub};
4470             } elsif ($cv->is_named) {
4471             # need to find the attached lexical sub (#130 + #341) at run-time
4472 0 0       0 # in the PadNAMES array. So keep the empty PVCV
4473             warn "lexsub &".$fullname." saved as empty $sym\n" if $debug{sub};
4474 0 0       0 } else {
4475 0 0 0     0 warn "Warning: &".$fullname." not found\n" if $debug{sub};
4476             $init->add( "/* CV $fullname not found */" ) if $verbose or $debug{sub};
4477 0 0 0     0 # This block broke test 15, disabled
4478             if ($sv_ix == $svsect->index and !$new_cv_fw) { # can delete, is the last SV
4479 0 0       0 warn "No definition for sub $fullname (unable to autoload), skip CV[$sv_ix]\n"
4480 0         0 if $debug{cv};
4481 0         0 $svsect->remove;
4482 0         0 $xpvcvsect->remove;
4483             delsym( $cv );
4484             # Empty CV (methods) must be skipped not to disturb method resolution
4485 0         0 # (e.g. t/testm.sh POSIX)
4486             return '0';
4487             } else {
4488             # interim &AUTOLOAD saved, cannot delete. e.g. Fcntl, POSIX
4489 0 0 0     0 warn "No definition for sub $fullname (unable to autoload), stub CV[$sv_ix]\n"
4490             if $debug{cv} or $verbose;
4491             # continue, must save the 2 symbols from above
4492             }
4493             }
4494             }
4495 0         0  
4496 0         0 my $startfield = 0;
4497 0         0 my $padlist = $cv->PADLIST;
4498 0         0 set_curcv $cv;
4499 0         0 my $padlistsym = 'NULL';
4500 0         0 my $pv = $cv->PV;
4501 0         0 my $xsub = 0;
4502 0 0       0 my $xsubany = "{0}";
    0          
    0          
4503             if ($$root) {
4504             warn sprintf( "saving op tree for CV 0x%x, root=0x%x\n",
4505 0 0 0     0 $$cv, $$root )
4506 0         0 if $debug{cv} and $debug{gv};
4507 0 0 0     0 my $ppname = "";
    0          
4508 0 0       0 if ($cv->is_named) {
4509 0         0 my $name = $cv->can('NAME_HEK') ? $cv->NAME_HEK : "anonlex";
4510 0         0 $ppname = "pp_lexsub_".$name;
4511             $fullname = "".$name;
4512             }
4513 0         0 elsif ($gv and $$gv) {
4514 0         0 my ($stashname, $gvname);
4515 0         0 $stashname = $gv->STASH->NAME;
4516 0         0 $gvname = $gv->NAME;
4517 0 0       0 $fullname = $stashname.'::'.$gvname;
  0         0  
4518 0 0       0 $ppname = ( ${ $gv->FORM } == $$cv ) ? "pp_form_" : "pp_sub_";
4519 0 0       0 if ( $gvname ne "__ANON__" ) {
4520 0         0 $ppname .= ( $stashname eq "main" ) ? $gvname : "$stashname\::$gvname";
4521 0         0 $ppname =~ s/::/__/g;
  0         0  
4522 0 0       0 $ppname =~ s/(\W)/sprintf("0x%x", ord($1))/ge;
4523 0         0 if ( $gvname eq "INIT" ) {
4524 0         0 $ppname .= "_$initsub_index";
4525             $initsub_index++;
4526             }
4527             }
4528 0 0       0 }
4529 0         0 if ( !$ppname ) {
4530 0         0 $ppname = "pp_anonsub_$anonsub_index";
4531             $anonsub_index++;
4532 0         0 }
4533             $startfield = saveoptree( $ppname, $root, $cv->START, $padlist->ARRAY ); # XXX padlist is ignored
4534             #warn sprintf( "done saving op tree for CV 0x%x, flags (%s), name %s, root=0x%x => start=%s\n",
4535             # $$cv, $debug{flags}?$cv->flagspv:sprintf("0x%x",$cv->FLAGS), $ppname, $$root, $startfield )
4536             # if $debug{cv};
4537 0 0       0 # XXX missing cv_start for AUTOLOAD on 5.8
4538 0 0       0 $startfield = objsym($root->next) unless $startfield; # 5.8 autoload has only root
4539 0 0       0 $startfield = "0" unless $startfield; # XXX either CONST ANON or empty body
4540             if ($$padlist) {
4541             # XXX readonly comppad names and symbols invalid
4542             #local $B::C::pv_copy_on_grow = 1 if $B::C::ro_inc;
4543 0 0 0     0 warn sprintf( "saving PADLIST 0x%x for CV 0x%x\n", $$padlist, $$cv )
4544             if $debug{cv} and $debug{gv};
4545 0         0 # XXX avlen 2
4546             $padlistsym = $padlist->save($fullname.' :pad', $cv);
4547             warn sprintf( "done saving %s 0x%x for CV 0x%x\n",
4548 0 0 0     0 $padlistsym, $$padlist, $$cv )
4549             if $debug{cv} and $debug{gv};
4550             # do not record a forward for the pad only
4551              
4552             # issue 298: dynamic CvPADLIST(&END) since 5.18 - END{} blocks
4553 0 0 0     0 # and #169 and #304 Attribute::Handlers
      0        
4554             if ($] > 5.017 and
4555             ($B::C::dyn_padlist or $fullname =~ /^(main::END|main::INIT|Attribute::Handlers)/))
4556 0         0 {
4557             $init->add("{ /* &$fullname needs a dynamic padlist */",
4558             " PADLIST *pad;",
4559             " Newxz(pad, sizeof(PADLIST), PADLIST);",
4560             " Copy($padlistsym, pad, sizeof(PADLIST), char);",
4561             " CvPADLIST($sym) = pad;",
4562             "}");
4563 0         0 } else {
4564             $init->add( "CvPADLIST($sym) = $padlistsym;" );
4565             }
4566 0 0       0 }
4567             warn $fullname."\n" if $debug{sub};
4568             }
4569             elsif ($cv->is_named) {
4570             ;
4571             }
4572 0 0       0 elsif (!exists &$fullname) {
4573             warn $fullname." not found\n" if $debug{sub};
4574 0 0       0 warn "No definition for sub $fullname (unable to autoload)\n"
4575 0 0 0     0 if $debug{cv};
4576             $init->add( "/* $fullname not found */" ) if $verbose or $debug{sub};
4577             # XXX empty CV should not be saved. #159, #235
4578             # $svsect->remove( $sv_ix );
4579             # $xpvcvsect->remove( $xpvcv_ix );
4580 0 0       0 # delsym( $cv );
4581 0         0 if (!$new_cv_fw) {
4582             $symsect->add("XPVCVIX$xpvcv_ix\t0");
4583 0 0       0 }
4584 0 0 0     0 $CvFLAGS &= ~0x1000 if $PERL514; # CVf_DYNFILE
      0        
4585 0 0       0 $CvFLAGS &= ~0x400 if $gv and $$gv and $PERL514; #CVf_CVGV_RC
4586             $symsect->add(sprintf(
4587             "CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x".($PERL510?", {0}":''),
4588 0         0 $sv_ix, $xpvcv_ix, $cv->REFCNT, $CvFLAGS));
4589             return get_cv($fullname, 0);
4590             }
4591              
4592 0 0       0 # Now it is time to record the CV
4593 0         0 if ($new_cv_fw) {
4594 0 0       0 $sv_ix = $svsect->index + 1;
4595 0         0 if (!$cvforward{$sym}) { # avoid duplicates
4596 0         0 $symsect->add(sprintf("%s\t&sv_list[%d]", $sym, $sv_ix )); # forward the old CVIX to the new CV
4597             $cvforward{$sym}++;
4598 0         0 }
4599             $sym = savesym( $cv, "&sv_list[$sv_ix]" );
4600             }
4601              
4602             # $pv = '' unless defined $pv; # Avoid use of undef warnings
4603             #warn sprintf( "CV prototype %s for CV 0x%x\n", cstring($pv), $$cv )
4604 0 0       0 # if $pv and $debug{cv};
4605 0         0 my $proto = defined $pv ? cstring($pv) : 'NULL';
4606 0 0       0 my $pvsym = 'NULL';
4607 0         0 my $cur = defined $pv ? $cv->CUR : 0;
4608 0 0 0     0 my $len = $cur + 1;
4609 0 0       0 $len++ if IsCOW($cv) and !$B::C::cow;
4610             $len = 0 if $B::C::const_strings;
4611 0 0       0 # need to survive cv_undef as there is no protection against static CVs
4612             my $refcnt = $cv->REFCNT + ($PERL510 ? 1 : 0);
4613 0         0 # GV cannot be initialized statically
  0         0  
4614 0 0 0     0 my $xcv_outside = ${ $cv->OUTSIDE };
  0 0       0  
4615             if ($xcv_outside == ${ main_cv() } and !$MULTI) {
4616             # Provide a temp. debugging hack for CvOUTSIDE. The address of the symbol &PL_main_cv
4617             # is known to the linker, the address of the value PL_main_cv not. This is set later
4618 0         0 # (below) at run-time.
4619             $xcv_outside = '&PL_main_cv';
4620 0         0 } elsif (ref($cv->OUTSIDE) eq 'B::CV') {
4621             $xcv_outside = 0; # just a placeholder for a run-time GV
4622 0 0       0 }
    0          
4623 0         0 if ($PERL510) {
4624             $pvsym = save_hek($pv,$fullname,1);
4625             # XXX issue 84: we need to check the cv->PV ptr not the value.
4626 0 0       0 # "" is different to NULL for prototypes
4627             $len = $cur ? $cur+1 : 0;
4628             # TODO:
4629 0 0       0 # my $ourstash = "0"; # TODO stash name to bless it (test 16: "main::")
    0          
4630 0         0 if ($PERL522) {
4631 0 0       0 $CvFLAGS &= ~0x1000; # CVf_DYNFILE off
4632 0         0 $CvFLAGS |= 0x200000 if $CPERL52; # CVf_STATIC on
4633             my $xpvc = sprintf
4634             # stash magic cur {len} cvstash {start} {root} {cvgv} cvfile {cvpadlist} outside outside_seq cvflags cvdepth
4635             ("Nullhv, {0}, %u, {%u}, %s, {%s}, {s\\_%x}, {%s}, %s, {%s}, (CV*)%s, %s, 0x%x, %d",
4636             $cur, $len, "Nullhv",#CvSTASH later
4637             $startfield, $$root,
4638             "0", #GV later
4639             "NULL", #cvfile later (now a HEK)
4640             $padlistsym,
4641             $xcv_outside, #if main_cv set later
4642             ivx($cv->OUTSIDE_SEQ),
4643             $CvFLAGS,
4644             $cv->DEPTH);
4645 0 0       0 # repro only with 5.15.* threaded -q (70c0620) Encode::Alias::define_alias
4646 0 0       0 warn "lexwarnsym in XPVCV OUTSIDE: $xpvc" if $xpvc =~ /, \(CV\*\)iv\d/; # t/testc.sh -q -O3 227
4647 0         0 if (!$new_cv_fw) {
4648             $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4649             #$symsect->add
4650             # (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}"),
4651             # $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4652             # ));
4653 0         0 } else {
4654 0         0 $xpvcvsect->comment('STASH mg_u cur len CV_STASH START_U ROOT_U GV file PADLIST OUTSIDE outside_seq flags depth');
4655 0 0       0 $xpvcvsect->add($xpvc);
4656             $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {%s}",
4657             $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS,
4658 0 0       0 $CPERL52 ? $proto : "0"));
4659             $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4660             }
4661             } elsif ($PERL514) {
4662             # cv_undef wants to free it when CvDYNFILE(cv) is true.
4663 0         0 # E.g. DateTime: boot_POSIX. newXS reuses cv if autoloaded. So turn it off globally.
4664 0         0 $CvFLAGS &= ~0x1000; # CVf_DYNFILE off
4665             my $xpvc = sprintf
4666             # stash magic cur len cvstash start root cvgv cvfile cvpadlist outside outside_seq cvflags cvdepth
4667             ("Nullhv, {0}, %u, %u, %s, {%s}, {s\\_%x}, %s, %s, %s, (CV*)%s, %s, 0x%x, %d",
4668             $cur, $len, "Nullhv",#CvSTASH later
4669             $startfield, $$root,
4670             "0", #GV later
4671             "NULL", #cvfile later (now a HEK)
4672             $padlistsym,
4673             $xcv_outside, #if main_cv set later
4674             ivx($cv->OUTSIDE_SEQ),
4675             $CvFLAGS,
4676             $cv->DEPTH);
4677 0 0       0 #warn "lexwarnsym in XPVCV OUTSIDE: $xpvc" if $xpvc =~ /, \(CV\*\)iv\d/; # t/testc.sh -q -O3 227
4678 0         0 if (!$new_cv_fw) {
4679             $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4680             #$symsect->add
4681             # (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}"),
4682             # $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4683             # ));
4684 0         0 } else {
4685 0         0 $xpvcvsect->comment('STASH mg_u cur len CV_STASH START_U ROOT_U GV file PADLIST OUTSIDE outside_seq flags depth');
4686 0         0 $xpvcvsect->add($xpvc);
4687             $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {0}",
4688 0 0       0 $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS));
4689             $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4690             }
4691             } else { # 5.10-5.13
4692 0 0       0 # Note: GvFORM ends also here. #149 (B::FM), t/testc.sh -O3 -DGCF,-v 149
4693 0 0       0 my $depth = ref($cv) eq 'B::CV' ? $cv->DEPTH : 0;
4694 0         0 my $outside_seq = ref($cv) eq 'B::CV' ? $cv->OUTSIDE_SEQ : '0'; # XXX? #238
4695             my $xpvc = sprintf
4696             ("{%d}, %u, %u, {%s}, {%s}, %s,"
4697             ." %s, {%s}, {s\\_%x}, %s, %s, %s,"
4698             ." (CV*)%s, %s, 0x%x",
4699             0, # GvSTASH later. test 29 or Test::Harness
4700             $cur, $len,
4701             $depth,
4702             "NULL", "Nullhv", #MAGIC + STASH later
4703             "Nullhv",#CvSTASH later
4704             $startfield,
4705             $$root,
4706             "0", #GV later
4707             "NULL", #cv_file later (now a HEK)
4708             $padlistsym,
4709             $xcv_outside, #if main_cv set later
4710             $outside_seq,
4711             $CvFLAGS
4712 0 0       0 );
4713 0         0 if (!$new_cv_fw) {
4714             $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4715             #$symsect->add
4716             # (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}",
4717             # $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4718             # ));
4719 0         0 } else {
4720 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');
4721 0         0 $xpvcvsect->add($xpvc);
4722             $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {0}",
4723 0 0       0 $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS));
4724             $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4725             }
4726 0 0       0 }
4727 0 0 0     0 if ($$cv) {
      0        
4728 0 0       0 if ($PERL518 and (!$gv or ref($gv) eq 'B::SPECIAL')) {
4729 0 0       0 my $lexsub = $cv->can('NAME_HEK') ? $cv->NAME_HEK : "_anonlex_";
4730 0 0       0 $lexsub = '' unless defined $lexsub;
4731 0         0 warn "lexsub name $lexsub" if $debug{gv};
4732 0 0 0     0 my ($cstring, $cur, $utf8) = strlen_flags($lexsub);
4733 0         0 if (!$PERL56 and $utf8) {
4734             $cur = -$cur;
4735 0         0 }
4736             $init->add( "{ /* need a dynamic name hek */",
4737             sprintf(" HEK *lexhek = share_hek(savepvn(%s, %d), %d);",
4738             $cstring, abs($cur), $cur),
4739             sprintf(" CvNAME_HEK_set(s\\_%x, lexhek);", $$cv),
4740             "}");
4741 0         0 } else {
4742             my $gvstash = $gv->STASH;
4743             # defer GvSTASH because with DEBUGGING it checks for GP but
4744             # there's no GP yet.
4745 0 0 0     0 # But with -fstash the gvstash is set later
4746             $init->add( sprintf( "GvXPVGV(s\\_%x)->xnv_u.xgv_stash = s\\_%x;",
4747             $$cv, $$gvstash ) ) if $gvstash and !$B::C::stash;
4748 0 0 0     0 warn sprintf( "done saving GvSTASH 0x%x for CV 0x%x\n", $$gvstash, $$cv )
      0        
4749             if $gvstash and $debug{cv} and $debug{gv};
4750             }
4751 0 0       0 }
4752 0         0 if ( $cv->OUTSIDE_SEQ ) {
4753 0 0       0 my $cop = $symtable{ sprintf( "s\\_%x", $cv->OUTSIDE_SEQ ) };
4754             $init->add( sprintf( "CvOUTSIDE_SEQ(%s) = %s;", $sym, $cop ) ) if $cop;
4755             }
4756             }
4757 0         0 elsif ($PERL56) {
4758             my $xpvc = sprintf("%s, %u, %u, %s, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub, "
4759             ."$xsubany, Nullgv, \"\", %d, s\\_%x, (CV*)%s, 0x%x",
4760             $proto, $cur, $len, ivx($cv->IVX),
4761             nvx($cv->NVX), $startfield, $$root, $cv->DEPTH,
4762             $$padlist, $xcv_outside, $cv->CvFLAGS
4763 0 0       0 );
4764 0         0 if ($new_cv_fw) {
4765             $xpvcvsect->comment('pv cur len off nv magic mg_stash cv_stash start root xsub '
4766 0         0 .'xsubany cv_gv cv_file cv_depth cv_padlist cv_outside cv_flags');
4767 0         0 $xpvcvsect->add($xpvc);
4768             $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x"),
4769 0 0       0 $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS);
4770             $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4771 0         0 } else {
4772             $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4773             }
4774             }
4775 0         0 else { #5.8
4776             my $xpvc = sprintf("%s, %u, %u, %s, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub,"
4777             ." $xsubany, Nullgv, \"\", %d, s\\_%x, (CV*)s\\_%x, 0x%x, 0x%x",
4778             $proto, $cur, $len, ivx($cv->IVX),
4779             nvx($cv->NVX), $startfield, $$root, $cv->DEPTH,
4780             $$padlist, $xcv_outside, $cv->CvFLAGS, $cv->OUTSIDE_SEQ
4781 0 0       0 );
4782 0         0 if ($new_cv_fw) {
4783             $xpvcvsect->comment('pv cur len off nv magic mg_stash cv_stash '
4784             .'start root xsub xsubany cv_gv cv_file cv_depth cv_padlist '
4785 0         0 .'cv_outside cv_flags outside_seq');
4786 0         0 $xpvcvsect->add($xpvc);
4787             $svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x"),
4788 0 0       0 $xpvcvsect->index, $cv->REFCNT, $cv->FLAGS);
4789             $svsect->debug( $fullname, $cv->flagspv ) if $debug{flags};
4790 0         0 } else {
4791             $symsect->add("XPVCVIX$xpvcv_ix\t$xpvc");
4792             }
4793             }
4794 0 0 0     0  
4795             if ($CPERL52 and $Config{uselongdouble}) {
4796             # some very odd static struct init bug: CvOUTSIDE is pointing to CvROOT, CvROOT is corrupt.
4797 0         0 # CvPADLIST also pointing somewhere else. with gcc-5 and 4.8.
4798 0         0 $init->add(sprintf("xpvcv_list[$xpvcv_ix].xcv_root_u.xcv_root = s\\_%x;", $$root));
4799             $init->add("xpvcv_list[$xpvcv_ix].xcv_padlist_u.xcv_padlist = $padlistsym;");
4800             }
4801 0         0  
  0         0  
4802 0 0 0     0 $xcv_outside = ${ $cv->OUTSIDE };
  0 0 0     0  
      0        
4803             if ($xcv_outside == ${ main_cv() } or ref($cv->OUTSIDE) eq 'B::CV') {
4804 0 0       0 # patch CvOUTSIDE at run-time
  0         0  
4805 0         0 if ( $xcv_outside == ${ main_cv() } ) {
4806             $init->add( "CvOUTSIDE($sym) = PL_main_cv;",
4807 0 0       0 "SvREFCNT_inc(PL_main_cv);" );
4808 0 0       0 if ($$padlist) {
    0          
4809 0         0 if ($PERL522) {
4810             $init->add( "CvPADLIST($sym)->xpadl_outid = CvPADLIST(PL_main_cv)->xpadl_id;");
4811 0         0 } elsif ($] >= 5.017005) {
4812             $init->add( "CvPADLIST($sym)->xpadl_outid = PadlistNAMES(CvPADLIST(PL_main_cv));");
4813             }
4814             }
4815 0         0 } else {
4816             $init->add( sprintf("CvOUTSIDE(%s) = (CV*)s\\_%x;", $sym, $xcv_outside) );
4817             #if ($PERL522) {
4818             # $init->add( sprintf("CvPADLIST(%s)->xpadl_outid = CvPADLIST(s\\_%x)->xpadl_id;",
4819             # $sym, $xcv_outside));
4820             #}
4821             }
4822             }
4823 0         0 elsif ($] >= 5.017005 and $xcv_outside and $$padlist) {
4824 0 0       0 my $padl = $cv->OUTSIDE->PADLIST->save;
4825 0         0 if ($PERL522) {
4826             $init->add( sprintf("CvPADLIST(%s)->xpadl_outid = CvPADLIST(s\\_%x)->xpadl_id;",
4827             $sym, $xcv_outside));
4828             } else {
4829             # Make sure that the outer padlist is allocated before PadlistNAMES is accessed.
4830 0         0 # This needs to be postponed (test 227)
4831             $init1->add( sprintf( "CvPADLIST(%s)->xpadl_outid = PadlistNAMES(%s);", $sym, $padl) );
4832             }
4833 0 0 0     0 }
4834             if ($gv and $$gv) {
4835 0 0 0     0 #test 16: Can't call method "FETCH" on unblessed reference. gdb > b S_method_common
4836 0         0 warn sprintf( "Saving GV 0x%x for CV 0x%x\n", $$gv, $$cv ) if $debug{cv} and $debug{gv};
4837 0 0       0 $gv->save;
4838             if ($PERL514) { # FIXME 5.18.0 with lexsubs
4839 0         0 # XXX gvcv might be PVMG
4840             $init->add( sprintf( "CvGV_set((CV*)%s, (GV*)%s);", $sym, objsym($gv)) );
4841             # Since 5.13.3 and CvGV_set there are checks that the CV is not RC (refcounted).
4842             # Assertion "!CvCVGV_RC(cv)" failed: file "gv.c", line 219, function: Perl_cvgv_set
4843 0 0       0 # We init with CvFLAGS = 0 and set it later, as successfully done in the Bytecode compiler
4844             if ($CvFLAGS & 0x0400) { # CVf_CVGV_RC
4845             warn sprintf( "CvCVGV_RC turned off. CV flags=0x%x %s CvFLAGS=0x%x \n",
4846 0 0       0 $cv->FLAGS, $debug{flags}?$cv->flagspv:"", $CvFLAGS & ~0x400)
    0          
4847             if $debug{cv};
4848 0 0       0 $init->add( sprintf( "CvFLAGS((CV*)%s) = 0x%x; %s", $sym, $CvFLAGS,
4849             $debug{flags}?"/* ".$cv->flagspv." */":"" ) );
4850 0         0 }
4851             $init->add("CvSTART($sym) = $startfield;"); # XXX TODO someone is overwriting CvSTART also
4852 0         0 } else {
4853             $init->add( sprintf( "CvGV(%s) = %s;", $sym, objsym($gv) ) );
4854             }
4855 0 0 0     0 warn sprintf("done saving GV 0x%x for CV 0x%x\n",
4856             $$gv, $$cv) if $debug{cv} and $debug{gv};
4857 0 0       0 }
4858 0         0 unless ($optimize_cop) {
4859 0 0 0     0 my $file = $cv->FILE();
    0          
4860 0         0 if ($MULTI) {
4861             $init->add( savepvn( "CvFILE($sym)", $file ) );
4862 0         0 } elsif ($B::C::const_strings && length $file) {
4863             $init->add( sprintf( "CvFILE(%s) = (char *) %s;", $sym, constpv( $file ) ) );
4864 0         0 } else {
4865             $init->add( sprintf( "CvFILE(%s) = %s;", $sym, cstring( $file ) ) );
4866             }
4867 0         0 }
4868 0 0 0     0 my $stash = $cv->STASH;
4869             if ($$stash and ref($stash)) {
4870 0         0 # $init->add("/* saving STASH $fullname */\n" if $debug{cv};
4871             $stash->save($fullname);
4872 0         0 # $sym fixed test 27
4873             $init->add( sprintf( "CvSTASH_set((CV*)%s, s\\_%x);", $sym, $$stash ) );
4874             # 5.18 bless does not inc sv_objcount anymore. broken by ddf23d4a1ae (#208)
4875             # We workaround this 5.18 de-optimization by adding it if at least a DESTROY
4876 0 0 0     0 # method exists.
4877             $init->add("++PL_sv_objcount;") if $cvname eq 'DESTROY' and $] >= 5.017011;
4878 0 0 0     0 warn sprintf( "done saving STASH 0x%x for CV 0x%x\n", $$stash, $$cv )
4879             if $debug{cv} and $debug{gv};
4880 0         0 }
4881 0 0 0     0 my $magic = $cv->MAGIC;
4882 0         0 if ($magic and $$magic) {
4883             $cv->save_magic($fullname); # XXX will this work?
4884 0 0       0 }
4885 0 0       0 if (!$new_cv_fw) {
4886             $symsect->add(sprintf(
4887             "CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x".($PERL510?", {0}":''),
4888             $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS
4889             )
4890             );
4891 0 0       0 }
4892 0 0       0 if ($cur) {
4893             warn sprintf( "Saving CV proto %s for CV $sym 0x%x\n", cstring($pv), $$cv ) if $debug{cv};
4894             }
4895 0 0       0 # issue 84: empty prototypes sub xx(){} vs sub xx{}
4896 0 0 0     0 if (defined $pv) {
    0          
4897 0         0 if ($PERL510 and $cur) {
4898             $init->add( sprintf("SvPVX(&sv_list[%d]) = HEK_KEY(%s);", $sv_ix, $pvsym));
4899 0         0 } elsif (!$B::C::const_strings) { # not static, they are freed when redefined
4900             $init->add( sprintf("SvPVX(&sv_list[%d]) = savepvn(%s, %u);",
4901             $sv_ix, $proto, $cur));
4902 0         0 } else {
4903             $init->add( sprintf("SvPVX(&sv_list[%d]) = %s;",
4904             $sv_ix, $proto));
4905             }
4906 0 0       0 }
4907 0         0 $cv->OUTSIDE->save if $xcv_outside;
4908             return $sym;
4909             }
4910              
4911             package B::C;
4912 0     0   0 my @_v = Internals::V() if $] >= 5.011;
4913             sub __ANON__::_V { @_v };
4914              
4915 0     0   0 sub B::GV::save {
4916 0         0 my ($gv, $filter) = @_;
4917 0 0       0 my $sym = objsym($gv);
4918 0 0       0 if ( defined($sym) ) {
4919 0         0 warn sprintf( "GV 0x%x already saved as $sym\n", $$gv ) if $debug{gv};
4920             return $sym;
4921             }
4922 0         0 else {
4923 0         0 my $ix = $gv_index++;
4924 0 0       0 $sym = savesym( $gv, "gv_list[$ix]" );
4925             warn sprintf( "Saving GV 0x%x as $sym\n", $$gv ) if $debug{gv};
4926             }
4927             warn sprintf( " GV *%s $sym type=%d, flags=0x%x %s\n", $gv->NAME,
4928 0 0 0     0 # B::SV::SvTYPE not with 5.6
4929 0 0 0     0 B::SV::SvTYPE($gv), $gv->FLAGS) if $debug{gv} and !$PERL56;
      0        
4930 0 0       0 if ($PERL510 and !$PERL5257 and $gv->FLAGS & 0x40000000) { # SVpbm_VALID
4931 0         0 warn sprintf( " GV $sym isa FBM\n") if $debug{gv};
4932             return B::BM::save($gv);
4933             }
4934             # since 5.25.7 VALID is just a B magic at a gv->SV->PVMG. See below.
4935 0         0  
4936 0         0 my $gvname = $gv->NAME;
4937 0 0       0 my $package;
4938 0         0 if (ref($gv->STASH) eq 'B::SPECIAL') {
4939 0 0       0 $package = '__ANON__';
4940             warn sprintf( "GV STASH = SPECIAL $gvname\n") if $debug{gv};
4941 0         0 } else {
4942             $package = $gv->STASH->NAME;
4943 0 0       0 }
4944             return q/(SV*)&PL_sv_undef/ if skip_pkg($package);
4945 0         0  
4946 0         0 my $fullname = $package . "::" . $gvname;
4947             my $fancyname;
4948             sub Save_HV() { 1 }
4949             sub Save_AV() { 2 }
4950             sub Save_SV() { 4 }
4951             sub Save_CV() { 8 }
4952             sub Save_FORM() { 16 }
4953             sub Save_IO() { 32 }
4954 0 0 0     0 sub Save_ALL() { 63 }
4955 0         0 if ( $filter and $filter =~ m/ :pad/ ) {
4956 0         0 $fancyname = cstring($filter);
4957             $filter = 0;
4958 0         0 } else {
4959             $fancyname = cstring($fullname);
4960             }
4961 0 0 0     0 # checked for defined'ness in Carp. So the GV must exist, the CV not
4962 0         0 if ($fullname =~ /^threads::(tid|AUTOLOAD)$/ and !$ITHREADS) {
4963             $filter = Save_CV;
4964             }
4965 0 0 0     0 # no need to assign any SV/AV/HV to them (172)
4966             if ($PERL518 and $fullname =~ /^DynaLoader::dl_(
4967             require_symbols|
4968             modules|
4969             shared_objects|
4970             resolve_using|
4971             librefs)/x)
4972 0         0 {
4973             $filter = Save_SV + Save_AV + Save_HV;
4974             }
4975             # skip static %Encode::Encoding since 5.20. GH #200.
4976             # Let it be initialized by boot_Encode/Encode_XSEncoding
4977             #if ($] >= 5.020 and $fullname eq 'Encode::Encoding') {
4978             # warn "skip %Encode::Encoding - XS initialized\n" if $debug{gv};
4979             # $filter = Save_HV;
4980             #}
4981 0         0  
4982 0 0 0     0 my $is_empty = $gv->is_empty;
4983 0         0 if (!defined $gvname and $is_empty) { # 5.8 curpad name
4984             return q/(SV*)&PL_sv_undef/;
4985 0 0       0 }
4986 0         0 my $name = $package eq 'main' ? $gvname : $fullname;
4987 0 0 0     0 my $cname = cstring($name);
4988 0 0       0 my $notqual = ($] >= 5.008009 and $package eq 'main') ? 'GV_NOTQUAL' : '0';
4989 0         0 warn " GV name is $fancyname\n" if $debug{gv};
4990 0         0 my $egvsym;
4991             my $is_special = ref($gv) eq 'B::SPECIAL';
4992              
4993             # If we come across a stash, we therefore have code using this symbol.
4994             # But this does not mean that we need to save the package then.
4995             # if (defined %Exporter::) should not import Exporter, it should return undef.
4996             #if ( $gvname =~ m/::$/ ) {
4997             # my $package = $gvname;
4998             # $package =~ s/::$//;
4999             # mark_package($package); #wrong
5000 0 0       0 #}
5001 0         0 if ($fullname =~ /^(bytes|utf8)::AUTOLOAD$/) {
5002 0         0 $gv = force_heavy($package); # defer to run-time autoload, or compile it in?
5003             $sym = savesym( $gv, $sym ); # override new gv ptr to sym
5004 0 0       0 }
5005 0         0 if ( !$is_empty ) {
5006 0 0 0     0 my $egv = $gv->EGV;
5007 0         0 unless (ref($egv) eq 'B::SPECIAL' or ref($egv->STASH) eq 'B::SPECIAL') {
5008 0 0       0 my $estash = $egv->STASH->NAME;
5009             if ( $$gv != $$egv ) {
5010             warn(sprintf( "EGV name is %s, saving it now\n",
5011 0 0       0 $estash . "::" . $egv->NAME )
5012 0         0 ) if $debug{gv};
5013             $egvsym = $egv->save;
5014             }
5015             }
5016             }
5017             #if ($fullname eq 'threads::tid' and !$ITHREADS) { # checked for defined'ness in Carp
5018             # $init->add(qq[$sym = (GV*)&PL_sv_undef;]);
5019             # return $sym;
5020 0 0 0     0 #}
5021 0         0 if ($fullname =~ /^main::STDOUT$/i and $PERL56) {
5022             return 'Nullgv'; # perl.c: setdefout(Nullgv)
5023 0         0 }
5024             my $core_syms = {ENV => 'PL_envgv',
5025             ARGV => 'PL_argvgv',
5026             INC => 'PL_incgv',
5027             STDIN => 'PL_stdingv',
5028             STDERR => 'PL_stderrgv',
5029             "\010" => 'PL_hintgv', # ^H
5030             "_" => 'PL_defgv',
5031             "@" => 'PL_errgv',
5032             "\022" => 'PL_replgv', # ^R
5033 0         0 };
5034             my $is_coresym;
5035             # those are already initialized in init_predump_symbols()
5036 0         0 # and init_main_stash()
5037 0 0       0 for my $s (sort keys %$core_syms) {
5038 0         0 if ($fullname eq 'main::'.$s) {
5039             $sym = savesym( $gv, $core_syms->{$s} );
5040             # $init->add( sprintf( "SvREFCNT($sym) = $u32fmt;", $gv->REFCNT ) );
5041 0         0 # return $sym;
5042             $is_coresym++;
5043             }
5044 0 0 0     0 }
    0          
    0          
5045 0         0 if ($fullname =~ /^main::std(in|out|err)$/) { # same as uppercase above
5046 0         0 $init->add(qq[$sym = gv_fetchpv($cname, $notqual, SVt_PVGV);]);
5047 0         0 $init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) );
5048             return $sym;
5049             }
5050             elsif ($fullname eq 'main::0') { # dollar_0 already handled before, so don't overwrite it
5051             # only the $0 part, not @0 &0 ...
5052             #$init->add(qq[$sym = gv_fetchpv($cname, $notqual, SVt_PV);]);
5053 0         0 #$init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) );
5054             $filter = Save_SV;
5055             #return $sym;
5056             }
5057 0         0 elsif ($B::C::ro_inc and $fullname =~ /^main::([0-9])$/) { # ignore PV regexp captures with -O2
5058             $filter = Save_SV;
5059             }
5060             # gv_fetchpv loads Errno resp. Tie::Hash::NamedCapture, but needs *INC #90
5061             #elsif ( $fullname eq 'main::!' or $fullname eq 'main::+' or $fullname eq 'main::-') {
5062             # $init1->add(qq[$sym = gv_fetchpv($name, TRUE, SVt_PVGV);]); # defer until INC is setup
5063             # $init1->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) );
5064             # return $sym;
5065 0         0 #}
5066 0         0 my $svflags = $gv->FLAGS;
5067             my $savefields = 0;
5068 0         0  
5069 0 0       0 my $gp;
5070 0 0 0     0 my $gvadd = $notqual ? "$notqual|GV_ADD" : "GV_ADD";
    0 0        
5071 0         0 if ( $PERL510 and $gv->isGV_with_GP and !$is_coresym) {
5072             $gp = $gv->GP; # B limitation
5073 0 0 0     0 # warn "XXX EGV='$egvsym' for IMPORTED_HV" if $gv->GvFLAGS & 0x40;
    0 0        
    0 0        
    0 0        
      0        
5074             if ( defined($egvsym) && $egvsym !~ m/Null/ ) {
5075             warn(sprintf("Shared GV alias for *$fullname 0x%x%s %s to $egvsym\n",
5076 0 0       0 $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
    0          
5077             )) if $debug{gv};
5078 0 0       0 # Shared glob *foo = *bar
5079             $init->add("$sym = ".gv_fetchpvn($package eq 'main' ? $gvname : $fullname,
5080 0         0 "$gvadd|GV_ADDMULTI", "SVt_PVGV").";");
5081 0         0 $init->add( "GvGP_set($sym, GvGP($egvsym));" );
5082             $is_empty = 1;
5083             }
5084             elsif ( $gp and exists $gptable{0+$gp} ) {
5085             warn(sprintf("Shared GvGP for *$fullname 0x%x%s %s GP:0x%x\n",
5086             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5087 0 0       0 $gv->FILE, $gp
    0          
5088 0         0 )) if $debug{gv};
5089 0         0 $init->add("$sym = ".gv_fetchpvn($name, $notqual, "SVt_PVGV").";");
5090 0         0 $init->add( sprintf("GvGP_set(%s, %s);", $sym, $gptable{0+$gp}) );
5091             $is_empty = 1;
5092             }
5093             elsif ( $gp and !$is_empty and $gvname =~ /::$/) {
5094             warn(sprintf("Shared GvGP for stash %$fullname 0x%x%s %s GP:0x%x\n",
5095             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5096 0 0       0 $gv->FILE, $gp
    0          
5097 0         0 )) if $debug{gv};
5098 0 0       0 $init->add("$sym = ".gv_fetchpvn($name, "GV_ADD", "SVt_PVHV").";");
5099             $gptable{0+$gp} = "GvGP($sym)" if 0+$gp;
5100             }
5101             elsif ( $gp and !$is_empty ) {
5102             warn(sprintf("New GV for *$fullname 0x%x%s %s GP:0x%x\n",
5103             $svflags, $debug{flags} ? "(".$gv->flagspv.")" : "",
5104 0 0       0 $gv->FILE, $gp
    0          
5105             )) if $debug{gv};
5106 0         0 # XXX !PERL510 and OPf_COP_TEMP we need to fake PL_curcop for gp_file hackery
5107 0         0 $init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PV").";");
5108 0         0 $savefields = Save_ALL;
5109             $gptable{0+$gp} = "GvGP($sym)";
5110             }
5111 0         0 else {
5112             $init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PVGV").";");
5113             }
5114 0         0 } elsif (!$is_coresym) {
5115             $init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PV").";");
5116 0         0 }
5117 0 0 0     0 my $gvflags = $gv->GvFLAGS;
5118 0         0 if ($gvflags > 256 and !$PERL510) { # $gv->GvFLAGS as U8 single byte only
5119             $gvflags = $gvflags & 255;
5120             }
5121             $init->add( sprintf( "SvFLAGS(%s) = 0x%x;%s", $sym, $svflags,
5122             $debug{flags}?" /* ".$gv->flagspv." */":"" ),
5123 0 0       0 sprintf( "GvFLAGS(%s) = 0x%x; %s", $sym, $gvflags,
    0          
5124 0 0       0 $debug{flags}?"/* ".$gv->flagspv(SVt_PVGV)." */":"" ));
    0          
5125             $init->add( sprintf( "GvLINE(%s) = %d;", $sym,
5126             ($gv->LINE > 2147483647 # S32 INT_MAX
5127             ? 4294967294 - $gv->LINE
5128             : $gv->LINE )))
5129             unless $is_empty;
5130              
5131             # XXX hack for when Perl accesses PVX of GVs, only if SvPOK
5132             #if (!($svflags && 0x400)) { # defer to run-time (0x400 -> SvPOK) for convenience
5133 0 0       0 # XXX also empty "main::" destruction accesses a PVX, so do not check if_empty
5134 0         0 if ( !$PERL510 ) {
5135             $init->add("if (SvPOK($sym) && !SvPVX($sym)) SvPVX($sym) = (char*)emptystring;");
5136             }
5137              
5138 0 0       0 # walksymtable creates an extra reference to the GV (#197)
5139 0         0 if ( $gv->REFCNT > 1 ) {
5140             $init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT) );
5141 0 0       0 }
5142             return $sym if $is_empty;
5143 0         0  
5144 0 0       0 my $gvrefcnt = $gv->GvREFCNT;
5145 0         0 if ( $gvrefcnt > 1 ) {
5146             $init->add( sprintf( "GvREFCNT(%s) += $u32fmt;", $sym, $gvrefcnt - 1) );
5147             }
5148 0 0       0  
5149             warn "check which savefields for \"$gvname\"\n" if $debug{gv};
5150             # some non-alphabetic globs require some parts to be saved
5151 0 0 0     0 # ( ex. %!, but not $! )
    0          
    0          
    0          
    0          
5152 0         0 if ( $gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/ ) {
5153             $savefields = Save_HV | Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO;
5154             }
5155 0         0 elsif ( $fullname eq 'main::!' ) { #Errno
5156             $savefields = Save_HV | Save_SV | Save_CV;
5157             }
5158 0         0 elsif ( $fullname eq 'main::ENV' or $fullname eq 'main::SIG' ) {
5159             $savefields = Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO;
5160             }
5161 0         0 elsif ( $fullname eq 'main::ARGV' ) {
5162             $savefields = Save_HV | Save_SV | Save_CV | Save_FORM | Save_IO;
5163             }
5164 0         0 elsif ( $fullname =~ /^main::STD(IN|OUT|ERR)$/ ) {
5165             $savefields = Save_FORM | Save_IO;
5166 0 0 0     0 }
      0        
      0        
      0        
5167             $savefields &= ~$filter if ($filter and $filter !~ m/ :pad/
5168             and $filter =~ m/^\d+$/ and $filter > 0 and $filter < 64);
5169             # issue 79: Only save stashes for stashes.
5170             # But not other values to avoid recursion into unneeded territory.
5171 0 0 0     0 # We walk via savecv, not via stashes.
5172 0         0 if (ref($gv) eq 'B::STASHGV' and $gvname !~ /::$/) {
5173             return $sym;
5174             }
5175              
5176             # attributes::bootstrap is created in perl_parse.
5177             # Saving it would overwrite it, because perl_init() is
5178 0 0       0 # called after perl_parse(). But we need to xsload it.
5179 0 0       0 if ($fullname eq 'attributes::bootstrap') {
  0         0  
5180 0 0       0 unless ( defined( &{ $package . '::bootstrap' } ) ) {
5181 0         0 warn "Forcing bootstrap of $package\n" if $verbose;
  0         0  
5182             eval { $package->bootstrap };
5183 0         0 }
5184 0 0       0 mark_package('attributes', 1);
5185 0         0 if ($] >= 5.011) {
5186 0         0 $savefields &= ~Save_CV;
5187 0         0 $xsub{attributes} = 'Dynamic-'. $INC{'attributes.pm'}; # XSLoader
5188             $use_xsloader = 1;
5189 0         0 } else {
5190             $xsub{attributes} = 'Static';
5191             }
5192             }
5193              
5194 0 0 0     0 # avoid overly dynamic POSIX redefinition warnings: GH #335, #345
5195 0         0 if ($PERL522 and $fullname =~ /^POSIX::M/) {
5196             $savefields &= ~Save_CV;
5197 0         0 }
5198 0 0       0 my $gvsv;
5199             if ($savefields) {
5200 0 0       0 # Don't save subfields of special GVs (*_, *1, *# and so on)
5201 0         0 warn "GV::save saving subfields $savefields\n" if $debug{gv};
5202 0 0 0     0 $gvsv = $gv->SV;
5203 0 0       0 if ( $$gvsv && $savefields & Save_SV ) {
5204 0         0 warn "GV::save \$".$sym." $gvsv\n" if $debug{gv};
5205             my $core_svs = { # special SV syms to assign to the right GvSV
5206             "\\" => 'PL_ors_sv',
5207             "/" => 'PL_rs',
5208             "@" => 'PL_errors',
5209 0         0 };
5210 0 0       0 for my $s (sort keys %$core_svs) {
5211 0         0 if ($fullname eq 'main::'.$s) {
5212             savesym( $gvsv, $core_svs->{$s} ); # TODO: This could bypass BEGIN settings (->save is ignored)
5213             }
5214 0 0 0     0 }
5215 0         0 if ($PERL5257 and $gvsv->MAGICAL) {
5216 0         0 my @magic = $gvsv->MAGIC;
5217 0 0       0 foreach my $mg (@magic) {
5218 0 0       0 if ($mg->TYPE eq 'B') {
5219 0         0 warn sprintf( " GvSV $sym isa FBM\n") if $debug{gv};
5220             savesym($gvsv, B::BM::save($gvsv));
5221             }
5222             }
5223 0 0 0     0 }
      0        
      0        
5224 0 0       0 if ($gvname eq 'VERSION' and $xsub{$package} and $gvsv->FLAGS & SVf_ROK and !$PERL56) {
5225 0         0 warn "Strip overload from $package\::VERSION, fails to xs boot (issue 91)\n" if $debug{gv};
5226 0         0 my $rv = $gvsv->object_2svref();
5227 55     55   848 my $origsv = $$rv;
  55         154  
  55         44518  
5228 0         0 no strict 'refs';
  0         0  
5229 0         0 ${$fullname} = "$origsv";
  0         0  
5230 0         0 svref_2object(\${$fullname})->save($fullname);
5231             $init->add( sprintf( "GvSVn(%s) = (SV*)s\\_%x;", $sym, $$gvsv ) );
5232 0         0 } else {
5233             $gvsv->save($fullname); #even NULL save it, because of gp_free nonsense
5234 0 0       0 # we need sv magic for the core_svs (PL_rs -> gv) (#314)
5235 0 0       0 if (exists $core_svs->{$gvname}) {
5236 0         0 if ($gvname eq "\\") { # ORS special case #318 (initially NULL)
5237             return $sym;
5238 0 0       0 } else {
5239 0         0 $gvsv->save_magic($fullname) if ref($gvsv) eq 'B::PVMG';
5240             $init->add( sprintf( "SvREFCNT(s\\_%x) += 1;", $$gvsv ) );
5241             }
5242 0         0 }
5243             $init->add( sprintf( "GvSVn(%s) = (SV*)s\\_%x;", $sym, $$gvsv ) );
5244 0 0       0 }
5245 0 0       0 if ($fullname eq 'main::$') { # $$ = PerlProc_getpid() issue #108
5246 0         0 warn sprintf( " GV $sym \$\$ perlpid\n") if $debug{gv};
5247             $init->add( "sv_setiv(GvSV($sym), (IV)PerlProc_getpid());" );
5248 0 0       0 }
5249             warn "GV::save \$$fullname\n" if $debug{gv};
5250 0         0 }
5251 0 0 0     0 my $gvav = $gv->AV;
5252 0 0       0 if ( $$gvav && $savefields & Save_AV ) {
5253 0         0 warn "GV::save \@$fullname\n" if $debug{gv};
5254 0         0 $gvav->save($fullname);
5255 0 0       0 $init->add( sprintf( "GvAV(%s) = s\\_%x;", $sym, $$gvav ) );
5256 0         0 if ($fullname eq 'main::-') {
5257             $init->add( sprintf("AvFILLp(s\\_%x) = -1;", $$gvav),
5258             sprintf("AvMAX(s\\_%x) = -1;", $$gvav));
5259             }
5260 0         0 }
5261 0 0 0     0 my $gvhv = $gv->HV;
5262 0 0       0 if ( $$gvhv && $savefields & Save_HV ) {
5263 0 0       0 if ($fullname ne 'main::ENV') {
5264 0 0 0     0 warn "GV::save \%$fullname\n" if $debug{gv};
    0          
5265 0         0 if ($fullname eq 'main::!') { # force loading Errno
5266 0         0 $init->add("/* \%! force saving of Errno */");
5267 0         0 mark_package('Config', 1); # Errno needs Config to set the EGV
5268 0         0 walk_syms('Config');
5269             mark_package('Errno', 1); # B::C needs Errno but does not import $!
5270 0         0 } elsif ($fullname eq 'main::+' or $fullname eq 'main::-') {
5271 0 0       0 $init->add("/* \%$gvname force saving of Tie::Hash::NamedCapture */");
5272 0         0 if ($PERL514) {
5273 0         0 mark_package('Config', 1); # DynaLoader needs Config to set the EGV
5274 0         0 walk_syms('Config');
  0         0  
5275             svref_2object(\&{'Tie::Hash::NamedCapture::bootstrap'})->save;
5276 0         0 }
5277             mark_package('Tie::Hash::NamedCapture', 1);
5278             }
5279             # skip static %Encode::Encoding since 5.20. GH #200. sv_upgrade cannot upgrade itself.
5280             # Let it be initialized by boot_Encode/Encode_XSEncodingm with exceptions.
5281 0 0 0     0 # GH #200 and t/testc.sh 75
    0          
5282 0 0       0 if ($] >= 5.020 and $fullname eq 'Encode::Encoding') {
5283 0         0 warn "skip some %Encode::Encoding - XS initialized\n" if $debug{gv};
5284 0         0 my %tmp_Encode_Encoding = %Encode::Encoding;
5285 0         0 %Encode::Encoding = (); # but we need some non-XS encoding keys
5286 0 0       0 for my $k (qw(utf8 utf-8-strict Unicode Internal Guess)) {
5287             $Encode::Encoding{$k} = $tmp_Encode_Encoding{$k} if exists $tmp_Encode_Encoding{$k};
5288 0         0 }
5289 0         0 $gvhv->save($fullname);
5290             $init->add( "/* deferred some XS enc pointers for \%Encode::Encoding */",
5291 0         0 sprintf("GvHV(%s) = s\\_%x;", $sym, $$gvhv ) );
5292             %Encode::Encoding = %tmp_Encode_Encoding;
5293             }
5294             # XXX TODO 49: crash at BEGIN { %warnings::Bits = ... }
5295 0         0 elsif ($fullname ne 'main::INC') {
5296 0         0 $gvhv->save($fullname);
5297             $init->add( sprintf( "GvHV(%s) = s\\_%x;", $sym, $$gvhv ) );
5298             }
5299             }
5300 0         0 }
5301 0 0 0     0 my $gvcv = $gv->CV;
5302 0 0       0 if ( !$$gvcv and $savefields & Save_CV ) {
5303 55     55   465 warn "Empty CV $fullname, AUTOLOAD and try again\n" if $debug{gv};
  55         154  
  55         16015  
5304             no strict 'refs';
5305             # Fix test 31, catch unreferenced AUTOLOAD. The downside:
5306             # It stores the whole optree and all its children.
5307 0         0 # Similar with test 39: re::is_regexp
5308 0 0 0     0 svref_2object( \*{"$package\::AUTOLOAD"} )->save
  0         0  
5309 0         0 if $package and exists ${"$package\::"}{AUTOLOAD};
5310 0 0 0     0 svref_2object( \*{"$package\::CLONE"} )->save
  0         0  
5311 0         0 if $package and exists ${"$package\::"}{CLONE};
5312             $gvcv = $gv->CV; # try again
5313             }
5314 0 0 0     0 # This will autovivify the CvGV of a named CV
      0        
      0        
      0        
5315             if ( $$gvcv and $savefields & Save_CV
5316             and ref($gvcv) eq 'B::CV'
5317             #and !is_named($gvcv)
5318             and ref($gvcv->GV->EGV) ne 'B::SPECIAL'
5319             and !skip_pkg($package) )
5320 0         0 {
5321 0         0 my $package = $gvcv->GV->EGV->STASH->NAME;
5322 0         0 my $oname = $gvcv->GV->EGV->NAME;
5323 0         0 my $origname = $package . "::" . $oname;
5324 0 0 0     0 my $cvsym;
    0 0        
      0        
5325             if ( $gvcv->XSUB and $oname ne '__ANON__' and $fullname ne $origname ) { #XSUB CONSTSUB alias
5326 0 0       0 warn "Boot $package, XS CONSTSUB alias of $fullname to $origname\n"
5327 0         0 if $debug{pkg};
5328             mark_package($package, 1);
5329 55     55   438 {
  55         155  
  55         96117  
  0         0  
5330 0         0 no strict 'refs';
5331 0 0 0     0 svref_2object( \&{"$package\::bootstrap"} )->save
  0         0  
5332             if $package and defined &{"$package\::bootstrap"};
5333             }
5334 0         0 # XXX issue 57: incomplete xs dependency detection
5335             my %hack_xs_detect =
5336             ('Scalar::Util' => 'List::Util',
5337             'Sub::Exporter' => 'Params::Util',
5338 0 0       0 );
5339 0         0 if (my $dep = $hack_xs_detect{$package}) {
  0         0  
5340             svref_2object( \&{"$dep\::bootstrap"} )->save;
5341             }
5342 0 0       0 # must save as a 'stub' so newXS() has a CV to populate
5343 0         0 warn "save stub CvGV for $sym GP assignments $origname\n" if $debug{gv};
5344             $init2->add(
5345             sprintf("if ((sv = (SV*)%s))", get_cv($origname, "GV_ADD")),
5346             sprintf(" GvCV_set(%s, (CV*)SvREFCNT_inc_simple_NN(sv));", $sym));
5347             # TODO: add evtl. to SvRV also.
5348             }
5349 0 0       0 elsif (!$PERL510 or $gp) {
5350 0         0 if ($fullname eq 'Internals::V') { # local_patches if $] >= 5.011
5351             $gvcv = svref_2object( \&__ANON__::_V );
5352             }
5353             # TODO: may need fix CvGEN if >0 to re-validate the CV methods
5354 0 0       0 # on PERL510 (>0 +
5355 0         0 warn "GV::save &$fullname...\n" if $debug{gv};
5356             $cvsym = $gvcv->save($fullname);
5357 0 0       0 # backpatch "$sym = gv_fetchpv($name, GV_ADD, SVt_PV)" to SVt_PVCV
    0          
5358 0 0 0     0 if ($cvsym =~ /get_cv/) {
    0          
5359 0         0 if (!$xsub{$package} and in_static_core($package, $gvname)) {
5360 0         0 my $in_gv;
  0         0  
5361 0 0       0 for (@{ $init->[-1]{current} }) {
5362 0         0 if ($in_gv) {
5363 0         0 s/^.*\Q$sym\E.*=.*;//;
5364             s/GvGP_set\(\Q$sym\E.*;//;
5365 0         0 }
5366 0         0 my $gv_get = gv_fetchpvn($name, "GV_ADD", "SVt_PV");
5367 0 0       0 my $new_gv_get = gv_fetchpvn($name, "GV_ADD", "SVt_PVCV");
5368 0         0 if (/^\Q$sym = $gv_get;\E/) {
5369 0         0 s/^\Q$sym = $gv_get;\E/$sym = $new_gv_get;/;
5370 0 0       0 $in_gv++;
5371             warn "removed $sym GP assignments $origname (core CV)\n" if $debug{gv};
5372             }
5373 0         0 }
5374             $init->add( sprintf( "GvCV_set(%s, (CV*)SvREFCNT_inc(%s));", $sym, $cvsym ));
5375             }
5376             elsif ($xsub{$package}) {
5377 0 0       0 # must save as a 'stub' so newXS() has a CV to populate later in dl_init()
5378 0 0       0 warn "save stub CvGV for $sym GP assignments $origname (XS CV)\n" if $debug{gv};
5379 0         0 my $get_cv = get_cv($oname ne "__ANON__" ? $origname : $fullname, "GV_ADD");
5380             $init2->add(sprintf("if ((sv = (SV*)%s))", $get_cv),
5381             sprintf(" GvCV_set(%s, (CV*)SvREFCNT_inc_simple_NN(sv));", $sym));
5382             }
5383 0         0 else {
5384             $init->add( sprintf( "GvCV_set(%s, (CV*)(%s));", $sym, $cvsym ));
5385 0 0       0 }
5386             if ($gvcv->XSUBANY) {
5387 0         0 # some XSUB's set this field. but which part?
5388 0 0       0 my $xsubany = $gvcv->XSUBANY;
    0          
5389             if ($package =~ /^DBI::(common|db|dr|st)/) {
5390             # DBI uses the any_ptr for dbi_ima_t *ima, and all dr,st,db,fd,xx handles
5391             # for which several ptrs need to be patched. #359
5392 0         0 # the ima is internal only
5393             my $dr = $1;
5394 0 0 0     0 warn sprintf("eval_pv: DBI->_install_method(%s-) (XSUBANY=0x%x)\n",
5395 0         0 $fullname, $xsubany) if $verbose and $debug{cv};
5396             $init2->add_eval(sprintf("DBI->_install_method('%s', 'DBI.pm', \$DBI::DBI_methods{%s}{%s})",
5397             $fullname, $dr, $fullname));
5398             } elsif ($package eq 'Tie::Hash::NamedCapture') {
5399             # pretty high _ALIAS CvXSUBANY.any_i32 values
5400             } else {
5401 0         0 # try if it points to an already registered symbol
5402 0 0 0     0 my $anyptr = $symtable{ sprintf( "s\\_%x", $xsubany ) };
    0 0        
    0 0        
5403 0         0 if ($anyptr and $xsubany > 1000) { # not a XsubAliases
5404             $init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_ptr = &%s;", $sym, $anyptr ));
5405             } # some heuristics TODO. long or ptr? TODO 32bit
5406             elsif ($xsubany > 0x100000
5407             and ($xsubany < 0xffffff00 or $xsubany > 0xffffffff))
5408 0 0 0     0 {
    0 0        
5409             if ($package eq 'POSIX' and $gvname =~ /^is/) {
5410 0         0 # need valid XSANY.any_dptr
5411             $init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_dptr = (void*)&%s;", $sym, $gvname));
5412             } elsif ($package eq 'List::MoreUtils' and $gvname =~ /_iterator$/) {
5413 0         0 # should be only the 2 iterators
5414             $init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_ptr = (void*)&%s;", $sym,
5415             "XS_List__MoreUtils__".$gvname));
5416 0 0       0 } else {
5417 0         0 warn sprintf("TODO: Skipping %s->XSUBANY = 0x%x\n", $fullname, $xsubany ) if $verbose;
5418             $init2->add( sprintf( "/* TODO CvXSUBANY(GvCV(%s)).any_ptr = 0x%lx; */", $sym, $xsubany ));
5419             }
5420             } elsif ($package eq 'Fcntl') {
5421             # S_ macro values
5422             } else {
5423 0         0 # most likely any_i32 values for the XsubAliases provided by xsubpp
5424             $init2->add( sprintf( "/* CvXSUBANY(GvCV(%s)).any_i32 = 0x%x; XSUB Alias */", $sym, $xsubany ));
5425             }
5426             }
5427             }
5428             }
5429 0         0 elsif ($cvsym =~ /^(cv|&sv_list)/) {
5430             $init->add( sprintf( "GvCV_set(%s, (CV*)(%s));", $sym, $cvsym ));
5431             }
5432 0 0 0     0 else {
5433             warn "wrong CvGV for $sym $origname: $cvsym\n" if $debug{gv} or $verbose;
5434             }
5435             }
5436 0 0 0     0 # special handling for backref magic
      0        
      0        
5437 0         0 if ($PERL514 and $cvsym and $cvsym !~ /(get_cv|NULL|lexwarn)/ and $gv->MAGICAL) {
5438 0         0 my @magic = $gv->MAGIC;
5439 0 0       0 foreach my $mg (@magic) {
5440 0         0 if ($mg->TYPE eq '<') {
5441             $init->add( "sv_magic((SV*)$sym, (SV*)$cvsym, '<', 0, 0);",
5442 0 0       0 "CvCVGV_RC_off($cvsym);");
5443 0         0 if (!($mg->FLAGS & 2)) {
5444             mg_RC_off($mg, $sym, '<'); # 390
5445             }
5446             }
5447             }
5448             }
5449 0 0 0     0 }
5450 0 0       0 if (!$PERL510 or $gp) {
5451             if ( $] > 5.009 ) {
5452             # TODO implement heksect to place all heks at the beginning
5453             #$heksect->add($gv->FILE);
5454             #$init->add(sprintf("GvFILE_HEK($sym) = hek_list[%d];", $heksect->index));
5455              
5456 0 0 0     0 # XXX Maybe better leave it NULL or asis, than fighting broken
5457             if ($B::C::stash and $fullname =~ /::$/) {
5458             # ignore stash hek asserts when adding the stash
5459             # he->shared_he_he.hent_hek == hek assertions (#46 with IO::Poll::)
5460 0         0 } else {
5461 0 0 0     0 my $file = save_hek($gv->FILE,$fullname,1);
5462             $init->add(sprintf("GvFILE_HEK(%s) = %s;", $sym, $file))
5463             if $file ne 'NULL' and !$optimize_cop;
5464             }
5465             # $init->add(sprintf("GvNAME_HEK($sym) = %s;", save_hek($gv->NAME))) if $gv->NAME;
5466             } else {
5467             # XXX ifdef USE_ITHREADS and PL_curcop->op_flags & OPf_COP_TEMP
5468 0 0       0 # GvFILE is at gp+1
5469             $init->add( sprintf( "GvFILE(%s) = %s;", $sym, cstring( $gv->FILE ) ))
5470             unless $optimize_cop;
5471 0 0 0     0 warn "GV::save GvFILE(*$fullname) " . cstring( $gv->FILE ) . "\n"
5472             if $debug{gv} and !$ITHREADS;
5473 0         0 }
5474 0 0 0     0 my $gvform = $gv->FORM;
5475 0 0       0 if ( $$gvform && $savefields & Save_FORM ) {
5476 0         0 warn "GV::save GvFORM(*$fullname) ...\n" if $debug{gv};
5477 0         0 $gvform->save($fullname);
5478             $init->add( sprintf( "GvFORM(%s) = (CV*)s\\_%x;", $sym, $$gvform ));
5479 0 0       0 # glob_assign_glob analog to CV
5480 0 0       0 $init->add( sprintf( "SvREFCNT_inc(s\\_%x);", $$gvform )) if $PERL510;
5481             warn "GV::save GvFORM(*$fullname) done\n" if $debug{gv};
5482 0         0 }
5483 0 0 0     0 my $gvio = $gv->IO;
5484 0 0       0 if ( $$gvio && $savefields & Save_IO ) {
5485 0 0 0     0 warn "GV::save GvIO(*$fullname)...\n" if $debug{gv};
    0 0        
      0        
5486             if ( $fullname =~ m/::DATA$/ &&
5487             ( $fullname eq 'main::DATA' or $B::C::save_data_fh) ) # -O2 or 5.8
5488 55     55   562 {
  55         206  
  55         3312  
5489 0         0 no strict 'refs';
  0         0  
5490 55     55   379 my $fh = *{$fullname}{IO};
  55         147  
  55         745676  
5491 0 0       0 use strict 'refs';
5492 0         0 warn "GV::save_data $sym, $fullname ...\n" if $debug{gv};
5493 0         0 $gvio->save($fullname, 'is_DATA');
5494 0 0       0 $init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) );
5495             $gvio->save_data( $sym, $fullname, <$fh> ) if $fh->opened;
5496 0         0 } elsif ( $fullname =~ m/::DATA$/ && !$B::C::save_data_fh ) {
5497 0         0 $gvio->save($fullname, 'is_DATA');
5498 0         0 $init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) );
5499             warn "Warning: __DATA__ handle $fullname not stored. Need -O2 or -fsave-data.\n";
5500 0         0 } else {
5501 0         0 $gvio->save($fullname);
5502             $init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) );
5503 0 0       0 }
5504             warn "GV::save GvIO(*$fullname) done\n" if $debug{gv};
5505 0         0 }
5506             $init->add("");
5507             }
5508             }
5509             # Shouldn't need to do save_magic since gv_fetchpv handles that. Esp. < and IO not
5510 0 0       0 # $gv->save_magic($fullname) if $PERL510;
5511 0         0 warn "GV::save *$fullname done\n" if $debug{gv};
5512             return $sym;
5513             }
5514              
5515 0     0   0 sub B::AV::save {
5516 0         0 my ($av, $fullname, $cv) = @_;
5517 0 0       0 my $sym = objsym($av);
5518             return $sym if defined $sym;
5519 0 0       0  
5520 0         0 $fullname = '' unless $fullname;
5521 0         0 my ($fill, $avreal, $max, $static_av, $av_cow, $av_cog);
5522 0         0 my $ispadlist = ref($av) eq 'B::PADLIST';
5523 0 0 0     0 my $ispadnamelist = ref($av) eq 'B::PADNAMELIST';
5524 0         0 if ($ispadnamelist or $ispadlist) {
5525             $fill = $av->MAX;
5526             } else {
5527 0         0 # cornercase: tied array without FETCHSIZE
  0         0  
5528 0 0       0 eval { $fill = $av->FILL; };
5529             $fill = -1 if $@; # catch error in tie magic
5530 0         0 }
5531 0 0       0 $max = $fill;
5532 0 0       0 my $svpcast = $ispadlist ? "(PAD*)" : "(SV*)";
5533             $svpcast = "(PADNAME*)" if $ispadnamelist;
5534 0 0 0     0  
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
      0        
      0        
5535 0         0 if ($PERL522 and $ispadnamelist) {
5536             $padnlsect->comment("xpadnl_fill, xpadnl_alloc, xpadnl_max, xpadnl_max_named, xpadnl_refcnt");
5537 0         0 # TODO: max_named walk all names and look for non-empty names
5538 0         0 my $refcnt = $av->REFCNT + 1; # XXX defer free to global destruction: 28
5539 0         0 my $maxnamed = $av->MAXNAMED;
5540 0         0 $padnlsect->add("$fill, NULL, $fill, $maxnamed, $refcnt /* +1 */");
5541 0         0 $padnl_index = $padnlsect->index;
5542 0         0 $sym = savesym( $av, "&padnamelist_list[$padnl_index]" );
5543             push @B::C::static_free, $sym;
5544             }
5545 0         0 elsif ($ispadlist and $] >= 5.021008) { # id+outid as U32 (PL_padlist_generation++)
5546 0         0 $padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_id, xpadl_outid");
5547 0         0 my ($id, $outid) = ($av->id, $av->outid);
5548 0         0 $padlistsect->add("$fill, NULL, $id, $outid");
5549 0         0 $padlist_index = $padlistsect->index;
5550             $sym = savesym( $av, "&padlist_list[$padlist_index]" );
5551             }
5552 0         0 elsif ($ispadlist and $] >= 5.017006 and $] < 5.021008) { # id added again with b4db586814
5553 0         0 $padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_outid");
5554 0         0 $padlistsect->add("$fill, NULL, NULL"); # Perl_pad_new(0)
5555 0         0 $padlist_index = $padlistsect->index;
5556 0 0 0     0 $sym = savesym( $av, "&padlist_list[$padlist_index]" );
      0        
      0        
5557 0         0 if ($cv and $cv->OUTSIDE and ref($cv->OUTSIDE) ne 'B::SPECIAL' and $cv->OUTSIDE->PADLIST) {
5558 0 0       0 my $outid = $cv->OUTSIDE->PADLIST->save();
5559             $init->add("($sym)->xpadl_outid = (PADNAMELIST*)$outid;") if $outid;
5560             }
5561             }
5562 0         0 elsif ($ispadlist and $] >= 5.017004) {
5563 0         0 $padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_id, xpadl_outid");
5564 0         0 $padlistsect->add("$fill, NULL, 0, 0"); # Perl_pad_new(0)
5565 0         0 $padlist_index = $padlistsect->index;
5566 0 0 0     0 $sym = savesym( $av, "&padlist_list[$padlist_index]" );
      0        
      0        
5567 0         0 if ($cv and $cv->OUTSIDE and ref($cv->OUTSIDE) ne 'B::SPECIAL' and $cv->OUTSIDE->PADLIST) {
5568 0 0       0 my $outid = $cv->OUTSIDE->PADLIST->save();
5569             $init->add("($sym)->xpadl_outid = (PADNAMELIST*)$outid;") if $outid;
5570             }
5571             }
5572             # we set it static, not perl. (c)perl only observes it.
5573             # decide if to store the array static (with run-time cow overhead) or dynamic
5574             elsif ($CPERL52 and $B::C::av_init and $fill > -1
5575             and (isAvSTATIC($av) or canAvSTATIC($av, $fullname)))
5576 0         0 {
5577 0         0 $xpvavsect->comment( "stash, magic, fill, max, static alloc" );
5578 0         0 my $alloc = "";
5579 0         0 my $count = 0;
5580             my $flags = $av->FLAGS;
5581 0 0 0     0 # decide upon cow (const array, SVf_READONLY) or just cog (forbid av_extend)
5582 0         0 my $av_cow = ($flags & SVf_READONLY or $fullname =~ /(::ISA|::INC|curpad_name)$/) ? 1 : 0;
5583 0         0 my $magic = ''; # need to skip ->ARRAY with 'D' magic, test 90
5584 0         0 foreach my $mg ($av->MAGIC) {
5585 0 0       0 $magic = $mg->TYPE;
5586 0         0 if ($magic eq 'D') {
5587             last;
5588             }
5589 0 0       0 }
5590 0         0 my @array = $magic eq 'D' ? () : $av->ARRAY;
5591 0 0       0 my $n = scalar @array;
5592 0         0 my $name = ($av_cow ? "avcow_" : "avcog_") . $n;
5593 0 0       0 my $avstaticsect;
5594 0 0       0 if ($av_cow) {
5595 0         0 $avcowsect{ $n } = new B::C::Section($name, \%symtable, 0) unless exists $avcowsect{ $n };
5596             $avstaticsect = $avcowsect{ $n };
5597 0 0       0 } else {
5598 0         0 $avcogsect{ $n } = new B::C::Section($name, \%symtable, 0) unless exists $avcogsect{ $n };
5599             $avstaticsect = $avcogsect{ $n };
5600 0         0 }
5601             my $sect = sprintf("&%s_list[%u]", $name, $avstaticsect->index + 1);
5602 0         0 # protect against duplicates
5603             $sym = savesym( $av, sprintf("(AV*)&sv_list[%u]", $svsect->index + 1));
5604              
5605 0 0       0 # $B::C::const_strings = 0 if $flags & 0x40008000 == 0x40008000; # SVp_SCREAM|SVpbm_VALID
  0         0  
5606 0         0 my @values = map { $_->save($fullname."[".$count++."]") || () } @array;
5607             for (my $i=0; $i <= $#array; $i++) {
5608 0 0       0 # if any value is non-static (GV), fall back to dynamic AV::save
5609 0         0 if (!is_constant($values[$i])) {
5610 0         0 $alloc = '';
5611             last;
5612 0         0 }
5613             $alloc .= $values[$i].", ";
5614 0 0 0     0 }
5615 0         0 if ($alloc and $n) {
5616             $static_av = 1;
5617 0 0       0 warn sprintf("turn on %s %s\n", $av_cow ? "AvIsCOW" : "AvSTATIC", $sym, $fullname)
    0          
5618 0         0 if $debug{av};
5619             $flags |= SVf_IsCOW; # turn on AvSTATIC
5620 0         0 # $flags |= SVf_READONLY if $av_cow; # and turn on COW
5621 0         0 $alloc = substr($alloc,0,-2);
5622 0         0 $avstaticsect->add( $alloc );
5623 0 0       0 $xpvavsect->add("Nullhv, {0}, $fill, $max, (SV**)$sect");
5624             $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}",
5625             $xpvavsect->index, $av->REFCNT, $flags,
5626 0         0 ($C99?".svu_array=(SV**)":"(char*)").$sect));
5627             $sym = savesym( $av, sprintf("(AV*)&sv_list[%u]", $svsect->index));
5628             } else {
5629 0 0       0 warn sprintf("turn off AvSTATIC %s %s\n", $sym, $fullname)
5630 0         0 if $debug{av};
5631 0         0 $flags &= ~SVf_IsCOW; # turn off AvSTATIC
5632 0 0 0     0 my $line = "Nullhv, {0}, -1, -1, 0";
5633 0         0 $line = "Nullhv, {0}, $fill, $max, 0" if $B::C::av_init or $B::C::av_init2;
5634 0         0 $xpvavsect->add($line);
5635             $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {0}",
5636             $xpvavsect->index, $av->REFCNT, $flags));
5637             }
5638             }
5639 0         0 elsif ($PERL514) {
5640             $xpvavsect->comment( "stash, magic, fill, max, alloc" );
5641 0         0 # 5.13.3: STASH, MAGIC, fill max ALLOC
5642 0 0 0     0 my $line = "Nullhv, {0}, -1, -1, 0";
5643 0         0 $line = "Nullhv, {0}, $fill, $max, 0" if $B::C::av_init or $B::C::av_init2;
5644 0         0 $xpvavsect->add($line);
5645             $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}",
5646             $xpvavsect->index, $av->REFCNT, $av->FLAGS,
5647             '0'));
5648             #$avreal = $av->FLAGS & 0x40000000; # SVpav_REAL (unused)
5649             }
5650 0         0 elsif ($PERL510) {
5651             $xpvavsect->comment( "xnv_u, fill, max, xiv_u, magic, stash" );
5652 0         0 # 5.9.4+: nvu fill max iv MG STASH
5653 0 0 0     0 my $line = "{0}, -1, -1, {0}, {0}, Nullhv";
5654 0 0       0 $line = "{0}, $fill, $max, {0}, {0}, Nullhv" if $B::C::av_init or $B::C::av_init2;
5655 0         0 $line = "Nullhv, {0}, $fill, $max, NULL" if $PERL514;
5656 0         0 $xpvavsect->add($line);
5657             $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}",
5658             $xpvavsect->index, $av->REFCNT, $av->FLAGS,
5659             '0'));
5660             #$avreal = $av->FLAGS & 0x40000000; # SVpav_REAL (unused)
5661             }
5662 0         0 else {
5663             $xpvavsect->comment( "array, fill, max, off, nv, magic, stash, alloc, arylen, flags" );
5664 0         0 # 5.8: ARRAY fill max off nv MG STASH ALLOC arylen flags
5665 0 0 0     0 my $line = "0, -1, -1, 0, 0.0, 0, Nullhv, 0, 0";
5666 0 0       0 $line = "0, $fill, $max, 0, 0.0, 0, Nullhv, 0, 0" if $B::C::av_init or $B::C::av_init2;
5667             $line .= sprintf( ", 0x%x", $av->AvFLAGS ) if $] < 5.009;
5668 0         0 #$avreal = $av->AvFLAGS & 1; # AVf_REAL
5669 0         0 $xpvavsect->add($line);
5670             $svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x",
5671             $xpvavsect->index, $av->REFCNT, $av->FLAGS));
5672             }
5673 0         0  
5674 0 0       0 my ($magic, $av_index) = ('');
5675 0 0 0     0 $svsect->debug($fullname, $av->flagspv) if $debug{flags};
5676 0         0 if (!$ispadlist and !$ispadnamelist) {
5677 0         0 my $sv_ix = $svsect->index;
5678             $av_index = $xpvavsect->index;
5679 0         0 # protect against recursive self-references (Getopt::Long)
5680 0         0 $sym = savesym( $av, "(AV*)&sv_list[$sv_ix]" );
5681 0 0 0     0 $magic = $av->save_magic($fullname);
5682             push @B::C::static_free, $sym if $PERL518 and $av->FLAGS & SVs_OBJECT;
5683             }
5684 0 0       0  
5685 0         0 if ( $debug{av} ) {
5686 0 0       0 my $line = sprintf( "saving AV %s 0x%x [%s] FILL=%d", $fullname, $$av, B::class($av), $fill);
5687 0         0 $line .= sprintf( " AvFLAGS=0x%x", $av->AvFLAGS ) if $] < 5.009;
5688             warn "$line\n";
5689             }
5690              
5691 0 0 0     0 # XXX AVf_REAL is wrong test: need to save comppadlist but not stack
      0        
5692 0         0 if ($fill > -1 and $magic !~ /D/ and !$static_av) {
5693 0 0       0 my @array = $av->ARRAY; # crashes with D magic (Getopt::Long)
5694 0         0 if ( $debug{av} ) {
5695 0         0 my $i = 0;
5696 0         0 foreach my $el (@array) {
5697             my $val = '';
5698 0 0       0 # if SvIOK print iv, POK pv
5699 0 0       0 if ($el->can('FLAGS')) {
5700 0 0       0 $val = $el->IVX if $el->FLAGS & SVf_IOK;
5701             $val = cstring($el->PV) if $el->FLAGS & SVf_POK;
5702 0         0 }
5703             warn sprintf( "AV $av \[%d] = %s $val\n", $i++, B::class($el) );
5704             }
5705             }
5706              
5707             # my @names = map($_->save, @array);
5708             # XXX Better ways to write loop?
5709             # Perhaps svp[0] = ...; svp[1] = ...; svp[2] = ...;
5710             # Perhaps I32 i = 0; svp[i++] = ...; svp[i++] = ...; svp[i++] = ...;
5711              
5712             # micro optimization: op/pat.t ( and other code probably )
5713             # has very large pads ( 20k/30k elements ) passing them to
5714             # ->add is a performance bottleneck: passing them as a
5715             # single string cuts runtime from 6min20sec to 40sec
5716              
5717             # you want to keep this out of the no_split/split
5718 0         0 # map("\t*svp++ = (SV*)$_;", @names),
5719             my $acc = '';
5720             # Init optimization by Nick Koston
5721             # The idea is to create loops so there is less C code. In the real world this seems
5722 0         0 # to reduce the memory usage ~ 3% and speed up startup time by about 8%.
5723             my ($count, @values);
5724 0         0 {
  0         0  
5725 0 0 0     0 local $B::C::const_strings = $B::C::const_strings;
5726 0 0       0 if ($PERL510 and !$ispadlist) { # force dynamic PADNAME strings
  0 0       0  
5727 0 0       0 if ($] < 5.016) { $B::C::const_strings = 0 if $av->FLAGS & 0x40000000; } # SVpad_NAME
5728             else { $B::C::const_strings = 0 if ($av->FLAGS & 0x40008000 == 0x40008000); } # SVp_SCREAM|SVpbm_VALID
5729 0 0       0 }
  0         0  
5730             @values = map { $_->save($fullname."[".$count++."]") || () } @array;
5731 0         0 }
5732 0         0 $count = 0;
5733 0 0 0     0 for (my $i=0; $i <= $#array; $i++) {
      0        
5734 0 0       0 if ($fullname =~ m/^(INIT|END)$/ and $values[$i] and ref $array[$i] eq 'B::CV') {
5735 0         0 if ($array[$i]->XSUB) {
5736             $values[$i] =~ s/, 0\)/, GV_ADD\)/; # GvCV filled in later
5737 0         0 }
5738             $values[$i] = sprintf("SvREFCNT_inc(%s);", $values[$i]);
5739 0 0 0     0 }
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
5740             if ( $use_svpop_speedup
5741             && defined $values[$i]
5742             && defined $values[$i+1]
5743             && defined $values[$i+2]
5744             && $values[$i] =~ /^\&sv_list\[(\d+)\]/
5745             && $values[$i+1] eq "&sv_list[" . ($1+1) . "]"
5746             && $values[$i+2] eq "&sv_list[" . ($1+2) . "]" )
5747 0         0 {
5748 0   0     0 $count=0;
5749 0         0 while (defined($values[$i+$count+1]) and $values[$i+$count+1] eq "&sv_list[" . ($1+$count+1) . "]") {
5750             $count++;
5751 0         0 }
5752             $acc .= "\tfor (gcount=" . $1 . "; gcount<" . ($1+$count+1) . "; gcount++) {"
5753 0         0 ." *svp++ = $svpcast&sv_list[gcount]; };\n\t";
5754             $i += $count;
5755             } elsif ($use_av_undef_speedup
5756             && defined $values[$i]
5757             && defined $values[$i+1]
5758             && defined $values[$i+2]
5759             && $values[$i] =~ /^ptr_undef|&PL_sv_undef$/
5760             && $values[$i+1] =~ /^ptr_undef|&PL_sv_undef$/
5761             && $values[$i+2] =~ /^ptr_undef|&PL_sv_undef$/)
5762 0         0 {
5763 0   0     0 $count=0;
5764 0         0 while (defined $values[$i+$count+1] and $values[$i+$count+1] =~ /^ptr_undef|&PL_sv_undef$/) {
5765             $count++;
5766 0         0 }
5767             $acc .= "\tfor (gcount=0; gcount<" . ($count+1) . "; gcount++) {"
5768 0         0 ." *svp++ = $svpcast&PL_sv_undef; };\n\t";
5769             $i += $count;
5770 0 0       0 } else { # XXX 5.8.9d Test::NoWarnings has empty values
5771             $acc .= "\t*svp++ = $svpcast" . ($values[$i] ? $values[$i] : '&PL_sv_undef') . ";\n\t";
5772             }
5773 0         0 }
5774             $init->no_split;
5775 0 0       0  
    0          
    0          
    0          
5776 0         0 if ($ispadnamelist) {
5777 0         0 my $fill1 = $fill+1;
5778 0 0       0 $init->add("{", "\tPADNAME **svp;");
5779 0         0 $init->add("\tregister int gcount;") if $count;
5780             $init->add(
5781             "\tPADNAMELIST *padnl = $sym;",
5782             sprintf("\tNewxz(svp, %d, PADNAME *);", $fill+1),
5783             "\tPadnamelistARRAY(padnl) = svp;",
5784 0         0 );
5785 0         0 $init->add( substr( $acc, 0, -2 ) );
5786             $init->add("}");
5787             }
5788 0         0 elsif ($ispadlist) {
5789 0         0 my $fill1 = $fill+1;
5790 0 0       0 $init->add("{", "\tPAD **svp;");
5791 0         0 $init->add("\tregister int gcount;") if $count;
5792             $init->add(
5793             "\tPADLIST *padl = $sym;",
5794             sprintf("\tNewxz(svp, %d, PAD *);", $fill+1),
5795             "\tPadlistARRAY(padl) = svp;",
5796 0         0 );
5797 0         0 $init->add( substr( $acc, 0, -2 ) );
5798             $init->add("}");
5799             }
5800             # With -fav-init2 use independent_comalloc()
5801 0         0 elsif ($B::C::av_init2) {
5802 0         0 my $i = $av_index;
5803 0         0 $xpvav_sizes[$i] = $fill;
5804 0 0       0 my $init_add = "{ SV **svp = avchunks[$i]; AV *av = $sym;\n";
5805 0 0       0 $init_add .= "\tregister int gcount;\n" if $count;
5806 0 0       0 if ($fill > -1) {
5807 0         0 if ($PERL510) {
5808             $init_add .= "\tAvALLOC(av) = svp;\n".
5809             "\tAvARRAY(av) = svp;\n";
5810 0         0 } else {
5811             $init_add .= "\tAvALLOC(av) = svp;\n" .
5812             # XXX Dirty hack from av.c:Perl_av_extend()
5813             "\tSvPVX(av) = (char*)svp;";
5814             }
5815 0         0 }
5816 0         0 $init_add .= substr( $acc, 0, -2 );
5817             $init->add( $init_add . "}" );
5818             }
5819             # With -fav-init faster initialize the array as the initial av_extend()
5820             # is very expensive.
5821             # The problem was calloc, not av_extend.
5822             # Since we are always initializing every single element we don't need
5823             # calloc, only malloc. wmemset'ting the pointer to PL_sv_undef
5824             # might be faster also.
5825 0         0 elsif ($B::C::av_init) {
5826             $init->add(
5827             "{", "\tSV **svp;",
5828 0 0       0 "\tAV *av = $sym;");
5829 0 0       0 $init->add("\tregister int gcount;") if $count;
5830 0 0       0 my $fill1 = $fill < 3 ? 3 : $fill+1;
5831 0 0       0 if ($fill > -1) {
5832             $fill1 = $fill+1 if $fullname eq 'END';
5833 0 0       0 # Perl_safesysmalloc (= calloc => malloc) or Perl_malloc (= mymalloc)?
5834 0         0 if ($MYMALLOC) {
5835             $init->add(sprintf("\tNewx(svp, %d, SV*);", $fill1),
5836             "\tAvALLOC(av) = svp;");
5837             } else {
5838             # Bypassing Perl_safesysmalloc on darwin fails with "free from wrong pool", test 25.
5839 0         0 # So with DEBUGGING perls we have to track memory and use calloc.
5840             $init->add("#ifdef PERL_TRACK_MEMPOOL",
5841             sprintf("\tsvp = (SV**)Perl_safesysmalloc(%d * sizeof(SV*));", $fill1),
5842             "#else",
5843             sprintf("\tsvp = (SV**)malloc(%d * sizeof(SV*));", $fill1),
5844             "#endif",
5845             "\tAvALLOC(av) = svp;");
5846 0 0       0 }
5847 0         0 if ($PERL510) {
5848             $init->add("\tAvARRAY(av) = svp;");
5849             } else { # read-only AvARRAY macro
5850 0         0 # XXX Dirty hack from av.c:Perl_av_extend()
5851             $init->add("\tSvPVX(av) = (char*)svp;");
5852             }
5853 0         0 }
5854 0         0 $init->add( substr( $acc, 0, -2 ) ); # AvFILLp already in XPVAV
5855             $init->add( "}" );
5856             }
5857 0 0       0 else { # unoptimized with the full av_extend()
5858 0         0 my $fill1 = $fill < 3 ? 3 : $fill+1;
5859 0 0       0 $init->add("{", "\tSV **svp;");
5860 0         0 $init->add("\tregister int gcount;") if $count;
5861             $init->add("\tAV *av = $sym;\t/* $fullname */",
5862             "\tav_extend(av, $fill1);",
5863 0         0 "\tsvp = AvARRAY(av);");
5864 0         0 $init->add( substr( $acc, 0, -2 ) );
5865 0         0 $init->add( "\tAvFILLp(av) = $fill;" );
5866             $init->add( "}" );
5867 0         0 }
5868             $init->split;
5869              
5870             # we really added a lot of lines ( B::C::InitSection->add
5871             # should really scan for \n, but that would slow
5872 0         0 # it down
5873             $init->inc_count($#array);
5874             }
5875 0         0 else {
5876 0 0 0     0 my $max = $av->MAX;
5877             $init->add("av_extend($sym, $max);")
5878             if $max > -1 and !$static_av;
5879 0 0       0 }
5880 0         0 $init->add("SvREADONLY_on($sym);") if $av_cow;
5881             return $sym;
5882             }
5883              
5884 0     0   0 sub B::HV::save {
5885 0 0       0 my ($hv, $fullname) = @_;
5886 0         0 $fullname = '' unless $fullname;
5887 0 0       0 my $sym = objsym($hv);
5888 0         0 return $sym if defined $sym;
5889 0         0 my $name = $hv->NAME;
5890 0         0 my $is_stash = $name;
5891 0 0       0 my $magic;
5892             if ($name) {
5893             # It's a stash. See issue 79 + test 46
5894 0 0       0 warn sprintf( "Saving stash HV \"%s\" from \"$fullname\" 0x%x MAX=%d\n",
5895             $name, $$hv, $hv->MAX ) if $debug{hv};
5896              
5897             # A perl bug means HvPMROOT isn't altered when a PMOP is freed. Usually
5898             # the only symptom is that sv_reset tries to reset the PMf_USED flag of
5899             # a trashed op but we look at the trashed op_type and segfault.
5900 0         0 #my $adpmroot = ${$hv->PMROOT}; # XXX When was this fixed?
5901 0         0 my $adpmroot = 0;
5902 0         0 $sym = savestashpv($name);
5903 0 0       0 savesym( $hv, $sym );
5904 0         0 if ($adpmroot) {
5905             $init->add(sprintf( "HvPMROOT(hv%d) = (PMOP*)s\\_%x;",
5906             $hv_index, $adpmroot ) );
5907 0 0 0     0 }
      0        
5908             if ($PERL518 and $hv->FLAGS & SVf_AMAGIC and length($name)) {
5909 0 0       0 # fix overload stringify
5910 0         0 if ($hv->Gv_AMG) { # potentially removes the AMG flag
5911             $init2->add( sprintf("mro_isa_changed_in(%s); /* %s */", $sym, $name));
5912             }
5913             }
5914             # Add aliases if namecount > 1 (GH #331)
5915 0 0       0 # There was no B API for the count or multiple enames, so I added one.
5916 0 0       0 my @enames = ($PERL514 ? $hv->ENAMES : ());
5917 0 0       0 if (@enames > 1) {
5918 0         0 warn "Saving for $name multiple enames: ", join(" ",@enames), "\n" if $debug{hv};
5919             my $name_count = $hv->name_count;
5920             # If the stash name is empty xhv_name_count is negative, and names[0] should
5921 0         0 # be already set. but we rather write it.
5922 0         0 $init->no_split;
5923             my $hv_max = $hv->MAX + 1;
5924 0         0 # unshift @enames, $name if $name_count < 0; # stashpv has already set names[0]
5925             $init->add( "if (!SvOOK($sym)) {", # hv_auxinit is not exported
5926             " HE **a;",
5927             "#ifdef PERL_USE_LARGE_HV_ALLOC",
5928             sprintf( " Newxz(a, PERL_HV_ARRAY_ALLOC_BYTES(%d) + sizeof(struct xpvhv_aux), HE*);",
5929             $hv_max),
5930             "#else",
5931             sprintf( " Newxz(a, %d + sizeof(struct xpvhv_aux), HE*);", $hv_max),
5932             "#endif",
5933             " SvOOK_on($sym);",
5934             "}",
5935             "{",
5936             " struct xpvhv_aux *aux = HvAUX($sym);",
5937             sprintf( " Newx(aux->xhv_name_u.xhvnameu_names, %d, HEK*);", scalar @enames),
5938 0         0 sprintf( " aux->xhv_name_count = %d;", $name_count));
5939 0         0 my $i = 0;
5940 0         0 while (@enames) {
5941 0 0       0 my ($cstring, $cur, $utf8) = strlen_flags(shift @enames);
5942             $init->add(
5943             sprintf( " aux->xhv_name_u.xhvnameu_names[%u] = share_hek(%s, %d);",
5944             $i++, $cstring, $utf8 ? -$cur : $cur));
5945 0         0 }
5946 0         0 $init->add( "}" );
5947             $init->split;
5948             }
5949              
5950             # issue 79, test 46: save stashes to check for packages.
5951             # and via B::STASHGV we only save stashes for stashes.
5952             # For efficiency we skip most stash symbols unless -fstash.
5953             # However it should be now safe to save all stash symbols.
5954 0 0       0 # $fullname !~ /::$/ or
5955 0         0 if (!$B::C::stash) { # -fno-stash: do not save stashes
5956 0 0 0     0 $magic = $hv->save_magic('%'.$name.'::'); #symtab magic set in PMOP #188 (#267)
      0        
5957 0         0 if ($PERL510 and is_using_mro() && mro::get_mro($name) eq 'c3') {
5958             B::C::make_c3($name);
5959 0 0 0     0 }
5960 0 0       0 if ($magic and $magic =~ /c/) {
5961             warn "defer AMT magic of $name\n" if $debug{mg};
5962             # defer AMT magic of XS loaded hashes. #305 Encode::XS with tiehash magic
5963             # $init1->add(qq[$sym = gv_stashpvn($cname, $len, GV_ADDWARN|GV_ADDMULTI);]);
5964 0         0 }
5965             return $sym;
5966 0 0 0     0 }
5967 0         0 return $sym if skip_pkg($name) or $name eq 'main';
5968 0 0       0 $init->add( "SvREFCNT_inc($sym);" );
5969             warn "Saving stash keys for HV \"$name\" from \"$fullname\"\n" if $debug{hv};
5970             }
5971              
5972             # Ordinary HV or Stash
5973             # KEYS = 0, inc. dynamically below with hv_store. TODO: HvSTATIC readonly tables,
5974 0 0       0 # without hv_store
5975 0         0 if ($PERL510) {
5976 0 0       0 my $flags = $hv->FLAGS & ~SVf_READONLY;
5977 0 0       0 $flags &= ~SVf_PROTECT if $PERL522;
5978 0         0 if ($PERL514) { # fill removed with 5.13.1
5979 0         0 $xpvhvsect->comment( "stash mgu max keys" );
5980             $xpvhvsect->add(sprintf( "Nullhv, {0}, %d, %d",
5981             $hv->MAX, 0 ));
5982 0         0 } else {
5983 0         0 $xpvhvsect->comment( "GVSTASH fill max keys MG STASH" );
5984             $xpvhvsect->add(sprintf( "{0}, %d, %d, {%d}, {0}, Nullhv",
5985             0, $hv->MAX, 0 ));
5986 0         0 }
5987             $svsect->add(sprintf("&xpvhv_list[%d], $u32fmt, 0x%x, {0}",
5988             $xpvhvsect->index, $hv->REFCNT, $flags));
5989 0 0 0     0 # XXX failed at 16 (tied magic) for %main::
      0        
5990 0         0 if (!$is_stash and ($] >= 5.010 and $hv->FLAGS & SVf_OOK)) {
5991 0         0 $sym = sprintf("&sv_list[%d]", $svsect->index);
5992             my $hv_max = $hv->MAX + 1;
5993 0         0 # riter required, new _aux struct at the end of the HvARRAY. allocate ARRAY also.
5994             $init->add("{\tHE **a;",
5995             "#ifdef PERL_USE_LARGE_HV_ALLOC",
5996             sprintf("\tNewxz(a, PERL_HV_ARRAY_ALLOC_BYTES(%d) + sizeof(struct xpvhv_aux), HE*);",
5997             $hv_max),
5998             "#else",
5999             sprintf("\tNewxz(a, %d + sizeof(struct xpvhv_aux), HE*);", $hv_max),
6000             "#endif",
6001             "\tHvARRAY($sym) = a;",
6002             sprintf("\tHvRITER_set($sym, %d);", $hv->RITER),"}");
6003             }
6004             } # !5.10
6005 0         0 else {
6006 0         0 $xpvhvsect->comment( "array fill max keys nv mg stash riter eiter pmroot name" );
6007             $xpvhvsect->add(sprintf( "0, 0, %d, 0, 0.0, 0, Nullhv, %d, 0, 0, 0",
6008 0         0 $hv->MAX, $hv->RITER));
6009             $svsect->add(sprintf( "&xpvhv_list[%d], $u32fmt, 0x%x",
6010             $xpvhvsect->index, $hv->REFCNT, $hv->FLAGS));
6011 0 0       0 }
6012 0         0 $svsect->debug($fullname, $hv->flagspv) if $debug{flags};
6013             my $sv_list_index = $svsect->index;
6014 0 0       0 warn sprintf( "saving HV %s &sv_list[%d] 0x%x MAX=%d KEYS=%d\n",
6015             "%".$fullname, $sv_list_index, $$hv, $hv->MAX, $hv->KEYS ) if $debug{hv};
6016             # XXX B does not keep the UTF8 flag [RT 120535] #200
6017 0 0 0     0 # shared heks only since 5.10, our fixed C.xs variant
6018             my @contents = ($PERL510 && $hv->can('ARRAY_utf8')) ? $hv->ARRAY_utf8 : $hv->ARRAY;
6019             # protect against recursive self-reference
6020             # i.e. with use Moose at stash Class::MOP::Class::Immutable::Trait
6021 0 0       0 # value => rv => cv => ... => rv => same hash
6022 0 0 0     0 $sym = savesym( $hv, "(HV*)&sv_list[$sv_list_index]" ) unless $is_stash;
6023             push @B::C::static_free, $sym if $PERL518 and $hv->FLAGS & SVs_OBJECT;
6024 0 0       0  
    0          
6025 0         0 if (@contents) {
6026 0         0 local $B::C::const_strings = $B::C::const_strings;
6027 0         0 my ($i, $length);
6028 0         0 $length = scalar(@contents);
6029 0         0 for ( $i = 1 ; $i < @contents ; $i += 2 ) {
6030 0         0 my $key = $contents[$i - 1]; # string only
6031             my $sv = $contents[$i];
6032             warn sprintf("HV recursion? with $fullname\{$key\} -> %s\n", $sv->RV)
6033             if ref($sv) eq 'B::RV'
6034             #and $sv->RV->isa('B::CV')
6035 0 0 0     0 and defined objsym($sv)
      0        
6036 0 0       0 and $debug{hv};
6037 0 0 0     0 if ($is_stash) {
6038 0         0 if (ref($sv) eq "B::GV" and $sv->NAME =~ /::$/) {
6039 0 0       0 $sv = bless $sv, "B::STASHGV"; # do not expand stash GV's only other stashes
6040 0         0 warn "saving STASH $fullname".'{'.$key."}\n" if $debug{hv};
6041             $contents[$i] = $sv->save($fullname.'{'.$key.'}');
6042 0 0       0 } else {
6043 0         0 warn "skip STASH symbol *",$fullname.$key,"\n" if $debug{hv};
6044 0         0 $contents[$i] = undef;
6045             $length -= 2;
6046             # warn "(length=$length)\n" if $debug{hv};
6047             }
6048 0 0       0 } else {
6049 0         0 warn "saving HV \$".$fullname.'{'.$key."} $sv\n" if $debug{hv};
6050             $contents[$i] = $sv->save($fullname.'{'.$key.'}');
6051             #if ($key eq "" and $] >= 5.010) {
6052             # warn " turn off HvSHAREKEYS with empty keysv\n" if $debug{hv};
6053             # $init->add("HvSHAREKEYS_off(&sv_list[$sv_list_index]);");
6054             #}
6055             }
6056 0 0       0 }
6057 0         0 if ($length) { # there may be skipped STASH symbols
6058 0 0       0 $init->no_split;
6059             $init->add( "{",
6060 0         0 sprintf("\tHV *hv = %s%s;", $sym=~/^hv|\(HV/ ? '' : '(HV*)', $sym ));
6061 0         0 while (@contents) {
6062 0 0       0 my ( $key, $value ) = splice( @contents, 0, 2 );
6063 0 0 0     0 if ($value) {
      0        
6064 0         0 $value = "(SV*)$value" if $value !~ /^&sv_list/ or ($PERL510 and $] < 5.012);
6065             my ($cstring, $cur, $utf8) = strlen_flags($key);
6066             # issue 272: if SvIsCOW(sv) && SvLEN(sv) == 0 => sharedhek (key == "")
6067 0 0       0 # >= 5.10: SvSHARED_HASH: PV offset to hek_hash
6068 0         0 $cur = -$cur if $utf8;
6069             $init->add(sprintf( "\thv_store(hv, %s, %d, %s, 0);",
6070 0 0       0 $cstring, $cur, $value )); # !! randomized hash keys
6071 0 0 0     0 warn sprintf( " HV key \"%s\" = %s\n", $key, $value) if $debug{hv};
      0        
      0        
6072             if (!$swash_ToCf and $fullname =~ /^utf8::SWASHNEW/
6073             and $cstring eq '"utf8\034unicore/To/Cf.pl\0340"' and $cur == 23)
6074 0         0 {
6075 0 0       0 $swash_ToCf = $value;
6076             warn sprintf( "Found PL_utf8_tofold ToCf swash $value\n") if $verbose;
6077             }
6078             }
6079 0         0 }
6080 0         0 $init->add("}");
6081 0 0       0 $init->split;
6082             $init->add( sprintf("HvTOTALKEYS(%s) = %d;", $sym, $length / 2)) if !$PERL56;
6083             }
6084             } elsif ($PERL514) { # empty contents still needs to set keys=0
6085 0         0 # test 36, 140
6086             $init->add( "HvTOTALKEYS($sym) = 0;");
6087 0         0 }
6088 0 0       0 $magic = $hv->save_magic($fullname);
6089 0 0       0 $init->add( "SvREADONLY_on($sym);") if $hv->FLAGS & SVf_READONLY;
6090             if ($magic =~ /c/) {
6091 0         0 # defer AMT magic of XS loaded stashes
6092 0         0 my ($cname, $len, $utf8) = strlen_flags($name);
6093             $init2->add(qq[$sym = gv_stashpvn($cname, $len, GV_ADDWARN|GV_ADDMULTI|$utf8);]);
6094 0 0 0     0 }
      0        
      0        
6095 0         0 if ($PERL510 and $name and is_using_mro() and mro::get_mro($name) eq 'c3') {
6096             B::C::make_c3($name);
6097 0         0 }
6098             return $sym;
6099             }
6100              
6101 0     0   0 sub B::IO::save_data {
6102 0         0 my ( $io, $sym, $globname, @data ) = @_;
6103             my $data = join '', @data;
6104 0         0 # XXX using $DATA might clobber it!
6105 0 0       0 my $ref = svref_2object( \\$data )->save;
6106 0         0 $init->add("/* save $globname in RV ($ref) */") if $verbose;
6107             $init->add( "GvSVn( $sym ) = (SV*)$ref;");
6108 0 0       0  
6109             if ($PERL56) {
6110 0         0 # Pseudo FileHandle
6111             $init2->add_eval( sprintf 'open(%s, \'<\', $%s);', $globname, $globname );
6112 0         0 } else { # force inclusion of PerlIO::scalar as it was loaded in BEGIN.
6113             $init2->add_eval( sprintf 'open(%s, \'<:scalar\', $%s);', $globname, $globname );
6114 0         0 # => eval_pv("open(main::DATA, '<:scalar', $main::DATA);",1); DATA being a ref to $data
6115 0         0 $init->pre_destruct( sprintf 'eval_pv("close %s;", 1);', $globname );
6116 0 0       0 $use_xsloader = 1; # layers are not detected as XSUB CV, so force it
6117 0 0       0 require PerlIO unless $savINC{'PerlIO.pm'};
6118 0         0 require PerlIO::scalar unless $savINC{'PerlIO/scalar.pm'};
6119 0         0 mark_package("PerlIO", 1);
6120 0         0 $curINC{'PerlIO.pm'} = $INC{'PerlIO.pm'}; # as it was loaded from BEGIN
6121 0         0 mark_package("PerlIO::scalar", 1);
6122 0         0 $curINC{'PerlIO/scalar.pm'} = $INC{'PerlIO/scalar.pm'};
6123             $xsub{'PerlIO::scalar'} = 'Dynamic-'.$INC{'PerlIO/scalar.pm'}; # force dl_init boot
6124             }
6125             }
6126              
6127 0     0   0 sub B::IO::save {
6128 0         0 my ($io, $fullname, $is_DATA) = @_;
6129 0 0       0 my $sym = objsym($io);
6130 0         0 return $sym if defined $sym;
6131 0 0       0 my $pv = $io->PV;
6132 0         0 $pv = '' unless defined $pv;
6133 0 0       0 my ( $pvsym, $len, $cur );
6134 0         0 if ($pv) {
6135 0         0 $pvsym = savepv($pv);
6136             $cur = $io->CUR;
6137 0         0 } else {
6138 0         0 $pvsym = 'NULL';
6139             $cur = 0;
6140 0 0       0 }
6141 0         0 if ($cur) {
6142 0 0 0     0 $len = $cur + 1;
6143             $len++ if IsCOW($io) and !$B::C::cow;
6144 0         0 } else {
6145             $len = 0;
6146             }
6147 0 0 0     0 warn sprintf( "IO $fullname sv_list[%d] 0x%x (%s) = '%s'\n", $svsect->index+1, $$io, $io->SvTYPE, $pv )
6148 0 0       0 if $debug{sv} and $] > 5.008; # no method "SvTYPE" via package "B::IO"
    0          
    0          
6149             if ($PERL514) {
6150 0         0 # IFP in sv.sv_u.svu_fp
6151 0         0 $xpviosect->comment("STASH, xmg_u, cur, len, xiv_u, xio_ofp, xio_dirpu, page, page_len, ..., type, flags");
6152 0 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*/";
6153 0 0       0 $tmpl =~ s{ /\*.+?\*/\n\t}{}g unless $verbose;
6154 0         0 $tmpl =~ s{ /\*flags\*/$}{} unless $verbose;
6155             $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 0 0       0 );
6165             $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 0         0 elsif ($] > 5.011000) {
6170 0         0 $xpviosect->comment("xnv_u, cur, len, lines, xmg_u, xmg_stash, xio_ifp, xio_ofp, xio_dirpu, ..., type, flags");
6171 0 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*/";
6172 0 0       0 $tmpl =~ s{ /\*.+?\*/\n\t}{}g unless $verbose;
6173 0         0 $tmpl =~ s{ /\*flags\*/$}{} unless $verbose;
6174             $xpviosect->add(
6175             sprintf($tmpl,
6176             $cur, $len,
6177             $io->LINES, # moved to IVX with 5.11.1
6178             $io->PAGE, $io->PAGE_LEN,
6179             $io->LINES_LEFT, "NULL",
6180             "NULL", "NULL",
6181             cchar( $io->IoTYPE ), $io->IoFLAGS
6182             )
6183 0 0       0 );
6184             $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}",
6185             $xpviosect->index, $io->REFCNT, $io->FLAGS,
6186             $B::C::pv_copy_on_grow ? $pvsym : 0));
6187             }
6188 0         0 elsif ($PERL510) {
6189 0         0 $xpviosect->comment("xnv_u, cur, len, xiv_u, xmg_u, xmg_stash, xio_ifp, xio_ofp, xio_dirpu, lines, ..., type, flags");
6190 0 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*/";
6191 0 0       0 $tmpl =~ s{ /\*[^\*]+?\*/\n\t}{}g unless $verbose;
6192 0         0 $tmpl =~ s{ /\*flags\*/$}{} unless $verbose;
6193             $xpviosect->add(
6194             sprintf($tmpl,
6195             $cur, $len,
6196             $io->IVX,
6197             $io->LINES,
6198             $io->PAGE, $io->PAGE_LEN,
6199             $io->LINES_LEFT, "NULL",
6200             "NULL", "NULL",
6201             cchar( $io->IoTYPE ), $io->IoFLAGS
6202             )
6203 0 0       0 );
6204             $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}",
6205             $xpviosect->index, $io->REFCNT, $io->FLAGS,
6206             $B::C::pv_copy_on_grow ? $pvsym : 0));
6207             }
6208 0         0 else { # 5.6 and 5.8
6209 0         0 $xpviosect->comment("xpv_pv, cur, len, iv, nv, magic, stash, xio_ifp, xio_ofp, xio_dirpu, ..., subprocess, type, flags");
6210             $xpviosect->add(
6211             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",
6212             $pvsym, $cur, $len,
6213             $io->IVX, $io->NVX,
6214             $io->LINES, $io->PAGE,
6215             $io->PAGE_LEN, $io->LINES_LEFT,
6216             "NULL", "NULL",
6217             "NULL", $io->SUBPROCESS,
6218             cchar( $io->IoTYPE ), $io->IoFLAGS
6219             )
6220 0         0 );
6221             $svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x",
6222             $xpviosect->index, $io->REFCNT, $io->FLAGS));
6223 0 0       0 }
6224 0         0 $svsect->debug($fullname, $io->flagspv) if $debug{flags};
6225             $sym = savesym( $io, sprintf( "(IO*)&sv_list[%d]", $svsect->index ) );
6226 0 0 0     0  
      0        
6227 0         0 if ($PERL510 and !$B::C::pv_copy_on_grow and $cur) {
6228             $init->add(sprintf("SvPVX(sv_list[%d]) = %s;", $svsect->index, $pvsym));
6229 0         0 }
6230 0         0 my ( $field );
6231 0         0 foreach $field (qw(TOP_GV FMT_GV BOTTOM_GV)) {
6232 0 0       0 my $fsym = $io->$field();
6233 0         0 if ($$fsym) {
6234 0         0 $init->add( sprintf( "Io%s(%s) = (GV*)s\\_%x;", $field, $sym, $$fsym ) );
6235             $fsym->save;
6236             }
6237 0         0 }
6238 0         0 foreach $field (qw(TOP_NAME FMT_NAME BOTTOM_NAME)) {
6239 0 0       0 my $fsym = $io->$field;
6240             $init->add(sprintf("Io%s(%s) = savepvn(%s, %u);", $field, $sym,
6241             cstring( $fsym ), length $fsym)) if $fsym;
6242 0         0 }
6243 0 0 0     0 $io->save_magic($fullname); # This handle the stash also (we need to inc the refcnt)
6244             if (!$PERL56 and !$is_DATA) { # PerlIO
6245 0         0 # deal with $x = *STDIN/STDOUT/STDERR{IO} and aliases
6246             my $perlio_func;
6247             # Note: all single-direction fp use IFP, just bi-directional pipes and
6248 0         0 # sockets use OFP also. But we need to set both, pp_print checks OFP.
6249 0         0 my $o = $io->object_2svref();
6250 0         0 eval "require ".ref($o).";";
6251             my $fd = $o->fileno();
6252             # use IO::Handle ();
6253 0         0 # my $fd = IO::Handle::fileno($o);
6254 0         0 my $i = 0;
6255 0 0 0     0 foreach (qw(stdin stdout stderr)) {
      0        
6256 0         0 if ($io->IsSTD($_) or (defined($fd) and $fd == -$i)) {
6257             $perlio_func = $_;
6258 0         0 }
6259             $i++;
6260 0 0       0 }
6261 0         0 if ($perlio_func) {
6262             $init->add("IoIFP(${sym}) = IoOFP(${sym}) = PerlIO_${perlio_func}();");
6263             #if ($fd < 0) { # fd=-1 signals an error
6264             # XXX print may fail at flush == EOF, wrong init-time?
6265             #}
6266 0         0 } else {
6267 0         0 my $iotype = $io->IoTYPE;
6268             my $ioflags = $io->IoFLAGS;
6269             # If an IO handle was opened at BEGIN, we try to re-init it, based on fd and IoTYPE.
6270             # IOTYPE:
6271             # - STDIN/OUT HANDLE IoIOFP alias
6272             # I STDIN/OUT/ERR HANDLE IoIOFP alias
6273             # < read-only HANDLE fdopen
6274             # > write-only HANDLE if fd<3 or IGNORE warn and comment
6275             # a append HANDLE -"-
6276             # + read and write HANDLE fdopen
6277             # s socket DIE
6278             # | pipe DIE
6279             # # NUMERIC HANDLE fdopen
6280             # space closed IGNORE
6281 0 0 0     0 # \0 ex/closed? IGNORE
    0          
    0          
6282             if ($iotype eq "\c@" or $iotype eq " ") {
6283             warn sprintf("Ignore closed IO Handle %s %s (%d)\n",
6284 0 0       0 cstring($iotype), $fullname, $ioflags)
6285             if $debug{gv};
6286             }
6287 0 0 0     0 elsif ($iotype =~ /[a>]/) { # write-only
6288             warn "Warning: Write BEGIN-block $fullname to FileHandle $iotype \&$fd\n"
6289 0 0       0 if $fd >= 3 or $verbose;
6290             my $mode = $iotype eq '>' ? 'w' : 'a';
6291             #$init->add( sprintf("IoIFP($sym) = IoOFP($sym) = PerlIO_openn(aTHX_ NULL,%s,%d,0,0,NULL,0,NULL);",
6292 0 0       0 # cstring($mode), $fd));
    0          
6293             $init->add(sprintf( "%sIoIFP(%s) = IoOFP(%s) = PerlIO_fdopen(%d, %s);%s",
6294             $fd<3?'':'/*', $sym, $sym, $fd, cstring($mode), $fd<3?'':'*/'));
6295             }
6296             elsif ($iotype =~ /[<#\+]/) {
6297 0 0 0     0 # skips warning if it's one of our PerlIO::scalar __DATA__ handles
6298             warn "Warning: Read BEGIN-block $fullname from FileHandle $iotype \&$fd\n"
6299 0         0 if $fd >= 3 or $verbose; # need to setup it up before
6300             $init->add("/* XXX WARNING: Read BEGIN-block $fullname from FileHandle */",
6301 0         0 "IoIFP($sym) = IoOFP($sym) = PerlIO_fdopen($fd, \"r\");");
6302 0 0 0     0 my $tell;
6303 0         0 if ($io->can("tell") and $tell = $io->tell()) {
6304             $init->add("PerlIO_seek(IoIFP($sym), $tell, SEEK_SET);")
6305             }
6306             } else {
6307 0         0 # XXX We should really die here
6308             warn sprintf("ERROR: Unhandled BEGIN-block IO Handle %s\&%d (%d) from %s\n",
6309 0         0 cstring($iotype), $fd, $ioflags, $fullname);
6310             $init->add("/* XXX WARNING: Unhandled BEGIN-block IO Handle ",
6311             "IoTYPE=$iotype SYMBOL=$fullname, IoFLAGS=$ioflags */",
6312             "IoIFP($sym) = IoOFP($sym) = PerlIO_fdopen($fd, \"$iotype\");");
6313             }
6314             }
6315             }
6316 0 0       0  
6317 0         0 if ( $PERL518 ) {
6318 0 0 0     0 my $stash = $io->SvSTASH;
6319 0         0 if ($stash and $$stash) {
6320 0         0 my $stsym = $stash->save("%".$stash->NAME);
6321             $init->add(
6322             sprintf( "SvREFCNT(%s) += 1;", $stsym ),
6323             sprintf( "SvSTASH_set(%s, %s);", $sym, $stsym )
6324             );
6325 0 0       0 warn sprintf( "done saving STASH %s %s for IO %s\n", $stash->NAME, $stsym, $sym )
6326             if $debug{gv};
6327             }
6328             }
6329 0         0  
6330             return $sym;
6331             }
6332              
6333 0     0   0 sub B::SV::save {
6334             my $sv = shift;
6335              
6336             # This is where we catch an honest-to-goodness Nullsv (which gets
6337 0 0       0 # blessed into B::SV explicitly) and any stray erroneous SVs.
6338 0         0 return 0 unless $$sv;
6339             warn sprintf( "cannot save that type of SV: %s (0x%x)\n", B::class($sv), $$sv );
6340             }
6341              
6342 0     0 0 0 sub output_all {
6343 0         0 my $init_name = shift;
6344 0 0       0 my $section;
6345             return if $check;
6346 0         0  
6347             my @sections =
6348             (
6349             $copsect, $opsect, $unopsect, $binopsect, $logopsect, $condopsect,
6350             $listopsect, $pmopsect, $svopsect, $padopsect, $pvopsect, $loopsect,
6351             $methopsect, $unopauxsect,
6352             $xpvsect, $xpvavsect, $xpvhvsect, $xpvcvsect, $padlistsect,
6353             $padnlsect, $xpvivsect, $xpvuvsect, $xpvnvsect, $xpvmgsect, $xpvlvsect,
6354             $xrvsect, $xpvbmsect, $xpviosect, $svsect, $padnamesect,
6355 0 0       0 );
6356 0         0 if ($PERL522) {
6357 0         0 pop @sections;
6358 0         0 for my $n (sort keys %padnamesect) {
6359             push @sections, $padnamesect{$n};
6360             }
6361 0 0       0 }
6362 0         0 if ($CPERL52) {
6363 0         0 for my $n (sort keys %avcowsect) {
6364             push @sections, $avcowsect{$n};
6365 0         0 }
6366 0         0 for my $n (sort keys %avcogsect) {
6367             push @sections, $avcogsect{$n};
6368             }
6369 0 0 0     0 }
6370 0         0 printf "\t/* %s */", $symsect->comment if $symsect->comment and $verbose;
6371 0         0 $symsect->output( \*STDOUT, "#define %s\n" );
6372 0         0 print "\n";
6373             output_declarations();
6374 0         0 # XXX add debug versions with ix=opindex if $debug{flags}
6375 0         0 foreach $section (@sections) {
6376 0 0       0 my $lines = $section->index + 1;
6377 0         0 if ($lines) {
6378 0         0 my $name = $section->name;
6379             my $typename = $section->typename;
6380 0 0 0     0 # static SV** arrays for AvSTATIC, HvSTATIC, ...
6381 0         0 if ($typename eq 'SV*' and $name =~ /^(?:avco[gw])_(\d+)$/) {
6382 0 0       0 my $n = $1;
6383 0         0 $typename = 'const SV*' if $name =~ /^avcow_/;
6384             print "Static $typename ${name}_list[$lines][$n];\n";
6385 0         0 } else {
6386             print "Static $typename ${name}_list[$lines];\n";
6387             }
6388             }
6389             }
6390              
6391 0         0 # hack for when Perl accesses PVX of GVs
6392             print 'Static const char emptystring[] = "\0";',"\n";
6393 0         0 # newXS for core XS needs a filename
6394 0 0       0 print 'Static const char xsfile[] = "universal.c";',"\n";
6395 0         0 if ($MULTI) {
6396             print "#define ptr_undef 0\n";
6397 0 0       0 } else {
6398 0         0 if ($] > 5.01903) {
6399             print "#define ptr_undef NULL\n";
6400 0         0 } else {
6401             print "#define ptr_undef &PL_sv_undef\n";
6402 0 0       0 }
6403 0         0 if ($PERL510) { # XXX const sv SIGSEGV
6404 0         0 print "#undef CopFILE_set\n";
6405             print "#define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv))\n";
6406             }
6407             }
6408 0 0       0 # print "#define MyPVX(sv) ".($] < 5.010 ? "SvPVX(sv)" : "((sv)->sv_u.svu_pv)")."\n";
6409 0         0 if ($] < 5.008008 ) {
6410             print <<'EOT';
6411             #ifndef SvSTASH_set
6412             # define SvSTASH_set(sv,hv) SvSTASH((sv)) = (hv)
6413             #endif
6414             #ifndef Newxz
6415             # define Newxz(v,n,t) Newz(0,v,n,t)
6416             #endif
6417             EOT
6418 0 0       0 }
6419 0         0 if ($] < 5.008009 ) {
6420             print <<'EOT';
6421             #ifndef SvREFCNT_inc_simple_NN
6422             # define SvREFCNT_inc_simple_NN(sv) (++SvREFCNT(sv), (SV*)(sv))
6423             #endif
6424             #ifndef STR_WITH_LEN
6425             #define STR_WITH_LEN(s) ("" s ""), (sizeof(s)-1)
6426             #endif
6427             EOT
6428 0 0       0 }
6429 0         0 if ($] < 5.013007 ) {
6430             print <<'EOT';
6431             #ifndef CvSTASH_set
6432             # define CvSTASH_set(cv,hv) CvSTASH((cv)) = (hv)
6433             #endif
6434             EOT
6435 0 0       0 }
6436 0         0 if ($] < 5.013010 ) { # added with c43ae56ff9cd before 5.13.10 at 2011-01-21
6437             print <<'EOT';
6438             #ifndef GvCV_set
6439             # define GvCV_set(gv,cv) (GvCV(gv) = (cv))
6440             #endif
6441             #ifndef GvGP_set
6442             # define GvGP_set(gv,gp) (GvGP(gv) = (gp))
6443             #endif
6444             EOT
6445 0 0 0     0 }
6446 0         0 if ($] >= 5.021005 and $] < 5.023) {
6447             print <<'EOT';
6448             /* PadlistNAMES broken as lvalue with v5.21.6-197-g0f94cb1,
6449             fixed with 5.22.1 and 5.23.0 */
6450             #if (PERL_VERSION == 22) || ( PERL_VERSION == 21 && PERL_SUBVERSION > 5)
6451             # undef PadlistNAMES
6452             # define PadlistNAMES(pl) *((PADNAMELIST **)PadlistARRAY(pl))
6453             #endif
6454             EOT
6455             }
6456 0         0 # handy accessors only in cperl for now:
6457             print <<'EOT';
6458             #ifndef get_svs
6459             # define get_svs(str, flags) get_sv((str), (flags))
6460             # define get_avs(str, flags) get_av((str), (flags))
6461             # define get_hvs(str, flags) get_hv((str), (flags))
6462             #endif
6463 0 0 0     0 EOT
6464 0         0 if (%init2_remap and !$HAVE_DLFCN_DLOPEN) {
6465             print <<'EOT';
6466             XS(XS_DynaLoader_dl_load_file);
6467             XS(XS_DynaLoader_dl_find_symbol);
6468             EOT
6469 0 0 0     0 }
6470 0         0 printf "\t/* %s */\n", $decl->comment if $decl->comment and $verbose;
6471 0         0 $decl->output( \*STDOUT, "%s\n" );
6472             print "\n";
6473 0         0  
6474 0         0 foreach $section (@sections) {
6475 0 0       0 my $lines = $section->index + 1;
6476 0         0 if ($lines) {
6477 0         0 my $name = $section->name;
6478             my $typename = $section->typename;
6479 0 0 0     0 # static SV** arrays for AvSTATIC, HvSTATIC, ...
6480 0         0 if ($typename eq 'SV*' and $name =~ /^(?:avco[wg])_(\d+)$/) {
6481 0 0       0 my $n = $1;
6482 0         0 $typename = 'const SV*' if $name =~ /^avcow_/;
6483             printf "Static %s %s_list[%u][%u] = {\n", $typename, $name, $lines, $n;
6484 0         0 } else {
6485             printf "Static %s %s_list[%u] = {\n", $typename, $name, $lines;
6486 0 0 0     0 }
6487             printf "\t/* %s */\n", $section->comment
6488 0         0 if $section->comment and $verbose;
6489 0         0 $section->output( \*STDOUT, "\t{ %s }, /* %s_list[%d] %s */%s\n" );
6490             print "};\n\n";
6491             }
6492             }
6493 0         0  
6494 0         0 fixup_ppaddr();
6495 0 0       0 print "static void perl_init0(pTHX) /* fixup_ppaddr */\n{\n\t";
  0         0  
6496 0         0 print "register int i;\n" if @{ $init0->[-1]{values} };
6497 0         0 $init0->output( \*STDOUT, "\t%s\n" );
6498             print "};\n\n";
6499 0 0 0     0  
6500 0         0 printf "\t/* %s */\n", $init->comment if $init->comment and $verbose;
6501 0 0       0 $init->output( \*STDOUT, "\t%s\n", $init_name );
6502 0 0 0     0 printf "/* deferred init1 of regexp */\n" if $verbose;
6503 0         0 printf "/* %s */\n", $init1->comment if $init1->comment and $verbose;
6504 0         0 $init1->output( \*STDOUT, "\t%s\n", 'perl_init1' );
6505 0 0       0 my $init2_name = 'perl_init2';
6506 0 0 0     0 printf "/* deferred init of XS/Dyna loaded modules */\n" if $verbose;
6507 0         0 printf "/* %s */\n", $init2->comment if $init2->comment and $verbose;
6508 0         0 my $remap = 0;
6509 0 0       0 for my $pkg (sort keys %init2_remap) {
6510 0         0 if (exists $xsub{$pkg}) { # check if not removed in between
6511             my ($stashfile) = $xsub{$pkg} =~ /^Dynamic-(.+)$/;
6512 0 0       0 # get so file from pm. Note: could switch prefix from vendor/site//
6513 0         0 if ($stashfile) {
6514 0         0 $init2_remap{$pkg}{FILE} = dl_module_to_sofile($pkg, $stashfile);
6515             $remap++;
6516             }
6517             }
6518 0 0       0 }
6519             if ($remap) {
6520 0         0 # XXX now emit arch-specific dlsym code
6521 0         0 $init2->no_split;
6522 0 0       0 $init2->add("{");
6523 0         0 if ($HAVE_DLFCN_DLOPEN) {
6524 0         0 $init2->add(" #include ");
6525             $init2->add(" void *handle;");
6526 0         0 } else {
6527 0         0 $init2->add(" void *handle;");
6528             $init2->add(" dTARG; dSP;",
6529             " targ=sv_newmortal();");
6530 0         0 }
6531 0 0       0 for my $pkg (sort keys %init2_remap) {
6532 0 0       0 if (exists $xsub{$pkg}) {
6533 0         0 if ($HAVE_DLFCN_DLOPEN) {
6534 0 0       0 my $ldopt = 'RTLD_NOW|RTLD_NOLOAD';
6535 0         0 $ldopt = 'RTLD_NOW' if $^O =~ /bsd/i; # 351 (only on solaris and linux, not any bsd)
6536             $init2->add( "", sprintf(" handle = dlopen(%s, %s);", cstring($init2_remap{$pkg}{FILE}), $ldopt));
6537             }
6538             else {
6539 0         0 $init2->add(" PUSHMARK(SP);",
6540             sprintf(" XPUSHs(newSVpvs(%s));", cstring($init2_remap{$pkg}{FILE})),
6541             " PUTBACK;",
6542             " XS_DynaLoader_dl_load_file(aTHX_ NULL);",
6543             " SPAGAIN;",
6544             " handle = INT2PTR(void*,POPi);",
6545             " PUTBACK;",
6546             );
6547 0         0 }
  0         0  
6548 0 0       0 for my $mg (@{$init2_remap{$pkg}{MG}}) {
6549             warn "init2 remap xpvmg_list[$mg->{ID}].xiv_iv to dlsym of $pkg\: $mg->{NAME}\n"
6550 0 0       0 if $verbose;
6551             if ($HAVE_DLFCN_DLOPEN) {
6552 0         0 $init2->add(sprintf(" xpvmg_list[%d].xiv_iv = PTR2IV( dlsym(handle, %s) );",
6553             $mg->{ID}, cstring($mg->{NAME})));
6554             } else {
6555             $init2->add(" PUSHMARK(SP);",
6556             " XPUSHi(PTR2IV(handle));",
6557             sprintf(" XPUSHs(newSVpvs(%s));", cstring($mg->{NAME})),
6558             " PUTBACK;",
6559             " XS_DynaLoader_dl_find_symbol(aTHX_ NULL);",
6560 0         0 " SPAGAIN;",
6561             sprintf(" xpvmg_list[%d].xiv_iv = POPi;", $mg->{ID}),
6562             " PUTBACK;",
6563             );
6564             }
6565             }
6566             }
6567 0         0 }
6568 0         0 $init2->add("}");
6569             $init2->split;
6570 0         0 }
6571 0 0       0 $init2->output( \*STDOUT, "\t%s\n", $init2_name );
6572 0         0 if ($verbose) {
6573 0 0       0 my $caller = caller;
6574 0         0 warn $caller eq 'B::CC' ? B::CC::compile_stats() : compile_stats();
6575             warn "NULLOP count: $nullop_count\n";
6576             }
6577             }
6578              
6579 0     0 0 0 sub output_declarations {
6580             print <<'EOT';
6581             #define UNUSED 0
6582             #define sym_0 0
6583              
6584             static void
6585             my_mg_RC_off(pTHX_ SV* sv, int type) {
6586             MAGIC *mg;
6587             for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
6588             if (mg->mg_type == type && (mg->mg_flags | MGf_REFCOUNTED))
6589             mg->mg_flags &= ~MGf_REFCOUNTED;
6590             }
6591             }
6592              
6593 0 0 0     0 EOT
6594             if ($PERL510 and IS_MSVC) {
6595 0         0 # initializing char * differs in levels of indirection from int
6596             print "#pragma warning( disable : 4047 )\n";
6597 0         0 # targ: unreferenced local variable
6598             print "#pragma warning( disable : 4101 )\n";
6599             }
6600              
6601 0 0       0 # Need fresh re-hash of strtab. share_hek does not allow hash = 0
6602 0         0 if ( $PERL510 ) {
6603             print <<'_EOT0';
6604             PERL_STATIC_INLINE HEK *
6605             my_share_hek( pTHX_ const char *str, I32 len );
6606             #undef share_hek
6607             #define share_hek(str, len) my_share_hek( aTHX_ str, len );
6608              
6609             PERL_STATIC_INLINE HEK *
6610             my_share_hek_0( pTHX_ const char *str, I32 len);
6611              
6612             #define HEK_HE(hek) \
6613             ((struct shared_he *)(((char *)(hek)) \
6614             - STRUCT_OFFSET(struct shared_he, \
6615             shared_he_hek)))
6616             #define HEK_shared_he(hek) \
6617             ((struct shared_he *)(((char *)(hek)) \
6618             - STRUCT_OFFSET(struct shared_he, \
6619             shared_he_hek))) \
6620             ->shared_he_he
6621              
6622             #define hek_hek_refcount(hek) \
6623             HEK_shared_he(hek).he_valu.hent_refcount
6624              
6625             #define unshare_hek_hek(hek) --(hek_hek_refcount(hek))
6626              
6627             _EOT0
6628              
6629 0 0       0 }
6630 0         0 if ($PERL522) {
6631             print <<'EOF';
6632             /* unfortunately we have to override this perl5.22 struct.
6633             The Padname string buffer in xpadn_str is pointed by xpadn_pv.
6634             */
6635             #define _PADNAME_BASE \
6636             char * xpadn_pv; \
6637             HV * xpadn_ourstash; \
6638             union { \
6639             HV * xpadn_typestash; \
6640             CV * xpadn_protocv; \
6641             } xpadn_type_u; \
6642             U32 xpadn_low; \
6643             U32 xpadn_high; \
6644             U32 xpadn_refcnt; \
6645             int xpadn_gen; \
6646             U8 xpadn_len; \
6647             U8 xpadn_flags
6648              
6649             #ifdef PERL_PADNAME_MINIMAL
6650             #define MY_PADNAME_BASE _PADNAME_BASE
6651             #else
6652             #define MY_PADNAME_BASE struct padname xpadn_padname
6653             #endif
6654              
6655             EOF
6656 0         0  
6657 0 0       0 for my $s (sort keys %padnamesect) {
6658 0         0 if ($padnamesect{$s}->index >= 0) {
6659             print <<"EOF";
6660             struct my_padname_with_str_$s {
6661             MY_PADNAME_BASE;
6662             char xpadn_str[$s];
6663             };
6664             typedef struct my_padname_with_str_$s PADNAME_$s;
6665             EOF
6666             }
6667             }
6668             #} elsif ($PERL518) {
6669             # print "typedef PADNAME MyPADNAME;\n";
6670 0 0 0     0 }
6671 0         0 if ($PERL510 and !$PERL514) {
6672 0         0 print "typedef struct refcounted_he COPHH;\n";
6673             print <<'EOF';
6674             #define cophh_store_pvn(cophh, keypv, keylen, hash, value, flags) \
6675             Perl_refcounted_he_new(aTHX_ cophh, newSVpvn_flags(keypv, keylen, flags), value)
6676             #define cophh_store_pvs(cophh, key, value, flags) \
6677             Perl_refcounted_he_new(aTHX_ cophh, Perl_newSVpvn_flags(aTHX_ STR_WITH_LEN(key), SVs_TEMP), value)
6678             #define CopHINTHASH_set(c,h) ((c)->cop_hints_hash = (h))
6679             EOF
6680 0 0       0 }
6681 0         0 if ($B::C::Config::have_HEK_STATIC) {
6682 0         0 print "/* store full char[] to avoid excess elements in array\n";
6683 0         0 print " (HEK only declared as char[1]) */\n";
6684             print "struct hek_ptr { U32 hek_hash; I32 hek_len; char hek_key[]; };\n";
6685             }
6686             # Tricky hack for -fcog since 5.10 on !c99 compilers required. We need a char* as
6687             # *first* sv_u element to be able to statically initialize it. A int does not allow it.
6688             # gcc error: initializer element is not computable at load time
6689             # We introduce a SVPV as SV.
6690 0 0 0     0 # In core since 5.12
      0        
6691 0         0 if ($PERL510 and $] < 5.012 and !$C99) {
6692             print <<'EOT0';
6693             typedef struct svpv {
6694             void * sv_any;
6695             U32 sv_refcnt;
6696             U32 sv_flags;
6697             union {
6698             char* svu_pv;
6699             IV svu_iv;
6700             UV svu_uv;
6701             SV* svu_rv;
6702             SV** svu_array;
6703             HE** svu_hash;
6704             GP* svu_gp;
6705             } sv_u;
6706             #ifdef DEBUG_LEAKING_SCALARS
6707             PERL_BITFIELD32 sv_debug_optype:9;
6708             PERL_BITFIELD32 sv_debug_inpad:1;
6709             PERL_BITFIELD32 sv_debug_cloned:1;
6710             PERL_BITFIELD32 sv_debug_line:16;
6711             # if PERL_VERSION < 11
6712             U32 sv_debug_serial; /* 5.10 only */
6713             # endif
6714             # if PERL_VERSION > 8
6715             char * sv_debug_file;
6716             # endif
6717             #endif
6718             } SVPV;
6719             EOT0
6720              
6721 0 0       0 }
    0          
6722 0         0 if ($PERL512) {
6723             print "typedef struct p5rx RE;\n";
6724             }
6725 0         0 elsif ($PERL510) {
6726             print "typedef SV * RE;\n";
6727             }
6728 0         0 else {
6729             print "typedef char * RE;\n";
6730 0 0       0 }
6731 0         0 if ($] == 5.010000) {
6732 0         0 print "#ifndef RX_EXTFLAGS\n";
6733 0         0 print "# define RX_EXTFLAGS(rx) ((rx)->extflags)\n";
6734             print "#endif\n";
6735 0 0 0     0 }
6736 0         0 if ($] >= 5.021001 and !$CPERL52) {
6737             print "Static IV PL_sv_objcount = 0; /* deprecated with 5.21.1 but still needed and used */\n";
6738 0         0 }
6739 0 0       0 print "SV* sv;\n";
6740             print "Static GV *gv_list[$gv_index];\n" if $gv_index;
6741             }
6742              
6743 0     0 0 0 sub output_boilerplate {
6744 0 0       0 my $creator = "created at ".scalar localtime()." with B::C $B::C::VERSION ";
6745 0         0 $creator .= $B::C::REVISION if $B::C::REVISION;
6746 0         0 $creator .= " for $^X";
6747             print "/* $creator */\n";
6748 0 0 0     0 # Store the sv_list index in sv_debug_file when debugging
6749 0 0       0 print "#define DEBUG_LEAKING_SCALARS 1\n" if $debug{flags} and $DEBUG_LEAKING_SCALARS;
6750 0         0 if ($B::C::Config::have_independent_comalloc) {
6751             print <<'_EOT1';
6752             #ifdef NEED_MALLOC_283
6753             # include "malloc-2.8.3.h"
6754             #endif
6755             _EOT1
6756              
6757 0         0 }
6758             print <<'_EOT2';
6759             #define PERL_CORE
6760             #include "EXTERN.h"
6761             #include "perl.h"
6762             #include "XSUB.h"
6763              
6764             /* Workaround for mapstart: the only op which needs a different ppaddr */
6765             #undef Perl_pp_mapstart
6766             #define Perl_pp_mapstart Perl_pp_grepstart
6767             #undef OP_MAPSTART
6768             #define OP_MAPSTART OP_GREPSTART
6769              
6770             #ifdef BROKEN_STATIC_REDECL
6771             #define Static extern
6772             #else
6773             #define Static static
6774             #endif /* BROKEN_STATIC_REDECL */
6775              
6776             #ifdef BROKEN_UNION_INIT
6777             #error BROKEN_UNION_INIT no longer needed, as Perl requires an ANSI compiler
6778             #endif
6779              
6780             /* No longer available when C is defined. */
6781             #ifndef Nullsv
6782             # define Null(type) ((type)NULL)
6783             # define Nullsv Null(SV*)
6784             # define Nullhv Null(HV*)
6785             # define Nullgv Null(GV*)
6786             # define Nullop Null(OP*)
6787             #endif
6788             #ifndef GV_NOTQUAL
6789             # define GV_NOTQUAL 0
6790             #endif
6791             /* Since 5.8.8 */
6792             #ifndef Newx
6793             # define Newx(v,n,t) New(0,v,n,t)
6794             #endif
6795             /* Since 5.14 */
6796             #if !defined(PERL_STATIC_INLINE)
6797             # ifdef HAS_STATIC_INLINE
6798             # define PERL_STATIC_INLINE static inline
6799             # else
6800             # define PERL_STATIC_INLINE static
6801             # endif
6802             #endif
6803             /* cperl compat */
6804             #ifndef HEK_STATIC
6805             # define HEK_STATIC(hek) 0
6806             #endif
6807              
6808             _EOT2
6809 0 0       0  
6810 0         0 if ($] < 5.008008) {
6811             print "#define GvSVn(s) GvSV(s)\n";
6812             }
6813              
6814             # XXX boot_DynaLoader is exported only >=5.8.9
6815             # does not compile on darwin with EXTERN_C declaration
6816 0         0 # See branch `boot_DynaLoader`
6817             print <<'_EOT4';
6818              
6819             #define XS_DynaLoader_boot_DynaLoader boot_DynaLoader
6820             EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
6821              
6822             static void xs_init (pTHX);
6823             static void dl_init (pTHX);
6824             _EOT4
6825 0 0 0     0  
6826             print <<'_EOT' if $CPERL51 and $^O ne 'MSWin32';
6827             EXTERN_C void dl_boot (pTHX);
6828             _EOT
6829 0 0 0     0  
6830 0         0 if ($B::C::av_init2 and $B::C::Config::use_declare_independent_comalloc) {
6831             print "void** dlindependent_comalloc(size_t, size_t*, void**);\n";
6832 0 0       0 }
6833 0         0 if ($B::C::av_init2) {
6834 0         0 my $last = $xpvavsect->index;
6835 0 0       0 my $size = $last + 1;
6836 0         0 if ($last) {
6837 0         0 $decl->add("Static void* avchunks[$size];");
6838 0         0 $decl->add("Static size_t avsizes[$size] = ");
6839 0         0 my $ptrsize = $Config{ptrsize};
6840 0         0 my $acc = "";
6841 0 0       0 for (0..$last) {
6842 0         0 if ($xpvav_sizes[$_] > 0) {
6843             $acc .= $xpvav_sizes[$_] * $ptrsize;
6844 0         0 } else {
6845             $acc .= 3 * $ptrsize;
6846 0 0       0 }
6847 0 0       0 $acc .= "," if $_ != $last;
6848             $acc .= "\n\t" unless ($_+1) % 30;
6849 0         0 }
6850 0         0 $decl->add("\t{$acc};");
6851 0         0 $init->add_initav("if (!independent_comalloc( $size, avsizes, avchunks ))");
6852             $init->add_initav(" Perl_die(aTHX_ \"panic: AV alloc failed\");");
6853             }
6854 0 0       0 }
6855 0         0 if ( !$B::C::destruct ) {
6856             print <<'_EOT4';
6857             static int fast_perl_destruct( PerlInterpreter *my_perl );
6858             static void my_curse( pTHX_ SV* const sv );
6859              
6860             #ifndef dVAR
6861             # ifdef PERL_GLOBAL_STRUCT
6862             # define dVAR pVAR = (struct perl_vars*)PERL_GET_VARS()
6863             # else
6864             # define dVAR dNOOP
6865             # endif
6866             #endif
6867             _EOT4
6868              
6869 0         0 } else {
6870             print <<'_EOT5';
6871             int my_perl_destruct( PerlInterpreter *my_perl );
6872             _EOT5
6873              
6874 0 0       0 }
6875 0         0 if ($] < 5.008009) {
6876             print <<'_EOT3';
6877             #ifndef savesharedpvn
6878             char *savesharedpvn(const char *const s, const STRLEN len);
6879             #endif
6880             _EOT3
6881              
6882             }
6883             }
6884              
6885 0     0 0 0 sub init_op_addr {
6886 0         0 my ( $op_type, $num ) = @_;
6887             my $op_list = $op_type . "_list";
6888 0         0  
6889             $init0->add( split /\n/, <<_EOT6 );
6890             for (i = 0; i < ${num}; ++i) {
6891             ${op_list}\[i].op_ppaddr = PL_ppaddr[PTR2IV(${op_list}\[i].op_ppaddr)];
6892             }
6893             _EOT6
6894              
6895             }
6896              
6897             sub output_main_rest {
6898 0 0   0 0 0  
6899 0         0 if ( $PERL510 ) {
6900             print <<'_EOT7';
6901             /* The first assignment got already refcount bumped */
6902             PERL_STATIC_INLINE HEK *
6903             my_share_hek( pTHX_ const char *str, I32 len) {
6904             U32 hash;
6905             PERL_HASH(hash, str, abs(len));
6906             return share_hek_hek(Perl_share_hek(aTHX_ str, len, hash));
6907             }
6908              
6909             _EOT7
6910 0 0       0 }
6911 0         0 if ( $PERL510 ) {
6912             print <<'_EOT7';
6913             PERL_STATIC_INLINE HEK *
6914             my_share_hek_0( pTHX_ const char *str, I32 len) {
6915             U32 hash;
6916             PERL_HASH(hash, str, abs(len));
6917             return Perl_share_hek(aTHX_ str, len, hash);
6918             }
6919              
6920             _EOT7
6921             }
6922 0 0       0  
6923 0         0 if ($] < 5.008009) {
6924             print <<'_EOT7a';
6925             #ifndef savesharedpvn
6926             char *savesharedpvn(const char *const s, const STRLEN len) {
6927             char *const d = (char*)PerlMemShared_malloc(len + 1);
6928             if (!d) { exit(1); }
6929             d[len] = '\0';
6930             return (char *)memcpy(d, s, len);
6931             }
6932             #endif
6933             _EOT7a
6934              
6935             }
6936 0 0       0 # -fno-destruct only >=5.8
6937 0         0 if ( !$B::C::destruct ) {
6938             print <<'_EOT8';
6939              
6940             #ifndef SvDESTROYABLE
6941             #define SvDESTROYABLE(sv) 1
6942             #endif
6943             /* 5.8 */
6944             #ifndef CvISXSUB
6945             #define CvISXSUB(sv) CvXSUB(sv)
6946             #endif
6947             #ifndef SvRV_set
6948             #define SvRV_set(a,b) SvRV(a) = (b)
6949             #endif
6950             /* 5.6 */
6951             #ifndef PERL_EXIT_DESTRUCT_END
6952             #define PERL_EXIT_DESTRUCT_END 2
6953             #endif
6954              
6955             static void
6956             my_curse( pTHX_ SV* const sv ) {
6957             dSP;
6958             dVAR;
6959             HV* stash;
6960              
6961             #if PERL_VERSION > 7
6962             assert(SvOBJECT(sv));
6963             do {
6964             stash = SvSTASH(sv);
6965             assert(SvTYPE(stash) == SVt_PVHV);
6966             if (HvNAME(stash)) {
6967             CV* destructor = NULL;
6968             if (!SvOBJECT(stash)) destructor = (CV *)SvSTASH(stash);
6969             if (!destructor
6970             #if (PERL_VERSION > 18) || (PERL_VERSION == 18 && PERL_SUBVERSION > 1)
6971             || HvMROMETA(stash)->destroy_gen != PL_sub_generation
6972             #endif
6973             ) {
6974             GV * const gv = gv_fetchmeth_autoload(stash, "DESTROY", 7, 0);
6975             if (gv) {
6976             destructor = GvCV(gv);
6977             if (!SvOBJECT(stash)) {
6978             SvSTASH(stash) =
6979             destructor ? (HV *)destructor : ((HV *)0)+1;
6980             #if (PERL_VERSION > 18) || (PERL_VERSION == 18 && PERL_SUBVERSION > 1)
6981             HvAUX(stash)->xhv_mro_meta->destroy_gen = PL_sub_generation;
6982             #endif
6983             }
6984             }
6985             }
6986             assert(!destructor || destructor == ((CV *)0)+1
6987             || SvTYPE(destructor) == SVt_PVCV);
6988             if (destructor && destructor != ((CV *)0)+1
6989             /* A constant subroutine can have no side effects, so
6990             don't bother calling it. */
6991             && !CvCONST(destructor)
6992             /* Don't bother calling an empty destructor or one that
6993             returns immediately. */
6994             && (CvISXSUB(destructor)
6995             || (CvSTART(destructor)
6996             && (CvSTART(destructor)->op_next->op_type != OP_LEAVESUB)
6997             && (CvSTART(destructor)->op_next->op_type != OP_PUSHMARK
6998             || CvSTART(destructor)->op_next->op_next->op_type != OP_RETURN
6999             )
7000             ))
7001             )
7002             {
7003             SV* const tmpref = newRV(sv);
7004             DEBUG_D(PerlIO_printf(Perl_debug_log, "Calling %s::DESTROY\n", HvNAME(stash)));
7005             SvREADONLY_on(tmpref); /* DESTROY() could be naughty */
7006             ENTER;
7007             PUSHSTACKi(PERLSI_DESTROY);
7008             EXTEND(SP, 2);
7009             PUSHMARK(SP);
7010             PUSHs(tmpref);
7011             PUTBACK;
7012             call_sv((SV*)destructor, G_DISCARD|G_EVAL|G_KEEPERR|G_VOID);
7013             POPSTACK;
7014             SPAGAIN;
7015             LEAVE;
7016             if(SvREFCNT(tmpref) < 2) {
7017             /* tmpref is not kept alive! */
7018             SvREFCNT(sv)--;
7019             SvRV_set(tmpref, NULL);
7020             SvROK_off(tmpref);
7021             }
7022             SvREFCNT_dec(tmpref);
7023             }
7024             }
7025             } while (SvOBJECT(sv) && SvSTASH(sv) != stash);
7026              
7027             if (SvOBJECT(sv)) {
7028             /* Curse before freeing the stash, as freeing the stash could cause
7029             a recursive call into S_curse. */
7030             SvOBJECT_off(sv); /* Curse the object. */
7031             SvSTASH_set(sv,0); /* SvREFCNT_dec may try to read this */
7032             }
7033             #endif
7034             }
7035              
7036             static int fast_perl_destruct( PerlInterpreter *my_perl ) {
7037             dVAR;
7038             VOL signed char destruct_level; /* see possible values in intrpvar.h */
7039             HV *hv;
7040             #ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
7041             pid_t child;
7042             #endif
7043              
7044             #ifndef MULTIPLICITY
7045             # ifndef PERL_UNUSED_ARG
7046             # define PERL_UNUSED_ARG(x) ((void)x)
7047             # endif
7048             PERL_UNUSED_ARG(my_perl);
7049             #endif
7050              
7051             assert(PL_scopestack_ix == 1);
7052              
7053             /* wait for all pseudo-forked children to finish */
7054             #if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7055             PERL_WAIT_FOR_CHILDREN;
7056             #endif
7057              
7058             destruct_level = PL_perl_destruct_level;
7059             #ifdef DEBUGGING
7060             {
7061             const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
7062             if (s) {
7063             const int i = atoi(s);
7064             #ifdef DEBUGGING
7065             if (destruct_level < i) destruct_level = i;
7066             #endif
7067             #ifdef PERL_TRACK_MEMPOOL
7068             /* RT #114496, for perl_free */
7069             PL_perl_destruct_level = i;
7070             #endif
7071             }
7072             }
7073             #endif
7074              
7075             if (PL_exit_flags & PERL_EXIT_DESTRUCT_END) {
7076             dJMPENV;
7077             int x = 0;
7078              
7079             JMPENV_PUSH(x);
7080             if (PL_endav && !PL_minus_c) {
7081             #if PERL_VERSION > 13
7082             PL_phase = PERL_PHASE_END;
7083             #endif
7084             call_list(PL_scopestack_ix, PL_endav);
7085             }
7086             JMPENV_POP;
7087             }
7088             _EOT8
7089 0         0  
7090             for (0 .. $#B::C::static_free) {
7091 0         0 # set static op members to NULL
7092 0 0       0 my $s = $B::C::static_free[$_];
7093 0         0 if ($s =~ /\(OP\*\)&unopaux_list/) {
7094             print " ($s)->op_type = OP_NULL;\n";
7095             }
7096             }
7097 0         0  
7098             print <<'_EOT9';
7099             LEAVE;
7100             FREETMPS;
7101             assert(PL_scopestack_ix == 0);
7102              
7103             /* Need to flush since END blocks can produce output */
7104             my_fflush_all();
7105              
7106             PL_main_start = NULL;
7107             PL_main_cv = NULL;
7108             PL_curcop = &PL_compiling;
7109             #if PERL_VERSION >= 13
7110             PL_phase = PERL_PHASE_DESTRUCT;
7111             #endif
7112              
7113             #if PERL_VERSION > 7
7114             if (PL_threadhook(aTHX)) {
7115             /* Threads hook has vetoed further cleanup */
7116             #if (PERL_VERSION > 8) || ((PERL_VERSION == 8) && (PERL_SUBVERSION > 8))
7117             PL_veto_cleanup = TRUE;
7118             return STATUS_EXIT;
7119             #else
7120             return STATUS_NATIVE_EXPORT;
7121             #endif
7122             }
7123             #if defined(PERLIO_LAYERS)
7124             # if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7125             PerlIO_destruct(aTHX);
7126             # endif
7127             #endif
7128              
7129             /* B::C -O3 specific: first curse (i.e. call DESTROY) all our static SVs */
7130             if (PL_sv_objcount) {
7131             int i = 1;
7132             DEBUG_D(PerlIO_printf(Perl_debug_log, "\nCursing named global static sv_arena:\n"));
7133             PL_in_clean_all = 1;
7134             for (; i < SvREFCNT(&sv_list[0]); i++) {
7135             SV *sv = &sv_list[i];
7136             if (SvREFCNT(sv)) {
7137             #if PERL_VERSION > 11
7138             if (SvTYPE(sv) == SVt_IV && SvROK(sv))
7139             #else
7140             if (SvTYPE(sv) == SVt_RV)
7141             #endif
7142             sv = SvRV(sv);
7143             if (sv && SvOBJECT(sv) && SvTYPE(sv) >= SVt_PVMG && SvSTASH(sv)
7144             && SvTYPE(sv) != SVt_PVCV && SvTYPE(sv) != SVt_PVIO
7145             && PL_defstash /* Still have a symbol table? */
7146             && SvDESTROYABLE(sv))
7147             {
7148             SvREFCNT(sv) = 0;
7149             my_curse(aTHX_ sv);
7150             }
7151             }
7152             }
7153             }
7154             if (DEBUG_D_TEST) {
7155             SV* sva;
7156             PerlIO_printf(Perl_debug_log, "\n");
7157             for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) {
7158             PerlIO_printf(Perl_debug_log, "sv_arena: 0x%p - 0x%p (%lu)\n",
7159             sva, sva+SvREFCNT(sva), (long)SvREFCNT(sva));
7160             }
7161             }
7162             #endif
7163              
7164             #if PERL_VERSION > 7
7165             PL_stashcache = (HV*)&PL_sv_undef; /* sometimes corrupted */
7166             #endif
7167             #if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7168             if (PL_sv_objcount) {
7169             # if PERL_VERSION > 7
7170             PL_stashcache = newHV(); /* Hack: sometimes corrupted, holding a GV */
7171             # endif
7172             PL_in_clean_all = 1;
7173             sv_clean_objs(); /* and now curse the rest */
7174             PL_sv_objcount = 0;
7175             }
7176             #endif
7177              
7178             PL_warnhook = NULL;
7179             PL_diehook = NULL;
7180             /* call exit list functions */
7181             while (PL_exitlistlen-- > 0)
7182             PL_exitlist[PL_exitlistlen].fn(aTHX_ PL_exitlist[PL_exitlistlen].ptr);
7183             PL_exitlist = NULL;
7184              
7185             #if defined(PERLIO_LAYERS)
7186             # if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24)
7187             PerlIO_cleanup(aTHX);
7188             # endif
7189             #endif
7190              
7191             #if PERL_VERSION > 7
7192             PL_stashcache = (HV*)&PL_sv_undef;
7193             #endif
7194             /* Silence strtab refcnt warnings during global destruction */
7195             Zero(HvARRAY(PL_strtab), HvMAX(PL_strtab), HE*);
7196             /* NULL the HEK "dfs" */
7197             #if PERL_VERSION > 10
7198             PL_registered_mros = (HV*)&PL_sv_undef;
7199             CopHINTHASH_set(&PL_compiling, NULL);
7200             #endif
7201              
7202             return 0;
7203             }
7204             _EOT9
7205              
7206             }
7207             # special COW handling for 5.10 because of S_unshare_hek_or_pvn limitations
7208             # XXX This fails in S_doeval SAVEFREEOP(PL_eval_root): test 15
7209             # if ( $PERL510 and (@B::C::static_free or $free->index > -1))
7210 0         0 else {
7211             print <<'_EOT7';
7212             int my_perl_destruct( PerlInterpreter *my_perl ) {
7213             VOL signed char destruct_level = PL_perl_destruct_level;
7214             const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
7215              
7216             /* set all our static pv and hek to &PL_sv_undef for perl_destruct() */
7217             _EOT7
7218              
7219             #for (0 .. $hek_index-1) {
7220             # # TODO: non-static only, seperate data structures please
7221             # printf " memset(HEK_HE(hek%d), 0, sizeof(struct shared_he));\n", $_;
7222 0         0 #}
7223             for (0 .. $#B::C::static_free) {
7224             # set the sv/xpv to &PL_sv_undef, not the pv itself.
7225             # If set to NULL pad_undef will fail in SvPVX_const(namesv) == '&'
7226 0         0 # XXX Another idea >5.10 is SvFLAGS(pv) = SVTYPEMASK
7227 0 0       0 my $s = $B::C::static_free[$_];
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
7228 0         0 if ($s =~ /^sv_list\[\d+\]\./) { # pv directly (unused)
7229             print " $s = NULL;\n";
7230 0         0 } elsif ($s =~ /^sv_list/) {
7231 0         0 print " SvLEN(&$s) = 0;\n";
7232             print " SvPV_set(&$s, (char*)&PL_sv_undef);\n";
7233 0         0 } elsif ($s =~ /^&sv_list/) {
7234 0         0 print " SvLEN($s) = 0;\n";
7235             print " SvPV_set($s, (char*)&PL_sv_undef);\n";
7236 0         0 } elsif ($s =~ /^\(HV\*\)&sv_list/) {
7237 0         0 print " SvREADONLY_on((SV*)$s);\n";
7238             print " SvREFCNT($s) = SvREFCNT_IMMORTAL;\n";
7239             } elsif ($s =~ /^\(AV\*\)&sv_list/) { # SVs_OBJECT flag, as the HV
7240             #print " SvREADONLY_on((SV*)$s);\n";
7241             #print " SvREFCNT($s) = SvREFCNT_IMMORTAL;\n";
7242 0         0 } elsif ($s =~ /^&padnamelist_list/) {
7243 0         0 print " Safefree(PadnamelistARRAY($s));\n";
7244 0         0 print " PadnamelistMAX($s) = 0;\n";
7245             print " PadnamelistREFCNT($s) = 0;\n";
7246 0         0 } elsif ($s =~ /^&padname(_\d+)?_list/) {
7247             print " PadnameREFCNT($s) = 0;\n";
7248             # dead code ---
7249 0 0 0     0 } elsif ($s =~ /^cop_list/) {
7250 0         0 if ($ITHREADS or !$MULTI) {
7251             print " CopFILE_set(&$s, NULL);";
7252 0 0 0     0 }
    0 0        
    0          
7253 0         0 if ($] >= 5.017) {
7254             print " CopSTASH_set(&$s, NULL);\n";
7255 0         0 } elsif ($] < 5.016 and $ITHREADS) {
7256             print " CopSTASHPV(&$s) = NULL;\n";
7257 0         0 } elsif ($] < 5.016 and !$ITHREADS) {
7258             print " CopSTASH(&$s) = NULL;\n";
7259 0         0 } else { # 5.16 experiment
7260             print " CopSTASHPV_set(&$s, NULL, 0);\n";
7261             }
7262 0         0 } elsif ($s =~ /\(OP\*\)&unopaux_list/) {
7263             print " ($s)->op_type = OP_NULL;\n";
7264             # end dead code ---
7265             #} elsif ($s =~ /^pv\d/) {
7266             # print " $s = \"\";\n";
7267 0         0 } elsif ($s ne 'ptr_undef') {
7268             warn("unknown $s at \@static_free[$_]");
7269             }
7270 0         0 }
7271             $free->output( \*STDOUT, "%s\n" );
7272 0         0  
7273 0 0       0 my $riter_type = "I32";
7274 0 0       0 if ($CPERL51) {
7275             $riter_type = $CPERL55 ? "U32" : "SSize_t";
7276 0         0 }
7277 0 0       0 my $hvmax_type = "STRLEN";
7278 0 0       0 if ($CPERL51) {
7279             $hvmax_type = $CPERL55 ? "U32" : "SSize_t";
7280 0         0 }
7281 0         0 print "#define RITER_T $riter_type\n";
7282             print "#define HVMAX_T $hvmax_type\n";
7283 0         0  
7284             print <<'_EOT7a';
7285              
7286             /* Avoid Unbalanced string table refcount warning with PERL_DESTRUCT_LEVEL=2 */
7287             if (s) {
7288             const int i = atoi(s);
7289             if (destruct_level < i) destruct_level = i;
7290             }
7291             if (destruct_level >= 1) {
7292             const HVMAX_T max = HvMAX(PL_strtab);
7293             HE * const * const array = HvARRAY(PL_strtab);
7294             RITER_T riter = 0;
7295             HE *hent = array[0];
7296             for (;;) {
7297             if (hent) {
7298             HE * const next = HeNEXT(hent);
7299             if (!HEK_STATIC(&((struct shared_he*)hent)->shared_he_hek))
7300             Safefree(hent);
7301             hent = next;
7302             }
7303             if (!hent) {
7304             if (++riter > max)
7305             break;
7306             hent = array[riter];
7307             }
7308             }
7309             /* Silence strtab refcnt warnings during global destruction */
7310             Zero(HvARRAY(PL_strtab), max, HE*);
7311             /* NULL the HEK "dfs" */
7312             #if PERL_VERSION > 10
7313             PL_registered_mros = (HV*)&PL_sv_undef;
7314             CopHINTHASH_set(&PL_compiling, NULL);
7315             #endif
7316             }
7317              
7318             /* B::C specific: prepend static svs to arena for sv_clean_objs */
7319             SvANY(&sv_list[0]) = (void *)PL_sv_arenaroot;
7320             PL_sv_arenaroot = &sv_list[0];
7321             #if PERL_VERSION > 7
7322             if (DEBUG_D_TEST) {
7323             SV* sva;
7324             PerlIO_printf(Perl_debug_log, "\n");
7325             for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) {
7326             PerlIO_printf(Perl_debug_log, "sv_arena: 0x%p - 0x%p (%lu)\n",
7327             sva, sva+SvREFCNT(sva), (long)SvREFCNT(sva));
7328             }
7329             }
7330              
7331             return perl_destruct( my_perl );
7332             #else
7333             perl_destruct( my_perl );
7334             return 0;
7335             #endif
7336             }
7337             _EOT7a
7338             }
7339 0         0  
7340             print <<'_EOT8';
7341              
7342             /* yanked from perl.c */
7343             static void
7344             xs_init(pTHX)
7345             {
7346             char *file = __FILE__;
7347             dTARG; dSP; CV * cv;
7348 0 0 0     0 _EOT8
7349 0         0 if ($CPERL51 and $debug{cv}) {
7350             print q{
7351             /* -DC set dl_debug to 3 */
7352             SV* sv = get_svs("DynaLoader::dl_debug", GV_ADD);
7353             sv_upgrade(sv, SVt_IV);
7354             SvIV_set(sv, 3);};
7355             }
7356             #if ($staticxs) { #FIXME!
7357             # print "\n#undef USE_DYNAMIC_LOADING
7358             #}
7359 0         0  
7360 0         0 delete $xsub{'DynaLoader'};
7361 0         0 delete $xsub{'UNIVERSAL'};
7362 0         0 print("/* XS bootstrapping code*/\n");
7363 0         0 print("\tSAVETMPS;\n");
7364 0         0 print("\ttarg=sv_newmortal();\n");
7365 0         0 foreach my $stashname ( sort keys %static_ext ) {
7366 0         0 my $stashxsub = $stashname;
7367             $stashxsub =~ s/::/__/g;
7368             #if ($stashxsub =~ m/\/(\w+)\.\w+$/ {$stashxsub = $1;}
7369 0 0       0 # cygwin has Win32CORE in static_ext
7370 0         0 warn "bootstrapping static $stashname added to xs_init\n" if $verbose;
7371             print "\tnewXS(\"$stashname\::bootstrap\", boot_$stashxsub, file);\n";
7372 0         0 }
7373 0         0 print "#ifdef USE_DYNAMIC_LOADING\n";
7374 0         0 print "\tPUSHMARK(sp);\n";
7375 0         0 printf "\tXPUSHp(\"DynaLoader\", %d);\n", length("DynaLoader");
7376 0 0       0 print "\tPUTBACK;\n";
7377 0         0 warn "bootstrapping DynaLoader added to xs_init\n" if $verbose;
7378 0         0 print "\tcv = newXS(\"DynaLoader::boot_DynaLoader\", boot_DynaLoader, file);\n";
7379 0         0 print "\tboot_DynaLoader(aTHX_ cv);\n";
7380 0 0 0     0 print "\tSPAGAIN;\n";
7381 0         0 if ($CPERL51 and $^O ne 'MSWin32') {
7382             print "\tdl_boot(aTHX);\n";
7383 0         0 }
7384             print "#endif\n";
7385              
7386 0         0 # my %core = map{$_ => 1} core_packages();
7387 0         0 foreach my $stashname ( sort keys %xsub ) {
7388 0 0       0 my $incpack = inc_packname($stashname);
7389 0 0       0 unless (exists $curINC{$incpack}) { # skip deleted packages
7390 0         0 warn "skip xs_init for $stashname !\$INC{$incpack}\n" if $debug{pkg};
7391 0 0       0 delete $include_package{$stashname};
7392 0         0 delete $xsub{$stashname} unless $static_ext{$stashname};
7393             next;
7394 0 0 0     0 }
7395 0         0 if ( $xsub{$stashname} !~ m/^Dynamic/ and !$static_ext{$stashname}) {
7396 0 0       0 my $stashxsub = $stashname;
7397 0         0 warn "bootstrapping $stashname added to xs_init\n" if $verbose;
7398 0         0 $stashxsub =~ s/::/__/g;
7399 0         0 print "\tPUSHMARK(sp);\n";
7400             printf "\tXPUSHp(\"%s\", %d);\n", # "::bootstrap" gets appended, TODO
7401 0         0 0 ? "strdup($stashname)" : $stashname, length($stashname);
7402 0         0 print "\tPUTBACK;\n";
7403 0         0 print "\tboot_$stashxsub(aTHX_ NULL);\n";
7404             print "\tSPAGAIN;\n";
7405             }
7406 0         0 }
7407 0         0 print "\tFREETMPS;\n/* end XS bootstrapping code */\n";
7408             print "}\n\n";
7409 0         0  
7410 0         0 my ($dl, $xs);
7411 0 0       0 my @dl_modules = @DynaLoader::dl_modules;
7412 0         0 my @PERLMODS = split(/\,/, $ENV{'PERLMODS'}) if $ENV{'PERLMODS'}; # from cpanel
7413 0         0 foreach my $perlmod (@PERLMODS) {
7414 0 0       0 warn "Extra module ${perlmod}\n";
  0         0  
7415             push @dl_modules, $perlmod unless grep { $_ ne $perlmod } @dl_modules;
7416             }
7417 0         0 # filter out unused dynaloaded B modules, used within the compiler only.
7418 0 0 0     0 for my $c (qw(B B::C)) {
7419             if (!$xsub{$c} and !$include_package{$c}) {
7420 0 0 0     0 # (hopefully, see test 103)
7421             warn "no dl_init for $c, not marked\n" if $verbose and !$skip_package{$c};
7422 0         0 # RT81332 pollute
  0         0  
7423             @dl_modules = grep { $_ ne $c } @dl_modules;
7424             # XXX Be sure to store the new @dl_modules
7425             }
7426 0         0 }
7427 0 0 0     0 for my $c (sort keys %skip_package) {
7428 0         0 warn "no dl_init for $c, skipped\n" if $verbose and $xsub{$c};
7429 0         0 delete $xsub{$c};
7430 0         0 $include_package{$c} = undef;
  0         0  
7431             @dl_modules = grep { $_ ne $c } @dl_modules;
7432 0         0 }
7433 0 0       0 @DynaLoader::dl_modules = @dl_modules;
7434 0         0 warn "\@dl_modules: ",join(" ",@dl_modules),"\n" if $verbose;
7435 0         0 foreach my $stashname (@dl_modules) {
7436             my $incpack = inc_packname($stashname);
7437             #unless (exists $INC{$incpack}) { # skip deleted packages
7438             # warn "XXX skip dl_init for $stashname !\$INC{$incpack}\n" if $debug{pkg};
7439             # delete $xsub{$stashname};
7440             # @dl_modules = grep { $_ ne $stashname } @dl_modules;
7441 0 0 0     0 #}
7442 0         0 if ($stashname eq 'attributes' and $] > 5.011) {
7443             $xsub{$stashname} = 'Dynamic-' . $INC{'attributes.pm'};
7444             }
7445 0 0 0     0 # actually boot all non-b-c dependent modules here. we assume XSLoader (Moose, List::MoreUtils)
7446 0         0 if (!exists( $xsub{$stashname} ) and $include_package{$stashname}) {
7447             $xsub{$stashname} = 'Dynamic-' . $INC{$incpack};
7448 0 0       0 # Class::MOP without Moose: find Moose.pm
7449 0 0       0 $xsub{$stashname} = 'Dynamic-' . $savINC{$incpack} unless $INC{$incpack};
7450 0         0 if (!$savINC{$incpack}) {
7451 0         0 eval "require $stashname;";
7452             $xsub{$stashname} = 'Dynamic-' . $INC{$incpack};
7453 0 0       0 }
7454             warn "Assuming xs loaded $stashname with $xsub{$stashname}\n" if $verbose;
7455 0 0 0     0 }
7456             if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic/ ) {
7457             # XSLoader.pm: $modlibname = (caller())[1]; needs a path at caller[1] to find auto,
7458 0 0       0 # otherwise we only have -e
7459 0         0 $xs++ if $xsub{$stashname} ne 'Dynamic';
7460             $dl++;
7461 0         0 }
7462 0         0 my $stashxsub = $stashname;
7463 0 0 0     0 $stashxsub =~ s/::/__/g;
      0        
      0        
7464             if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic-/
7465 0         0 and ($PERL522 or $staticxs)) {
7466             print "EXTERN_C void boot_$stashxsub(pTHX_ CV* cv);\n";
7467             }
7468 0 0 0     0 }
7469             warn "\%xsub: ",join(" ",sort keys %xsub),"\n" if $verbose and $debug{cv};
7470 0 0 0     0 # XXX Adding DynaLoader is too late here! The sections like $init are already dumped (#125)
    0 0        
7471 0         0 if ($dl and ! $curINC{'DynaLoader.pm'}) {
7472             die "Error: DynaLoader required but not dumped. Too late to add it.\n";
7473 0         0 } elsif ($xs and ! $curINC{'XSLoader.pm'}) {
7474             die "Error: XSLoader required but not dumped. Too late to add it.\n";
7475 0         0 }
7476             print <<'_EOT9';
7477              
7478             static void
7479             dl_init(pTHX)
7480             {
7481             char *file = __FILE__;
7482             _EOT9
7483 0 0       0  
7484             if ($dl) {
7485             # enforce attributes at the front of dl_init, #259
7486 0         0 # also Encode should be booted before PerlIO::encoding
7487 0 0       0 for my $front (qw(Encode attributes)) {
  0         0  
7488 0         0 if (grep { $_ eq $front } @dl_modules) {
  0         0  
7489 0         0 @dl_modules = grep { $_ ne $front } @dl_modules;
7490             unshift @dl_modules, $front;
7491             }
7492 0 0       0 }
  0 0       0  
7493 0         0 if ($staticxs) {open( XS, ">", $outfile.".lst" ) or return "$outfile.lst: $!\n"}
7494 0         0 print "\tdTARG; dSP;\n";
7495 0         0 print "/* DynaLoader bootstrapping */\n";
7496 0 0       0 print "\tENTER;\n";
7497 0 0       0 print "\t++cxstack_ix; cxstack[cxstack_ix].blk_oldcop = PL_curcop;\n" if $xs;
7498 0         0 print "\t/* assert(cxstack_ix == 0); */\n" if $xs;
7499 0 0       0 print "\tSAVETMPS;\n";
7500             print "\ttarg = sv_newmortal();\n" if $] < 5.008008;
7501 0 0 0     0  
  0         0  
7502             if (exists $xsub{"Coro::State"} and grep { $_ eq "Coro::State" } @dl_modules) {
7503             # Coro readonly symbols in BOOT (#293)
7504 0         0 # needed before dl_init, and after init
7505 0         0 print "\t{\n\t GV *sym;\n";
7506 0         0 for my $s (qw(Coro Coro::API Coro::current)) {
7507 0         0 print "\t sym = gv_fetchpv(\"$s\",0,SVt_PV);\n";
7508             print "\t if (sym && GvSVn(sym)) SvREADONLY_off(GvSVn(sym));\n";
7509 0         0 }
7510 0         0 print "\t sym = gv_fetchpv(\"Coro::pool_handler)\",0,SVt_PVCV);\n";
7511 0         0 print "\t if (sym && GvCV(sym)) SvREADONLY_off(GvCV(sym));\n";
7512             print "\t}\n";
7513 0 0 0     0 }
  0         0  
7514             if (exists $xsub{"EV"} and grep { $_ eq "EV" } @dl_modules) {
7515 0         0 # EV readonly symbols in BOOT (#368)
7516 0         0 print "\t{\n\t GV *sym;\n";
7517 0         0 for my $s (qw(EV::API)) {
7518 0         0 print "\t sym = gv_fetchpv(\"$s\",0,SVt_PV);\n";
7519             print "\t if (sym && GvSVn(sym)) SvREADONLY_off(GvSVn(sym));\n";
7520 0         0 }
7521             print "\t}\n";
7522 0         0 }
7523 0 0 0     0 foreach my $stashname (@dl_modules) {
7524 0         0 if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic/ ) {
7525 0         0 $use_xsloader = 1;
7526             print "\n\tPUSHMARK(sp);\n";
7527 0 0       0 # XXX -O1 or -O2 needs XPUSHs with dynamic pv
7528             printf "\t%s(%s, %d);\n", # "::bootstrap" gets appended
7529 0 0       0 $] < 5.008008 ? "XPUSHp" : "mXPUSHp", "\"$stashname\"", length($stashname);
7530 55     55   939 if ( $xsub{$stashname} eq 'Dynamic' ) {
  55         150  
  55         31222  
7531 0 0       0 no strict 'refs';
7532             warn "dl_init $stashname\n" if $verbose;
7533 0         0 # just in case we missed it. DynaLoader really needs the @ISA (#308)
  0         0  
7534 0         0 B::svref_2object( \@{$stashname."::ISA"} ) ->save;
7535 0         0 print "#ifndef STATICXS\n";
7536 0         0 print "\tPUTBACK;\n";
7537             print qq/\tcall_method("DynaLoader::bootstrap_inherit", G_VOID|G_DISCARD);\n/;
7538             }
7539 0         0 else { # XS: need to fix cx for caller[1] to find auto/...
7540 0         0 my ($stashfile) = $xsub{$stashname} =~ /^Dynamic-(.+)$/;
7541 0 0 0     0 print "#ifndef STATICXS\n";
7542 0 0       0 if ($] >= 5.015003 and $stashfile) {
7543 0         0 if ($CPERL51) {
7544             my $sofile;
7545 0         0 # search stashname in loaded sofiles
7546 0         0 my @modparts = split(/::/,$stashname);
7547 0         0 my $modfname = $modparts[-1];
7548 0         0 my $modpname = join('/',@modparts);
7549             my $needle = "auto/$modpname/$modfname\\.".$Config{dlext};
7550             #warn " load_file: @DynaLoader::dl_shared_objects";
7551 0         0 #warn " sofile?: $needle";
7552 0 0       0 for (@DynaLoader::dl_shared_objects) {
7553             if (m{$needle}) {
7554 0         0 #warn " load_file: found $_";
  0         0  
7555             $sofile = $_; last;
7556             }
7557 0 0       0 }
7558 0         0 unless ($sofile) {
7559 0         0 my $modlibname = $stashfile;
7560 0 0 0     0 my $c = scalar @modparts;
7561 0         0 if ($stashname eq 'Cwd' and $stashfile !~ /Cwd/) {
7562 0         0 warn "load_file: fixup Cwd vs $stashfile";
7563             $c = 3;
7564 0         0 }
7565 0         0 $modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename
7566             $sofile = "$modlibname/auto/$modpname/$modfname.".$Config{dlext};
7567             }
7568 0         0 #warn "load_file: $stashname, $stashfile, $sofile";
7569             $stashfile = $sofile;
7570 0         0 }
7571 0         0 my $stashfile_len = length($stashfile);
7572 0         0 $stashfile =~ s/(\\[^nrftacx"' ])/\\$1/g; # windows paths: \\ => \\\\
7573             printf "\tmXPUSHp(\"%s\", %d);\n", $stashfile, $stashfile_len;
7574 0         0 }
7575 0 0       0 print "\tPUTBACK;\n";
7576             warn "bootstrapping $stashname added to XSLoader dl_init\n" if $verbose;
7577             # XSLoader has the 2nd insanest API in whole Perl, right after make_warnings_object()
7578 0 0       0 # 5.15.3 workaround for [perl #101336]
7579 55     55   1659 if ($] >= 5.015003) {
  55         164  
  55         103466  
7580 0 0       0 no strict 'refs';
7581 0         0 unless (grep /^DynaLoader$/, get_isa($stashname)) {
  0         0  
7582 0         0 push @{$stashname."::ISA"}, 'DynaLoader';
  0         0  
7583             svref_2object( \@{$stashname."::ISA"} ) ->save;
7584 0 0       0 }
  0         0  
7585             warn '@',$stashname,"::ISA=(",join(",",@{$stashname."::ISA"}),")\n" if $debug{gv};
7586 0         0 # TODO #364: if a VERSION was provided need to add it here
7587             print qq/\tcall_pv("XSLoader::load_file", G_VOID|G_DISCARD);\n/;
7588 0 0       0 } else {
7589             printf qq/\tCopFILE_set(cxstack[cxstack_ix].blk_oldcop, "%s");\n/,
7590             $stashfile if $stashfile;
7591 0         0 # TODO #364: if a VERSION was provided need to add it here
7592             print qq/\tcall_pv("XSLoader::load", G_VOID|G_DISCARD);\n/;
7593             }
7594 0 0       0 }
7595 0         0 if ($staticxs) {
7596 0         0 my ($laststash) = $stashname =~ /::([^:]+)$/;
7597 0         0 my $path = $stashname;
7598 0 0       0 $path =~ s/::/\//g;
7599 0 0       0 $path .= "/" if $path; # can be empty
7600 0         0 $laststash = $stashname unless $laststash; # without ::
7601             my $sofile = "auto/" . $path . $laststash . '\.' . $Config{dlext};
7602             #warn "staticxs search $sofile in @DynaLoader::dl_shared_objects\n"
7603 0         0 # if $verbose and $debug{pkg};
7604 0 0       0 for (@DynaLoader::dl_shared_objects) {
7605 0         0 if (m{^(.+/)$sofile$}) {
7606 0 0       0 print XS $stashname,"\t",$_,"\n";
7607 0         0 warn "staticxs $stashname\t$_\n" if $verbose;
7608 0         0 $sofile = '';
7609             last;
7610             }
7611 0 0       0 }
7612 0 0 0     0 print XS $stashname,"\n" if $sofile; # error case
7613             warn "staticxs $stashname\t - $sofile not loaded\n" if $sofile and $verbose;
7614 0         0 }
7615 0         0 print "#else\n";
7616 0         0 print "\tPUTBACK;\n";
7617 0         0 my $stashxsub = $stashname;
7618 0 0 0     0 $stashxsub =~ s/::/__/g;
7619             if ($PERL522 or $staticxs) {
7620             # CvSTASH(CvGV(cv)) is invalid without (issue 86)
7621 0 0 0     0 # TODO: utf8 stashname (does make sense when loading from the fs?)
7622 0         0 if ($PERL522 and $staticxs) { # GH 333
7623             print "\t{
7624             CV* cv = (CV*)SvREFCNT_inc_simple_NN(get_cv(\"$stashname\::bootstrap\", GV_ADD));
7625             CvISXSUB_on(cv); /* otherwise a perl assertion fails. */
7626             cv->sv_any->xcv_padlist_u.xcv_hscxt = &PL_stack_sp; /* xs_handshake */
7627             boot_$stashxsub(aTHX_ cv);
7628             }\n";
7629 0         0 } else {
7630             print "\tboot_$stashxsub(aTHX_ get_cv(\"$stashname\::bootstrap\", GV_ADD));\n";
7631             }
7632 0         0 } else {
7633             print "\tboot_$stashxsub(aTHX_ NULL);\n";
7634 0         0 }
7635 0         0 print "#endif\n";
7636             print "\tSPAGAIN;\n";
7637             #print "\tPUTBACK;\n";
7638             } else {
7639 0 0       0 warn "no dl_init for $stashname, ".
    0          
7640             (!$xsub{$stashname} ? "not bootstrapped\n" : "bootstrapped as $xsub{$stashname}\n")
7641             if $verbose;
7642             # XXX Too late. This might fool run-time DynaLoading.
7643 0         0 # We really should remove this via init from @DynaLoader::dl_modules
  0         0  
7644             @DynaLoader::dl_modules = grep { $_ ne $stashname } @DynaLoader::dl_modules;
7645              
7646             }
7647 0         0 }
7648 0 0       0 print "\tFREETMPS;\n";
7649 0         0 print "\tcxstack_ix--;\n" if $xs; # i.e. POPBLOCK
7650 0         0 print "\tLEAVE;\n";
7651 0 0       0 print "/* end DynaLoader bootstrapping */\n";
7652             close XS if $staticxs;
7653 0         0 }
7654             print "}\n";
7655             }
7656              
7657 0 0   0 0 0 sub output_main {
7658 0         0 if (!defined($module)) {
7659             print <<'_EOT10';
7660              
7661             /* if USE_IMPLICIT_SYS, we need a 'real' exit */
7662             #if defined(exit)
7663             #undef exit
7664             #endif
7665              
7666             int
7667             main(int argc, char **argv, char **env)
7668             {
7669             int exitstatus;
7670             int i;
7671             char **fakeargv;
7672             int options_count;
7673             PerlInterpreter *my_perl;
7674              
7675             PERL_SYS_INIT3(&argc,&argv,&env);
7676              
7677             #ifdef WIN32
7678             #define PL_do_undump 0
7679             #endif
7680             if (!PL_do_undump) {
7681             my_perl = perl_alloc();
7682             if (!my_perl)
7683             exit(1);
7684             perl_construct( my_perl );
7685             PL_perl_destruct_level = 0;
7686             }
7687 0 0 0     0 _EOT10
7688             if ($ITHREADS and $] > 5.007) {
7689 0         0 # XXX init free elems!
7690 0         0 my $pad_len = regex_padav->FILL; # first is an empty avref
7691             print <<_EOT11;
7692             #ifdef USE_ITHREADS
7693             if (!*PL_regex_pad) {
7694             /* Someone is overwriting regex_pad since 5.15, but not on -fno-warnings */
7695             PL_regex_padav = newAV();
7696             #if PERL_VERSION > 10
7697             av_push(PL_regex_padav, newSVpvs("")); /* First entry is empty */
7698             #else
7699             av_push(PL_regex_padav, newSViv(0));
7700             #endif
7701             PL_regex_pad = AvARRAY(PL_regex_padav);
7702             }
7703             for( i = 0; i < $pad_len; ++i ) {
7704             av_push( PL_regex_padav, newSViv(0) );
7705             }
7706             PL_regex_pad = AvARRAY( PL_regex_padav );
7707             #endif
7708             _EOT11
7709              
7710 0 0       0 }
7711 0 0       0 print " PL_exit_flags |= PERL_EXIT_DESTRUCT_END;\n" unless $PERL56;
7712 0         0 if ($] >= 5.008009) {
7713             print <<'_SAFE_PUTENV';
7714             #ifndef PERL_USE_SAFE_PUTENV
7715             PL_use_safe_putenv = 0;
7716             #endif
7717             _SAFE_PUTENV
7718 0 0       0 }
7719 0         0 if (!$PERL510) {
7720             print <<'_EOT12';
7721             #if defined(CSH)
7722             if (!PL_cshlen)
7723             PL_cshlen = strlen(PL_cshname);
7724             #endif
7725             _EOT12
7726             }
7727              
7728 0         0 # XXX With -e "" we need to fake parse_body() scriptname = BIT_BUCKET
7729             print <<'_EOT13';
7730             #ifdef ALLOW_PERL_OPTIONS
7731             #define EXTRA_OPTIONS 3
7732             #else
7733             #define EXTRA_OPTIONS 4
7734             #endif /* ALLOW_PERL_OPTIONS */
7735             Newx(fakeargv, argc + EXTRA_OPTIONS + 1, char *);
7736             fakeargv[0] = argv[0];
7737             fakeargv[1] = "-e";
7738             fakeargv[2] = "";
7739             options_count = 3;
7740             _EOT13
7741              
7742 0 0 0     0 # honour -T
7743 0         0 if (!$PERL56 and ${^TAINT}) {
7744             print <<'_EOT14';
7745             fakeargv[options_count] = "-T";
7746             ++options_count;
7747             _EOT14
7748              
7749 0         0 }
7750             print <<'_EOT15';
7751             #ifndef ALLOW_PERL_OPTIONS
7752             fakeargv[options_count] = "--";
7753             ++options_count;
7754             #endif /* ALLOW_PERL_OPTIONS */
7755             for (i = 1; i < argc; i++)
7756             fakeargv[i + options_count - 1] = argv[i];
7757             fakeargv[argc + options_count - 1] = 0;
7758              
7759             exitstatus = perl_parse(my_perl, xs_init, argc + options_count - 1,
7760             fakeargv, env);
7761             if (exitstatus)
7762             exit( exitstatus );
7763              
7764             TAINT;
7765             _EOT15
7766 0 0       0  
7767 0         0 if ($use_perl_script_name) {
7768 0         0 my $dollar_0 = cstring($0);
7769 0         0 print sprintf(qq{ sv_setpv_mg(get_svs("0", GV_ADD|GV_NOTQUAL), %s);\n}, $dollar_0);
7770             print sprintf(qq{ CopFILE_set(&PL_compiling, %s);\n}, $dollar_0);
7771             }
7772             else {
7773 0         0 #print q{ warn("PL_origalen=%d\n", PL_origalen);},"\n";
7774 0         0 print qq{ sv_setpv_mg(get_svs("0", GV_ADD|GV_NOTQUAL), argv[0]);\n};
7775             print qq{ CopFILE_set(&PL_compiling, argv[0]);\n};
7776             }
7777 0 0       0 # more global vars
7778 0 0       0 print " PL_hints = $^H;\n" if $^H;
7779             print " PL_unicode = ${^UNICODE};\n" if ${^UNICODE};
7780             # system-specific needs to be skipped: is set during init_i18nl10n if PerlIO
7781             # is compiled in and on a utf8 locale.
7782             #print " PL_utf8locale = ${^UTF8LOCALE};\n" if ${^UTF8LOCALE};
7783             #print " PL_utf8cache = ${^UTF8CACHE};\n" if ${^UTF8CACHE};
7784 0 0       0 # nomg
7785 0 0       0 print sprintf(qq{ sv_setpv(get_svs(";", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($;)) if $; ne "\34";
7786             print sprintf(qq{ sv_setpv(get_svs("\\"", GV_NOTQUAL), %s); /* \$" */\n}, cstring($")) if $" ne " ";
7787 0 0       0 # global IO vars
7788 0 0       0 if ($PERL56) {
7789 0 0       0 print sprintf(qq{ PL_ofs = %s; PL_ofslen = %u; /* \$, */\n}, cstring($,), length $,) if $,;
7790             print sprintf(qq{ PL_ors = %s; PL_orslen = %u; /* \$\\ */\n}, cstring($\), length $\) if $\;
7791 0 0       0 } else {
7792 0 0       0 print sprintf(qq{ sv_setpv_mg(GvSVn(PL_ofsgv), %s); /* \$, */\n}, cstring($,)) if $,;
7793             print sprintf(qq{ sv_setpv_mg(get_svs("\\\\", GV_ADD|GV_NOTQUAL), %s); /* \$\\ */\n}, cstring($\)) if $\; #ORS
7794 0 0       0 }
7795 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs("/", GV_NOTQUAL), %s);\n}, cstring($/)) if $/ ne "\n"; #RS
7796             print qq{ sv_setiv_mg(get_svs("|", GV_ADD|GV_NOTQUAL), $|);\n} if $|; #OUTPUT_AUTOFLUSH
7797 0 0       0 # global format vars
7798 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs("^A", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($^A)) if $^A; #ACCUMULATOR
7799 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
7800 0 0       0 print sprintf(qq{ sv_setpv_mg(get_svs(":", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($:)) if $: ne " \n-"; #LINE_BREAK_CHARACTERS
7801             print sprintf(qq/ sv_setpv_mg(get_svs("^", GV_ADD|GV_NOTQUAL), savepvn(%s, %u));\n/, cstring($^), length($^))
7802 0 0       0 if $^ ne "STDOUT_TOP";
7803             print sprintf(qq/ sv_setpv_mg(get_svs("~", GV_ADD|GV_NOTQUAL), savepvn(%s, %u));\n/, cstring($~), length($~))
7804 0 0       0 if $~ ne "STDOUT";
7805 0 0 0     0 print qq{ sv_setiv_mg(get_svs("%", GV_ADD|GV_NOTQUAL), $%);\n} if $%; #PAGE_NUMBER
7806 0 0       0 print qq{ sv_setiv_mg(get_svs("-", GV_ADD|GV_NOTQUAL), $-);\n} unless ($- == 0 or $- == 60); #LINES_LEFT
7807             print qq{ sv_setiv_mg(get_svs("=", GV_ADD|GV_NOTQUAL), $=);\n} if $= != 60; #LINES_PER_PAGE
7808              
7809 55 0   55   57091 # deprecated global vars
  55         18347  
  55         87867  
  0         0  
7810 0 0       0 print qq{ {SV* s = get_svs("[",GV_NOTQUAL); sv_setiv(s, $[); mg_set(s);}\n} if $[; #ARRAY_BASE
7811 0         0 if ($] < 5.010) { # OFMT and multiline matching
7812             eval q[
7813             print sprintf(qq{ sv_setpv(GvSVn(gv_fetchpv("\$#", GV_ADD|GV_NOTQUAL, SVt_PV)), %s);\n},
7814             cstring($#)) if $#;
7815             print sprintf(qq{ sv_setiv(GvSVn(gv_fetchpv("\$*", GV_ADD|GV_NOTQUAL, SVt_IV)), %d);\n}, $*) if $*;
7816             ];
7817             }
7818 0         0  
7819 0         0 print sprintf(qq{ sv_setpv_mg(get_svs("\030", GV_ADD|GV_NOTQUAL), %s); /* \$^X */\n}, cstring($^X));
7820             print <<"EOT";
7821             TAINT_NOT;
7822              
7823             #if PERL_VERSION < 10 || ((PERL_VERSION == 10) && (PERL_SUBVERSION < 1))
7824             PL_compcv = 0;
7825             #else
7826             PL_compcv = MUTABLE_CV(newSV_type(SVt_PVCV));
7827             CvUNIQUE_on(PL_compcv);
7828             CvPADLIST(PL_compcv) = pad_new(0);
7829             #endif
7830              
7831             /* our special compiled init */
7832             perl_init(aTHX);
7833 0 0       0 EOT
7834 0 0       0 print " perl_init1(aTHX);\n" if $init1->index >= 0;
7835 0 0       0 print " dl_init(aTHX);\n" unless defined $module;
7836 0         0 print " perl_init2(aTHX);\n" if $init2->index >= 0;
7837 0         0 print "\n exitstatus = perl_run( my_perl );\n";
  0         0  
7838 0         0 foreach my $s ( @{ $init->[-1]{pre_destruct} } ) {
7839             print " ".$s."\n";
7840             }
7841 0 0       0  
7842 0 0       0 if ( !$B::C::destruct ) {
7843 0         0 warn "fast_perl_destruct (-fno-destruct)\n" if $verbose;
7844             print " fast_perl_destruct( my_perl );\n";
7845             #} elsif ( $PERL510 and (@B::C::static_free or $free->index > -1) ) {
7846             # warn "my_perl_destruct static strings\n" if $verbose;
7847             # print " my_perl_destruct( my_perl );\n";
7848             #} elsif ( $] >= 5.007003 ) {
7849             # print " perl_destruct( my_perl );\n";
7850             }
7851 0         0 else {
7852             print " my_perl_destruct( my_perl );\n";
7853             }
7854             # XXX endav is called via call_list and so it is freed right after usage. Setting dirty here is useless
7855 0         0 #print " PL_dirty = 1;\n" unless $B::C::pv_copy_on_grow; # protect against pad undef in END block
7856             print <<'EOT1';
7857             perl_free( my_perl );
7858              
7859             PERL_SYS_TERM();
7860              
7861             exit( exitstatus );
7862             }
7863             EOT1
7864              
7865             } # module
7866             }
7867              
7868             sub dump_symtable {
7869 0     0 0 0 # For debugging
7870 0         0 my ( $sym, $val );
7871             warn "----Symbol table:\n";
7872 0         0 #while ( ( $sym, $val ) = each %symtable )
7873 0         0 for $sym (sort keys %symtable) {
7874 0         0 $val = $symtable{$sym};
7875             warn "$sym => $val\n";
7876 0         0 }
7877             warn "---End of symbol table\n";
7878             }
7879              
7880 0     0 0 0 sub save_object {
7881 0         0 my $sv;
7882 0         0 foreach $sv (@_) {
7883             svref_2object($sv)->save;
7884             }
7885             }
7886       0 0    
7887             sub Dummy_BootStrap { }
7888              
7889       0     #ignore nullified cv
7890             sub B::SPECIAL::savecv {}
7891              
7892 0     0   0 sub B::GV::savecv {
7893 0         0 my $gv = shift;
7894 0         0 my $package = $gv->STASH->NAME;
7895 0         0 my $name = $gv->NAME;
7896 0         0 my $cv = $gv->CV;
7897 0         0 my $sv = $gv->SV;
7898 0         0 my $av = $gv->AV;
7899             my $hv = $gv->HV;
7900 0         0  
7901             my $fullname = $package . "::" . $name;
7902 0 0 0     0 warn sprintf( "Checking GV *%s 0x%x\n", cstring($fullname), $$gv )
7903             if $debug{gv} and $verbose;
7904             # We may be looking at this package just because it is a branch in the
7905             # symbol table which is on the path to a package which we need to save
7906             # e.g. this is 'Getopt' and we need to save 'Getopt::Long'
7907 0 0 0     0 #
7908 0 0 0     0 return if ( $package ne 'main' and !$include_package{$package} );
7909             return if ( $package eq 'main' and
7910             $name =~ /^([^\w].*|_\<.*|INC|ARGV|SIG|ENV|BEGIN|main::|!)$/ );
7911 0 0       0  
7912 0 0 0     0 warn sprintf( "Used GV \*$fullname 0x%x\n", $$gv ) if $debug{gv};
      0        
      0        
      0        
      0        
7913 0 0 0     0 return unless ( $$cv || $$av || $$sv || $$hv || $gv->IO || $gv->FORM );
      0        
7914             if ($$cv and $name eq 'bootstrap' and $cv->XSUB) {
7915 0 0       0 #return $cv->save($fullname);
7916 0         0 warn sprintf( "Skip XS \&$fullname 0x%x\n", $$cv ) if $debug{gv};
7917             return;
7918 0 0 0     0 }
      0        
      0        
7919             if ( $$cv and in_static_core($package, $name) and ref($cv) eq 'B::CV' # 5.8,4 issue32
7920 0 0       0 and $cv->XSUB ) {
7921             warn("Skip internal XS $fullname\n") if $debug{gv};
7922 0 0       0 # but prevent it from being deleted
7923             unless ($dumped_package{$package}) {
7924 0         0 #$dumped_package{$package} = 1;
7925             mark_package($package, 1);
7926 0         0 }
7927             return;
7928 0 0       0 }
7929 0 0       0 if ($package eq 'B::C') {
7930 0         0 warn sprintf( "Skip XS \&$fullname 0x%x\n", $$cv ) if $debug{gv};
7931             return;
7932 0 0       0 }
7933 0         0 if ($fullname =~ /^(bytes|utf8)::AUTOLOAD$/) {
7934             $gv = force_heavy($package);
7935             }
7936 0 0 0     0 # XXX fails and should not be needed. The B::C part should be skipped 9 lines above, but be defensive
7937             return if $fullname eq 'B::walksymtable' or $fullname eq 'B::C::walksymtable';
7938             # Config is marked on any Config symbol. TIE and DESTROY are exceptions,
7939 0 0       0 # used by the compiler itself
7940 0 0       0 if ($name eq 'Config') {
7941             mark_package('Config', 1) if !$include_package{'Config'};
7942 0 0 0     0 }
7943 0 0       0 $dumped_package{$package} = 1 if !exists $dumped_package{$package} and $package !~ /::$/;
7944 0         0 warn sprintf( "Saving GV \*$fullname 0x%x\n", $$gv ) if $debug{gv};
7945             $gv->save($fullname);
7946             }
7947              
7948             # Fixes bug #307: use foreach, not each
7949             # each is not safe to use (at all). walksymtable is called recursively which might add
7950             # symbols to the stash, which might cause re-ordered rehashes, which will fool the hash
7951             # iterator, leading to missing symbols in the binary.
7952             # Old perl5 bug: The iterator should really be stored in the op, not the hash.
7953 0     0 0 0 sub walksymtable {
7954 0         0 my ($symref, $method, $recurse, $prefix) = @_;
7955 0 0       0 my ($sym, $ref, $fullname);
7956             $prefix = '' unless defined $prefix;
7957              
7958             # If load_utf8_heavy doesn't happen before we walk utf8::
7959             # (when utf8_heavy has already been called) then the stored CV for utf8::S
7960 0 0 0     0 # WASHNEW could be wrong.
7961             load_utf8_heavy() if ( $prefix eq 'utf8::' && defined $symref->{'SWASHNEW'} );
7962              
7963             my @list = sort {
7964             # we want these symbols to be saved last to avoid incomplete saves
7965             # +/- reverse is to defer + - to fix Tie::Hash::NamedCapturespecial cases. GH #247
7966 0         0 # _loose_name redefined from utf8_heavy.pl GH #364
  0         0  
7967 0 0       0 foreach my $v (qw{- + utf8:: bytes::}) {
7968 0 0       0 $a eq $v and return 1;
7969             $b eq $v and return -1;
7970             }
7971 0         0 # reverse order for now to preserve original behavior before improved patch
7972             $b cmp $a
7973             } keys %$symref;
7974 0         0  
7975 55     55   751 foreach my $sym ( @list ) {
  55         166  
  55         11484  
7976 0         0 no strict 'refs';
7977 0         0 $ref = $symref->{$sym};
7978 0 0       0 $fullname = "*main::".$prefix.$sym;
7979 0         0 if ($sym =~ /::$/) {
7980 0 0 0     0 $sym = $prefix . $sym;
      0        
7981 0         0 if (svref_2object(\*$sym)->NAME ne "main::" && $sym ne "::" && &$recurse($sym)) {
7982             walksymtable(\%$fullname, $method, $recurse, $sym);
7983             }
7984 0         0 } else {
7985             svref_2object(\*$fullname)->$method();
7986             }
7987             }
7988             }
7989              
7990 0     0 0 0 sub walk_syms {
7991 55     55   470 my $package = shift;
  55         139  
  55         9034  
7992 0 0       0 no strict 'refs';
7993 0 0 0     0 return if $dumped_package{$package};
7994 0         0 warn "walk_syms $package\n" if $debug{pkg} and $verbose;
7995 0     0   0 $dumped_package{$package} = 1;
  0         0  
  0         0  
7996             walksymtable( \%{$package.'::'}, "savecv", sub { 1 }, $package.'::' );
7997             }
7998              
7999             # simplified walk_syms
8000             # needed to populate @B::C::Config::deps from Makefile.PL from within this %INC context
8001 0     0 0 0 sub walk_stashes {
8002 55     55   439 my ($symref, $prefix) = @_;
  55         151  
  55         22393  
8003 0 0       0 no strict 'refs';
8004 0         0 $prefix = '' unless defined $prefix;
8005 0 0       0 foreach my $sym ( sort keys %$symref ) {
8006 0         0 if ($sym =~ /::$/) {
8007 0         0 $sym = $prefix . $sym;
8008 0 0 0     0 $B::C::deps{ substr($sym,0,-2) }++;
8009 0         0 if ($sym ne "main::" && $sym ne "::") {
8010             walk_stashes(\%$sym, $sym);
8011             }
8012             }
8013             }
8014             }
8015              
8016 0     0 0 0 sub collect_deps {
8017 0         0 %B::C::deps = ();
8018 0         0 walk_stashes(\%main::);
8019             print join " ",(sort keys %B::C::deps);
8020             }
8021              
8022 0     0 0 0 sub mark_package {
8023 0         0 my $package = shift;
8024 0 0       0 my $force = shift;
8025 0 0       0 $force = 0 if $] < 5.010;
8026 0 0 0     0 return if skip_pkg($package); # or $package =~ /^B::C(C?)::/;
8027 55     55   498 if ( !$include_package{$package} or $force ) {
  55         152  
  55         21601  
8028 0 0 0     0 no strict 'refs';
8029 0         0 warn "mark_package($package, $force)\n" if $verbose and $debug{pkg};
8030 0 0       0 my @IO = qw(IO::File IO::Handle IO::Socket IO::Seekable IO::Poll);
  0         0  
8031 0 0       0 mark_package('IO') if grep { $package eq $_ } @IO;
8032 0 0       0 mark_package("DynaLoader") if $package eq 'XSLoader';
8033             $use_xsloader = 1 if $package =~ /^B|Carp$/; # to help CC a bit (49)
8034 0 0 0     0 # i.e. if force
      0        
8035             if (exists $include_package{$package}
8036             and !$include_package{$package}
8037             and $savINC{inc_packname($package)})
8038 0 0       0 {
    0          
8039             warn sprintf("$package previously deleted, save now%s\n",
8040             $force?" (forced)":"") if $verbose;
8041 0         0 # $include_package{$package} = 1;
8042 0         0 add_hashINC( $package );
8043             walk_syms( $package );
8044             } else {
8045 0 0 0     0 warn sprintf("mark $package%s\n", $force?" (forced)":"")
    0 0        
8046 0         0 if !$include_package{$package} and $verbose and $debug{pkg};
8047 0 0       0 $include_package{$package} = 1;
8048 0 0       0 push_package($package) if $] < 5.010;
8049             walk_syms( $package ) if !$B::C::walkall; # fixes i27-1
8050 0         0 }
8051 0 0       0 my @isa = get_isa($package);
8052             if ( @isa ) {
8053             # XXX walking the ISA is often not enough.
8054 0         0 # we should really check all new packages since the last full scan.
8055 0 0       0 foreach my $isa ( @isa ) {
8056 0 0       0 next if $isa eq $package;
8057 0 0       0 if ( $isa eq 'DynaLoader' ) {
  0         0  
8058 0 0       0 unless ( defined( &{ $package . '::bootstrap' } ) ) {
8059 0         0 warn "Forcing bootstrap of $package\n" if $verbose;
  0         0  
8060             eval { $package->bootstrap };
8061             }
8062 0 0 0     0 }
8063 55     55   440 if ( !$include_package{$isa} and !$skip_package{$isa} ) {
  55         146  
  55         51416  
8064 0 0       0 no strict 'refs';
8065 0         0 warn "$isa saved (it is in $package\'s \@ISA)\n" if $verbose;
  0         0  
8066 0 0       0 B::svref_2object( \@{$isa."::ISA"} ) ->save; #308
8067 0 0       0 if (exists $include_package{$isa} ) {
8068 0         0 warn "$isa previously deleted, save now\n" if $verbose; # e.g. Sub::Name
8069 0         0 mark_package($isa);
8070             walk_syms($isa); # avoid deep recursion
8071             } else {
8072 0         0 #warn "isa $isa save\n" if $verbose;
8073             mark_package($isa);
8074             }
8075             }
8076             }
8077             }
8078 0         0 }
8079             return 1;
8080             }
8081              
8082             # XS in CORE which do not need to be bootstrapped extra.
8083             # There are some specials like mro,re,UNIVERSAL.
8084 0     0 0 0 sub in_static_core {
8085 0 0       0 my ($stashname, $cvname) = @_;
8086 0         0 if ($stashname eq 'UNIVERSAL') {
8087             return $cvname =~ /^(isa|can|DOES|VERSION)$/;
8088 0 0       0 }
  0         0  
8089             %static_core_pkg = map {$_ => 1} static_core_packages()
8090 0 0       0 unless %static_core_pkg;
8091 0 0       0 return 1 if $static_core_pkg{$stashname};
8092 0         0 if ($stashname eq 'mro') {
8093             return $cvname eq 'method_changed_in';
8094 0 0       0 }
8095 0         0 if ($stashname eq 're') {
8096             return $cvname =~ /^(is_regexp|regname|regnames|regnames_count|regexp_pattern)$/;;
8097 0 0       0 }
8098 0         0 if ($stashname eq 'PerlIO') {
8099             return $cvname eq 'get_layers';
8100 0 0       0 }
8101 0         0 if ($stashname eq 'PerlIO::Layer') {
8102             return $cvname =~ /^(find|NoWarnings)$/;
8103 0         0 }
8104             return 0;
8105             }
8106              
8107             # XS modules in CORE. Reserved namespaces.
8108             # Note: mro,re,UNIVERSAL have both, static core and dynamic/static XS
8109             # version has an external ::vxs
8110 0     0 0 0 sub static_core_packages {
8111 0 0       0 my @pkg = qw(Internals utf8 UNIVERSAL);
8112 0 0       0 push @pkg, qw(strict coretypes DynaLoader XSLoader) if $CPERL51;
8113 0 0       0 push @pkg, 'attributes' if $] < 5.011; # partially static and dynamic
8114 0 0       0 push @pkg, 'version' if $] >= 5.010; # partially static and dynamic
8115             push @pkg, 'Tie::Hash::NamedCapture' if !$PERL514; # dynamic since 5.14
8116             #push @pkg, 'DynaLoader' if $Config{usedl};
8117             # Win32CORE only in official cygwin pkg. And it needs to be bootstrapped,
8118 0 0       0 # handled by static_ext.
8119 0 0       0 push @pkg, 'Cygwin' if $^O eq 'cygwin';
8120 0 0       0 push @pkg, 'NetWare' if $^O eq 'NetWare';
8121 0 0       0 push @pkg, 'OS2' if $^O eq 'os2';
8122             push @pkg, qw(VMS VMS::Filespec vmsish) if $^O eq 'VMS';
8123 0         0 #push @pkg, 'PerlIO' if $] >= 5.008006; # get_layers only
8124 0         0 push @pkg, split(/ /,$Config{static_ext});
8125             return @pkg;
8126             }
8127              
8128 0     0 0 0 sub skip_pkg {
8129 0 0 0     0 my $package = shift;
      0        
      0        
      0        
      0        
      0        
      0        
      0        
8130             if ( $package =~ /^(main::)?(Internals|O)::/
8131             #or $package =~ /::::/ # CORE/base/lex.t 54
8132             or $package =~ /^B::C::/
8133             or $package eq '__ANON__'
8134             or index($package, " ") != -1 # XXX skip invalid package names
8135             or index($package, "(") != -1 # XXX this causes the compiler to abort
8136             or index($package, ")") != -1 # XXX this causes the compiler to abort
8137             or exists $skip_package{$package}
8138 0         0 or ($DB::deep and $package =~ /^(DB|Term::ReadLine)/)) {
8139             return 1;
8140 0         0 }
8141             return 0;
8142             }
8143              
8144             # Do not delete/ignore packages which were brought in from the script,
8145             # i.e. not defined in B::C or O. Just to be on the safe side.
8146 0     0 0 0 sub can_delete {
8147 0 0 0     0 my $pkg = shift;
  0         0  
8148 0         0 if (exists $all_bc_deps{$pkg} and $B::C::can_delete_pkg) { return 1 };
8149             return undef;
8150             }
8151              
8152 55     55   557 sub should_save {
  55         168  
  55         30369  
8153 0     0 0 0 no strict qw(vars refs);
8154 0         0 my $package = shift;
8155 0 0       0 $package =~ s/::$//;
8156 0 0       0 if ( skip_pkg($package) ) {
8157 0         0 delete_unsaved_hashINC($package) if can_delete($package);
8158             return 0;
8159 0 0       0 }
8160             return $include_package{$package} = 0
8161 0 0       0 if ( $package =~ /::::/ ); # skip ::::ISA::CACHE etc.
8162 0 0       0 warn "Considering $package\n" if $debug{pkg}; #$include_package{$package}
8163 0 0       0 return if index($package, " ") != -1; # XXX skip invalid package names
8164 0 0       0 return if index($package, "(") != -1; # XXX this causes the compiler to abort
8165             return if index($package, ")") != -1; # XXX this causes the compiler to abort
8166 0 0       0 # core static mro has exactly one member, ext/mro has more
8167             if ($package eq 'mro') {
8168 0 0       0 # B::C is setting %mro:: to 3, make sure we have at least 10
8169 0 0       0 if (!is_using_mro()) { # core or ext?
8170 0         0 warn "ext/mro not loaded - skip\n" if $debug{pkg};
8171             return;
8172 0 0       0 } else {
8173             warn "ext/mro already loaded\n" if $debug{pkg};
8174 0         0 # $include_package{mro} = 1 if grep { $_ eq 'mro' } @DynaLoader::dl_modules;
8175             return $include_package{mro};
8176             }
8177 0 0 0     0 }
      0        
8178 0         0 if ($package eq 'attributes' and $] > 5.011
8179             and grep { $_ eq 'attributes' } @DynaLoader::dl_modules)
8180 0         0 {
8181 0         0 mark_package($package, 1);
8182             return 1;
8183 0 0       0 }
8184 0         0 if (exists $all_bc_deps{$package}) {
8185             foreach my $u ( grep( $include_package{$_}, sort keys %include_package ) ) {
8186             # If this package is a prefix to something we are saving, traverse it
8187             # but do not mark it for saving if it is not already
8188 0         0 # e.g. to get to B::OP we need to traverse B:: but need not save B
8189 0         0 my $p = $package;
8190 0 0 0     0 $p =~ s/(\W)/\\$1/g;
8191             return 1 if ( $u =~ /^$p\:\:/ ) && $include_package{$package};
8192             }
8193             }
8194 0         0 # Needed since 5.12.2: Check already if deleted
8195 0 0 0     0 my $incpack = inc_packname($package);
      0        
      0        
8196             if ( $] > 5.015001 and exists $all_bc_deps{$package}
8197 0         0 and !exists $curINC{$incpack} and $savINC{$incpack} ) {
8198 0 0       0 $include_package{$package} = 0;
8199 0         0 warn "Cached $package not in \%INC, already deleted (early)\n" if $debug{pkg};
8200             return 0;
8201             }
8202 0 0 0     0 # issue348: only drop B::C packages, not any from user code.
      0        
8203             if (($package =~ /^DynaLoader|XSLoader$/ and $use_xsloader)
8204 0         0 or (!exists $all_bc_deps{$package})) {
8205             $include_package{$package} = 1;
8206             }
8207 0 0       0 # If this package is in the same file as main:: or our source, save it. (72, 73)
8208             if ($mainfile) {
8209 55     55   456 # Find the first cv in this package for CV->FILE
  55         185  
  55         79045  
8210 0         0 no strict 'refs';
  0         0  
8211 0 0       0 for my $sym (sort keys %{$package.'::'}) {
  0         0  
8212             if (defined &{$package.'::'.$sym}) {
8213 0         0 # compare cv->FILE to $mainfile
  0         0  
8214 0 0 0     0 my $cv = svref_2object(\&{$package.'::'.$sym});
      0        
8215 0 0       0 if ($cv and $cv->can('FILE') and $cv->FILE) {
8216 0         0 $include_package{$package} = 1 if $mainfile eq $cv->FILE;
8217             last;
8218             }
8219             }
8220             }
8221             }
8222 0 0 0     0 # add overloaded but otherwise empty packages (#172)
  0   0     0  
  0         0  
8223 0         0 if ($savINC{'overload.pm'} and exists ${$package.'::'}{OVERLOAD} and exists ${$package.'::'}{'()'}) {
8224 0         0 mark_package($package, 1);
8225 0         0 mark_package('overload', 1);
8226             return 1;
8227             }
8228             # Omit the packages which we use (and which cause grief
8229             # because of fancy "goto &$AUTOLOAD" stuff).
8230 0 0       0 # XXX Surely there must be a nicer way to do this.
8231 0 0       0 if ( exists $include_package{$package} ) {
    0          
8232 0         0 if (! exists $all_bc_deps{$package}) {
8233 0         0 $include_package{$package} = 1;
8234 0 0       0 $curINC{$incpack} = $savINC{$incpack};
8235             warn "Cached new $package is kept\n" if $debug{pkg};
8236             }
8237 0 0       0 elsif (!$include_package{$package}) {
8238 0 0       0 delete_unsaved_hashINC($package) if can_delete($package);
8239             warn "Cached $package is already deleted\n" if $debug{pkg};
8240 0 0       0 } else {
8241             warn "Cached $package is cached\n" if $debug{pkg};
8242 0         0 }
8243             return $include_package{$package};
8244             }
8245              
8246 0 0       0 # Now see if current package looks like an OO class. This is probably too strong.
8247 0         0 if (!$all_bc_deps{$package}) {
8248             foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE)) {
8249             # 5.10 introduced version and Regexp::DESTROY, which we dont want automatically.
8250             # XXX TODO This logic here is wrong and unstable. Fixes lead to more failures.
8251 0 0 0     0 # The walker deserves a rewrite.
8252 0 0 0     0 if ( UNIVERSAL::can( $package, $m ) and $package !~ /^(B::C|version|Regexp|utf8|SelectSaver)$/ ) {
8253             next if $package eq 'utf8' and $m eq 'DESTROY'; # utf8::DESTROY is empty
8254             # we load Errno by ourself to avoid double Config warnings [perl #]
8255 0 0 0     0 # and we have special logic to detect and include it
8256             next if $package =~ /^(Errno|Tie::Hash::NamedCapture)$/ and $m eq 'TIEHASH';
8257 0 0 0     0 # XXX Config and FileHandle should not just return. If unneeded skip em.
8258             return 0 if $package eq 'Config' and $m =~ /DESTROY|TIEHASH/; # Config detected in GV
8259 0 0 0     0 # IO::File|IO::Handle added for B::CC only
8260 0 0       0 return 0 if $package =~ /^(FileHandle|IO::File|IO::Handle)/ and $m eq 'new';
8261 0         0 warn "$package has method $m: saving package\n" if $debug{pkg};
8262             return mark_package($package);
8263             }
8264             }
8265 0 0 0     0 }
8266 0         0 if ($package !~ /^PerlIO/ and can_delete($package)) {
8267             delete_unsaved_hashINC($package);
8268 0 0       0 }
    0          
8269 0 0       0 if (can_delete($package)) {
8270 0         0 warn "Delete $package\n" if $debug{pkg};
8271             return $include_package{$package} = 0;
8272 0 0       0 } elsif (! exists $all_bc_deps{$package}) { # and not in @deps
8273 0         0 warn "Keep $package\n" if $debug{pkg};
8274             return $include_package{$package} = 1;
8275             } else { # in @deps
8276 0         0 # warn "Ignore $package\n" if $debug{pkg};
8277             return;
8278             }
8279             }
8280              
8281 225     225 0 347 sub inc_packname {
8282             my $package = shift;
8283 225         790 # See below at the reverse packname_inc: utf8 => utf8.pm + utf8_heavy.pl
8284 225         409 $package =~ s/\:\:/\//g;
8285 225         436 $package .= '.pm';
8286             return $package;
8287             }
8288              
8289 0     0 0 0 sub packname_inc {
8290 0         0 my $package = shift;
8291 0 0       0 $package =~ s/\//::/g;
8292 0         0 if ($package =~ /^(Config_git\.pl|Config_heavy.pl)$/) {
8293             return 'Config';
8294 0 0       0 }
8295 0         0 if ($package eq 'utf8_heavy.pl') {
8296             return 'utf8';
8297 0         0 }
8298 0         0 $package =~ s/\.p[lm]$//;
8299             return $package;
8300             }
8301              
8302 225     225 0 345 sub delete_unsaved_hashINC {
8303 225         387 my $package = shift;
8304             my $incpack = inc_packname($package);
8305 225 50       516 # Not already saved package, so it is not loaded again at run-time.
8306             return if $dumped_package{$package};
8307 225 0 33     798 # Never delete external packages, but this check is done before
      33        
8308             return if $package =~ /^DynaLoader|XSLoader$/
8309             and defined $use_xsloader
8310 225 50 33     645 and $use_xsloader == 0;
8311 225         513 return if $^O eq 'MSWin32' and $package =~ /^Carp|File::Basename$/;
8312 225 50       499 $include_package{$package} = 0;
8313             if ($curINC{$incpack}) {
8314 0 0       0 #warn "Deleting $package from \%INC\n" if $debug{pkg};
8315 0         0 $savINC{$incpack} = $curINC{$incpack} if !$savINC{$incpack};
8316 0         0 $curINC{$incpack} = undef;
8317             delete $curINC{$incpack};
8318             }
8319             }
8320              
8321 0     0 0 0 sub add_hashINC {
8322 0         0 my $package = shift;
8323 0         0 my $incpack = inc_packname($package);
8324 0 0       0 $include_package{$package} = 1;
8325 0 0       0 unless ($curINC{$incpack}) {
8326 0 0       0 if ($savINC{$incpack}) {
8327 0         0 warn "Adding $package to \%INC (again)\n" if $debug{pkg};
8328             $curINC{$incpack} = $savINC{$incpack};
8329 0 0       0 # need to check xsub
8330             $use_xsloader = 1 if $package =~ /^DynaLoader|XSLoader$/;
8331 0 0       0 } else {
8332 0         0 warn "Adding $package to \%INC\n" if $debug{pkg};
8333 0         0 for (@INC) {
8334 0 0       0 my $p = $_.'/'.$incpack;
  0         0  
  0         0  
8335             if (-e $p) { $curINC{$incpack} = $p; last; }
8336 0 0       0 }
8337             $curINC{$incpack} = $incpack unless $curINC{$incpack};
8338             }
8339             }
8340             }
8341              
8342 0     0 0 0 sub walkpackages {
8343 55     55   530 my ( $symref, $recurse, $prefix ) = @_;
  55         146  
  55         13920  
8344 0 0       0 no strict 'vars';
8345             $prefix = '' unless defined $prefix;
8346 0 0       0 # check if already deleted - failed since 5.15.2
8347 0         0 return if $savINC{inc_packname(substr($prefix,0,-2))};
8348 0         0 for my $sym (sort keys %$symref) {
8349 0 0       0 my $ref = $symref->{$sym};
8350 0         0 next unless $ref;
8351 0         0 local (*glob);
8352 0 0       0 *glob = $ref;
8353 0         0 if ( $sym =~ /::$/ ) {
8354 0 0 0     0 $sym = $prefix . $sym;
8355             warn("Walkpackages $sym\n") if $debug{pkg} and $debug{walk};
8356             # This walker skips main subs to avoid recursion into O compiler subs again
8357 0 0 0     0 # and main syms are already handled
      0        
8358 0         0 if ( $sym ne "main::" && $sym ne "::" && &$recurse($sym) ) {
8359             walkpackages( \%glob, $recurse, $sym );
8360             }
8361             }
8362             }
8363             }
8364              
8365 55     55   460 sub save_unused_subs {
  55         145  
  55         136407  
8366 0     0 0 0 no strict qw(refs);
8367 0 0       0 my %sav_debug;
8368 0         0 if ( $debug{unused} ) {
8369 0         0 %sav_debug = %debug;
8370             %debug = ();
8371 0 0       0 }
8372             my $main = $module ? $module."::" : "main::";
8373              
8374             # -fwalkall: better strategy for compile-time added and required packages:
8375             # loop savecv and check pkg cache for new pkgs.
8376 0         0 # if so loop again with those new pkgs only, until the list of new pkgs is empty
8377             my ($walkall_cnt, @init_unused, @unused, @dumped) = (0);
8378 0         0 #do
  0         0  
8379 0 0       0 @init_unused = grep { $include_package{$_} } keys %include_package;
8380 0 0       0 if ($verbose) {
8381             warn "Prescan for unused subs in $main " . ($sav_debug{unused} ? " (silent)\n" : "\n");
8382             }
8383             # XXX TODO better strategy for compile-time added and required packages:
8384             # loop savecv and check pkg cache for new pkgs.
8385 0         0 # if so loop again with those new pkgs only, until the list of new pkgs is empty
8386 0 0       0 descend_marked_unused();
  0         0  
8387 0 0       0 walkpackages( \%{$main}, \&should_save, $main eq 'main::' ? undef : $main );
    0          
8388             warn "Saving unused subs in $main" . ($sav_debug{unused} ? " (silent)\n" : "\n")
8389 0         0 if $verbose;
  0         0  
8390 0         0 walksymtable( \%{$main}, "savecv", \&should_save );
  0         0  
8391 0 0       0 @unused = grep { $include_package{$_} } keys %include_package;
  0         0  
8392 0 0       0 @dumped = grep { $dumped_package{$_} and $_ ne 'main' } keys %dumped_package;
8393             warn sprintf("old unused: %d, new: %d, dumped: %d\n", scalar @init_unused, scalar @unused, scalar @dumped)
8394 0 0       0 if $verbose;
8395 0         0 if (!$B::C::walkall) {
8396             @unused = @init_unused = ();
8397 0         0 } else {
8398 0   0     0 my $done;
8399 0         0 do {
8400 0         0 $done = dump_rest();
  0         0  
8401 0 0       0 @unused = grep { $include_package{$_} } keys %include_package;
  0         0  
8402             @dumped = grep { $dumped_package{$_} and $_ ne 'main' } keys %dumped_package;
8403 0 0       0 } while @unused > @dumped and $done;
8404             last if $walkall_cnt++ > 3;
8405             }
8406             #} while @unused > @init_unused;
8407 0 0       0  
8408 0         0 if ( $sav_debug{unused} ) {
8409             %debug = %sav_debug;
8410             }
8411              
8412             # If any m//i is run-time loaded we'll get a "Undefined subroutine utf8::SWASHNEW"
8413             # With -fno-fold we don't insist on loading utf8_heavy and Carp.
8414 0 0 0     0 # Until it is compile-time required.
      0        
      0        
      0        
      0        
8415             if (exists($INC{'unicore/To/Title.pl'})
8416             or exists($INC{'unicore/To/Tc.pl'}) #242
8417             or exists($INC{'unicore/Heavy.pl'}) #242
8418 0 0       0 or ($savINC{'utf8_heavy.pl'} and ($B::C::fold or exists($savINC{'utf8.pm'})))) {
8419 0         0 require "utf8.pm" unless $savINC{"utf8.pm"};
8420 0         0 mark_package('utf8');
8421             load_utf8_heavy();
8422             }
8423             # run-time Carp
8424             # With -fno-warnings we don't insist on initializing warnings::register_categories and Carp.
8425             # Until it is compile-time required.
8426 0 0 0     0 # 68KB exe size 32-bit
      0        
8427 0         0 if ($] >= 5.013005 and ($B::C::warnings and exists $dumped_package{Carp})) {
  0         0  
8428 0         0 svref_2object( \&{"warnings\::register_categories"} )->save; # 68Kb 32bit
8429 0         0 add_hashINC("warnings");
8430             add_hashINC("warnings::register");
8431             }
8432 0 0 0     0 #196 missing INIT
      0        
8433 0         0 if ($xsub{EV} and $dumped_package{EV} and $EV::VERSION le '4.21') {
8434             $init2->add_eval
8435             (
8436             q(EV::default_loop() or )
8437             .q(die 'EV: cannot initialise libev backend. bad $ENV{LIBEV_FLAGS}?';)
8438             );
8439 0 0       0 }
8440 0         0 if ($use_xsloader) {
8441 0         0 force_saving_xsloader();
8442             mark_package('Config', 1); # required by Dynaloader and special cased previously
8443             }
8444             }
8445              
8446 0     0 0 0 sub inc_cleanup {
8447             my $rec_cnt = shift;
8448             # %INC sanity check issue 89:
8449 0         0 # omit unused, unsaved packages, so that at least run-time require will pull them in.
8450 0 0       0 my @deleted_inc;
8451 0         0 if ($CPERL51) {
8452 0         0 for (qw(strict coretypes DynaLoader XSLoader)) {
8453 0         0 $dumped_package{$_}++;
8454             $curINC{$_.".pm"} = $INC{$_.".pm"};
8455             }
8456 0         0 }
8457 0         0 for my $package (sort keys %INC) {
8458 0 0 0     0 my $pkg = packname_inc($package);
    0 0        
    0 0        
8459 0         0 if ($package =~ /^(Config_git\.pl|Config_heavy.pl)$/ and !$dumped_package{'Config'}) {
8460             delete $curINC{$package};
8461 0         0 } elsif ($package eq 'utf8_heavy.pl' and !$include_package{'utf8'}) {
8462 0         0 delete $curINC{$package};
8463             delete_unsaved_hashINC('utf8');
8464 0         0 } elsif (!$B::C::walkall and !exists $dumped_package{$pkg}) {
8465 0         0 delete_unsaved_hashINC($pkg);
8466             push @deleted_inc, $pkg;
8467             }
8468             }
8469 0         0 # sync %curINC deletions back to %INC
8470 0 0       0 for my $p (sort keys %INC) {
8471 0         0 if (!exists $curINC{$p}) {
8472 0         0 delete $INC{$p};
8473             push @deleted_inc, $p;
8474             }
8475 0 0 0     0 }
8476 0         0 if ($debug{pkg} and $verbose) {
  0         0  
8477 0         0 warn "\%include_package: ".join(" ",grep{$include_package{$_}} sort keys %include_package)."\n";
  0         0  
8478             warn "\%dumped_package: ".join(" ",grep{$dumped_package{$_}} sort keys %dumped_package)."\n";
8479             }
8480             # issue 340,350: do only on -fwalkall? do it in the main walker step
8481 0 0       0 # as in branch walkall-early?
8482 0         0 if ($B::C::walkall) {
8483 0 0 0     0 my $again = dump_rest();
8484             inc_cleanup($rec_cnt++) if $again and $rec_cnt < 2; # maximal 3 times
8485             }
8486 0         0 # final cleanup
8487 0         0 for my $p (sort keys %INC) {
8488 0 0       0 my $pkg = packname_inc($p);
8489             delete_unsaved_hashINC($pkg) unless exists $dumped_package{$pkg};
8490 0 0 0     0 # sync %curINC deletions back to %INC
8491 0         0 if (!exists $curINC{$p} and exists $INC{$p}) {
8492 0         0 delete $INC{$p};
8493             push @deleted_inc, $p;
8494             }
8495 0 0 0     0 }
8496 0 0       0 if ($debug{pkg} and $verbose) {
8497 0         0 warn "Deleted from \%INC: ".join(" ",@deleted_inc)."\n" if @deleted_inc;
8498 0         0 my @inc = grep !/auto\/.+\.(al|ix)$/, sort keys %INC;
8499             warn "\%INC: ".join(" ",@inc)."\n";
8500             }
8501             }
8502              
8503 0     0 0 0 sub dump_rest {
8504 0 0 0     0 my $again;
8505             warn "dump_rest:\n" if $verbose or $debug{pkg};
8506             #for my $p (sort keys %INC) {
8507 0         0 #}
8508 0         0 for my $p (sort keys %include_package) {
8509 0 0 0     0 $p =~ s/^main:://;
      0        
      0        
8510             if ($include_package{$p} and !exists $dumped_package{$p}
8511             and !$static_core_pkg{$p}
8512             and $p !~ /^(threads|main|__ANON__|PerlIO)$/
8513             )
8514 0 0 0     0 {
8515 0         0 if ($p eq 'warnings::register' and !$B::C::warnings) {
8516 0         0 delete_unsaved_hashINC('warnings::register');
8517             next;
8518 0         0 }
8519 0 0 0     0 $again++;
8520             warn "$p marked but not saved, save now\n" if $verbose or $debug{pkg};
8521             # mark_package( $p, 1);
8522             #eval {
8523             # require(inc_packname($p)) && add_hashINC( $p );
8524 0         0 #} unless $savINC{inc_packname($p)};
8525             walk_syms( $p );
8526             }
8527 0         0 }
8528             $again;
8529             }
8530              
8531             my @made_c3;
8532              
8533 0 0   0 0 0 sub make_c3 {
8534             my $package = shift or die;
8535 0 0       0  
  0         0  
8536 0         0 return if ( grep { $_ eq $package } @made_c3 );
8537             push @made_c3, $package;
8538 0         0  
8539 0         0 mark_package( 'mro', 1 );
8540 0   0     0 mark_package($package);
8541 0         0 my $isa_packages = mro::get_linear_isa($package) || [];
8542 0         0 foreach my $isa (@$isa_packages) {
8543             mark_package($isa);
8544 0 0 0     0 }
8545             warn "set c3 for $package\n" if $verbose or $debug{pkg};
8546              
8547             ## from setmro.xs:
8548             # classname = ST(0);
8549             # class_stash = gv_stashsv(classname, GV_ADD);
8550             # meta = HvMROMETA(class_stash);
8551             # Perl_mro_set_mro(aTHX_ meta, ST(1));
8552 0         0  
8553             $init2->add( sprintf( 'Perl_mro_set_mro(aTHX_ HvMROMETA(%s), newSVpvs("c3"));',
8554             savestashpv($package) ) );
8555             }
8556              
8557             # global state only, unneeded for modules
8558             sub save_context {
8559 0 0   0 0 0 # forbid run-time extends of curpad syms, names and INC
8560 0         0 warn "save context:\n" if $verbose;
8561 0 0       0 my $warner = $SIG{__WARN__};
8562             save_sig($warner) if $B::C::save_sig;
8563 0         0 # honour -w and %^H
8564             $init->add( "/* honor -w */",
8565 0 0       0 sprintf "PL_dowarn = ( %s ) ? G_WARN_ON : G_WARN_OFF;", $^W );
8566             if ($^{TAINT}) {
8567             $init->add( "/* honor -Tt */",
8568             "PL_tainting = TRUE;",
8569 0 0       0 # -T -1 false, -t 1 true
8570             "PL_taint_warn = ".($^{TAINT} < 0 ? "FALSE" : "TRUE").";");
8571             }
8572 0 0       0  
8573             if ($PERL510) {
8574 0 0 0     0 # need to mark assign c3 to %main::. no need to assign the default dfs
8575 0         0 if (is_using_mro() && mro::get_mro("main") eq 'c3') {
8576             make_c3('main');
8577             }
8578             # Tie::Hash::NamedCapture is added for *+ *-, Errno for *!
8579             #no strict 'refs';
8580             #if ( defined(objsym(svref_2object(\*{'main::+'}))) or defined(objsym(svref_2object(\*{'main::-'}))) ) {
8581             # use strict 'refs';
8582             # if (!$include_package{'Tie::Hash::NamedCapture'}) {
8583             # $init->add("/* force saving of Tie::Hash::NamedCapture */");
8584             # if ($] >= 5.014) {
8585             # mark_package('Config', 1); # DynaLoader needs Config to set the EGV
8586             # walk_syms('Config');
8587             # svref_2object(\&{'Tie::Hash::NamedCapture::bootstrap'})->save;
8588             # }
8589             # mark_package('Tie::Hash::NamedCapture', 1);
8590             # } # else already included
8591             #} else {
8592             # use strict 'refs';
8593             # delete_unsaved_hashINC('Tie::Hash::NamedCapture');
8594 55     55   594 #}
  55         162  
  55         4187  
8595 0 0       0 no strict 'refs';
  0         0  
8596 55     55   386 if ( defined(objsym(svref_2object(\*{'main::!'}))) ) {
  55         145  
  55         5381  
8597 0 0       0 use strict 'refs';
8598 0         0 if (!$include_package{'Errno'}) {
8599 0         0 $init->add("/* force saving of Errno */");
8600 0         0 mark_package('Config', 1);
8601 0         0 walk_syms('Config');
8602 0         0 mark_package('Errno', 1);
  0         0  
8603             svref_2object(\&{'Errno::bootstrap'})->save;
8604             } # else already included
8605 55     55   402 } else {
  55         155  
  55         14659  
8606 0         0 use strict 'refs';
8607             delete_unsaved_hashINC('Errno');
8608             }
8609             }
8610 0         0  
8611             my ($curpad_nam, $curpad_sym);
8612             {
8613 0         0 # Record comppad sv's names, may not be static
  0         0  
8614 0         0 local $B::C::const_strings = 0;
8615 0 0       0 $init->add("/* curpad names */");
8616 0         0 warn "curpad names:\n" if $verbose;
8617 0 0       0 $curpad_nam = ( comppadlist->ARRAY )[0]->save('curpad_name');
8618 0         0 warn "curpad syms:\n" if $verbose;
8619 0         0 $init->add("/* curpad syms */");
8620             $curpad_sym = ( comppadlist->ARRAY )[1]->save('curpad_syms');
8621 0         0 }
8622             my ($inc_hv, $inc_av);
8623 0 0       0 {
  0         0  
8624 0 0       0 local $B::C::const_strings = 1 if $B::C::ro_inc;
8625 0         0 warn "\%INC and \@INC:\n" if $verbose;
8626 0         0 $init->add('/* %INC */');
8627 0         0 inc_cleanup(0);
8628 0         0 my $inc_gv = svref_2object( \*main::INC );
8629 0         0 $inc_hv = $inc_gv->HV->save('main::INC');
8630 0         0 $init->add('/* @INC */');
8631             $inc_av = $inc_gv->AV->save('main::INC');
8632             }
8633 0         0 # ensure all included @ISA's are stored (#308), and also assign c3 (#325)
8634 0         0 my @saved_isa;
8635 55     55   444 for my $p (sort keys %include_package) {
  55         132  
  55         50889  
8636 0 0 0     0 no strict 'refs';
  0   0     0  
  0         0  
8637 0         0 if ($include_package{$p} and exists(${$p.'::'}{ISA}) and ${$p.'::'}{ISA}) {
8638 0         0 push @saved_isa, $p;
  0         0  
8639 0 0 0     0 svref_2object( \@{$p.'::ISA'} )->save($p.'::ISA');
      0        
8640 0         0 if ($PERL510 and is_using_mro() && mro::get_mro($p) eq 'c3') {
8641             make_c3($p);
8642             }
8643             }
8644 0 0 0     0 }
      0        
8645 0         0 warn "Saved \@ISA for: ".join(" ",@saved_isa)."\n" if @saved_isa and ($verbose or $debug{pkg});
8646             $init->add(
8647             "GvHV(PL_incgv) = $inc_hv;",
8648             "GvAV(PL_incgv) = $inc_av;",
8649             "PL_curpad = AvARRAY($curpad_sym);",
8650             "PL_comppad = $curpad_sym;", # fixed "panic: illegal pad"
8651             "PL_stack_sp = PL_stack_base;" # reset stack (was 1++)
8652 0 0       0 );
    0          
    0          
8653 0         0 if ($] < 5.017005) {
8654             $init->add(
8655             "av_store((AV*)CvPADLIST(PL_main_cv), 0, SvREFCNT_inc_simple_NN($curpad_nam)); /* namepad */",
8656             "av_store((AV*)CvPADLIST(PL_main_cv), 1, SvREFCNT_inc_simple_NN($curpad_sym)); /* curpad */");
8657 0         0 } elsif ($] < 5.019003) {
8658             $init->add(
8659             "PadlistARRAY(CvPADLIST(PL_main_cv))[0] = PL_comppad_name = (PAD*)SvREFCNT_inc_simple_NN($curpad_nam); /* namepad */",
8660             "PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)SvREFCNT_inc_simple_NN($curpad_sym); /* curpad */");
8661 0         0 } elsif ($] < 5.022) {
8662             $init->add(
8663             "PadlistARRAY(CvPADLIST(PL_main_cv))[0] = PL_comppad_name = (PAD*)SvREFCNT_inc_simple_NN($curpad_nam); /* namepad */",
8664             "PadnamelistMAXNAMED(PL_comppad_name) = AvFILL($curpad_nam);",
8665             "PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)SvREFCNT_inc_simple_NN($curpad_sym); /* curpad */");
8666 0         0 } else {
8667             $init->add(
8668             "PadlistNAMES(CvPADLIST(PL_main_cv)) = PL_comppad_name = $curpad_nam; /* namepad */",
8669             "PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)$curpad_sym; /* curpad */");
8670 0 0       0 }
8671 0         0 if ($] < 5.017) {
8672 0 0       0 my $amagic_generate = B::amagic_generation();
8673 0         0 warn "amagic_generation = $amagic_generate\n" if $verbose;
8674             $init->add("PL_amagic_generation = $amagic_generate;");
8675             };
8676             }
8677              
8678             sub descend_marked_unused {
8679             #if ($B::C::walkall) {
8680             # for my $pack (keys %all_bc_deps) {
8681             # mark_unused($pack, 0) if !exists $include_package{$pack} and !skip_pkg($pack);
8682             # }
8683 0     0 0 0 #}
8684 0         0 foreach my $pack ( sort keys %INC ) {
8685 0 0 0     0 my $p = packname_inc($pack);
      0        
8686             mark_package($p) if !skip_pkg($p) and !$all_bc_deps{$p} and $pack !~ /(autosplit\.ix|\.al)$/;
8687 0 0 0     0 }
8688 0         0 if ($debug{pkg} and $verbose) {
  0         0  
8689 0         0 warn "\%include_package: ".join(" ",grep{$include_package{$_}} sort keys %include_package)."\n";
8690             warn "\%skip_package: ".join(" ",sort keys %skip_package)."\n";
8691 0         0 }
8692 0 0       0 foreach my $pack ( sort keys %include_package ) {
8693             mark_package($pack) unless skip_pkg($pack);
8694             }
8695 0 0       0 warn "descend_marked_unused: "
8696             .join(" ",sort keys %include_package)."\n" if $debug{pkg};
8697             }
8698              
8699             sub save_main {
8700 0 0   0 0 0  
8701 0 0       0 warn "Starting compile\n" if $verbose;
8702 0         0 warn "Walking tree\n" if $verbose;
8703 0 0       0 %Exporter::Cache = (); # avoid B::C and B symbols being stored
8704 0         0 _delete_macros_vendor_undefined() if $PERL512;
8705 0         0 set_curcv B::main_cv;
8706 0 0       0 seek( STDOUT, 0, 0 ); #exclude print statements in BEGIN{} into output
8707             binmode( STDOUT, ':utf8' ) unless $PERL56;
8708 0 0       0  
8709             $verbose
8710             ? walkoptree_slow( main_root, "save" )
8711 0         0 : walkoptree( main_root, "save" );
8712             save_main_rest();
8713             }
8714              
8715 0     0   0 sub _delete_macros_vendor_undefined {
8716 55     55   477 foreach my $class (qw(POSIX IO Fcntl Socket Exporter Errno)) {
  55         141  
  55         1973  
8717 55     55   362 no strict 'refs';
  55         134  
  55         1966  
8718 55     55   364 no strict 'subs';
  55         132  
  55         206443  
8719 0         0 no warnings 'uninitialized';
8720 0         0 my $symtab = $class . '::';
8721 0 0 0     0 for my $symbol ( sort keys %$symtab ) {
8722 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)};
8723 0         0 next if ref $symtab->{$symbol};
8724 0         0 local $@;
8725 0         0 my $code = "$class\:\:$symbol();";
8726 0 0       0 eval $code;
8727 0         0 if ( $@ =~ m{vendor has not defined} ) {
8728 0         0 delete $symtab->{$symbol};
8729             next;
8730             }
8731             }
8732 0         0 }
8733             return 1;
8734             }
8735              
8736             sub fixup_ppaddr {
8737             # init op addrs must be the last action, otherwise
8738             # some ops might not be initialized
8739 0 0   0 0 0 # but it needs to happen before CALLREGCOMP, as a /i calls a compiled utf8::SWASHNEW
8740 0         0 if ($B::C::optimize_ppaddr) {
8741 0         0 foreach my $i (@op_sections) {
8742 0         0 my $section = $$i;
8743 0 0       0 my $num = $section->index;
8744 0         0 next unless $num >= 0;
8745             init_op_addr( $section->name, $num + 1 );
8746             }
8747             }
8748             }
8749              
8750             # save %SIG ( in case it was set in a BEGIN block )
8751             sub save_sig {
8752 0     0 0 0 # local $SIG{__WARN__} = shift;
8753 0         0 $init->no_split;
8754 0         0 my @save_sig;
8755 0 0       0 foreach my $k ( sort keys %SIG ) {
8756 0         0 next unless ref $SIG{$k};
8757 0 0 0     0 my $cvref = svref_2object( \$SIG{$k} );
8758 0         0 next if ref($cvref) eq 'B::CV' and $cvref->FILE =~ m|B/C\.pm$|; # ignore B::C SIG warn handler
8759             push @save_sig, [$k, $cvref];
8760 0 0       0 }
8761 0 0       0 unless (@save_sig) {
8762 0 0       0 $init->add( "/* no %SIG in BEGIN block */" ) if $verbose;
8763 0         0 warn "no %SIG in BEGIN block\n" if $verbose;
8764             return;
8765 0 0       0 }
8766 0 0       0 $init->add( "/* save %SIG */" ) if $verbose;
8767 0         0 warn "save %SIG\n" if $verbose;
8768 0         0 $init->add( "{", "\tHV* hv = get_hvs(\"main::SIG\", GV_ADD);" );
8769 0         0 foreach my $x ( @save_sig ) {
8770 0         0 my ($k, $cvref) = @$x;
8771 0         0 my $sv = $cvref->save;
8772 0         0 my ($cstring, $cur, $utf8) = strlen_flags($k);
8773 0         0 $init->add( '{', sprintf "\t".'SV* sv = (SV*)%s;', $sv );
8774             $init->add( sprintf("\thv_store(hv, %s, %u, %s, %d);",
8775 0         0 $cstring, $cur, 'sv', 0 ) );
8776             $init->add( "\t".'mg_set(sv);', '}' );
8777 0         0 }
8778 0         0 $init->add('}');
8779             $init->split;
8780             }
8781              
8782 0     0 0 0 sub force_saving_xsloader {
8783             mark_package("XSLoader", 1);
8784 0 0       0 # mark_package("DynaLoader", 1);
    0          
8785 0         0 if ($] < 5.015003) {
8786 0         0 $init->add("/* force saving of XSLoader::load */");
  0         0  
8787             eval { XSLoader::load; };
8788 0         0 # does this really save the whole packages?
8789 0         0 $dumped_package{XSLoader} = 1;
8790             svref_2object( \&XSLoader::load )->save;
8791 0         0 } elsif ($CPERL51) {
8792 0         0 $init->add("/* XSLoader::load_file already builtin into cperl */");
8793 0         0 $dumped_package{XSLoader} = 1;
8794 0         0 $dumped_package{DynaLoader} = 1;
8795             add_hashINC("XSLoader"); # builtin
8796 0         0 } else {
8797             $init->add("/* custom XSLoader::load_file */");
8798 0         0 # does this really save the whole packages?
8799 0         0 $dumped_package{DynaLoader} = 1;
8800 0         0 svref_2object( \&XSLoader::load_file )->save;
8801             svref_2object( \&DynaLoader::dl_load_flags )->save; # not saved as XSUB constant?
8802 0 0       0 }
8803 0         0 add_hashINC("XSLoader") if $] < 5.015003;
8804 0         0 add_hashINC("DynaLoader");
8805             $use_xsloader = 0; # do not load again
8806             }
8807              
8808             sub save_main_rest {
8809             # this is mainly for the test suite
8810             # local $SIG{__WARN__} = sub { print STDERR @_ } unless $debug{runtime};
8811              
8812 0 0 0 0 0 0 warn "done main optree, walking symtable for extras\n"
8813 0         0 if $verbose or $debug{cv};
8814 0         0 $init->add("");
8815 0         0 $init->add("/* done main optree, extra subs which might be unused */");
8816 0         0 save_unused_subs();
8817             $init->add("/* done extras */");
8818              
8819 0 0       0 # startpoints: XXX TODO push BEGIN/END blocks to modules code.
8820 0         0 warn "Writing init_av\n" if $debug{av};
8821 0         0 my $init_av = init_av->save('INIT');
8822             my $end_av;
8823             {
8824 0         0 # >=5.10 need to defer nullifying of all vars in END, not only new ones.
  0         0  
8825 0         0 local ($B::C::pv_copy_on_grow, $B::C::const_strings);
8826 0 0       0 $in_endav = 1;
8827 0         0 warn "Writing end_av\n" if $debug{av};
8828 0         0 $init->add("/* END block */");
8829 0         0 $end_av = end_av->save('END');
8830             $in_endav = 0;
8831 0 0       0 }
8832             if ( !defined($module) ) {
8833             $init->add(
8834 0         0 "/* startpoints */",
8835 0         0 sprintf( "PL_main_root = s\\_%x;", ${ main_root() } ),
  0         0  
8836             sprintf( "PL_main_start = s\\_%x;", ${ main_start() } ),
8837 0 0       0 );
8838             $init->add(index($init_av,'(AV*)')>=0
8839             ? "PL_initav = $init_av;"
8840 0 0       0 : "PL_initav = (AV*)$init_av;");
8841             $init->add(index($end_av,'(AV*)')>=0
8842             ? "PL_endav = $end_av;"
8843             : "PL_endav = (AV*)$end_av;");
8844 0 0       0 }
8845             save_context() unless defined($module);
8846             # warn "use_xsloader=$use_xsloader\n" if $verbose;
8847 0 0       0 # If XSLoader was forced later, e.g. in curpad, INIT or END block
8848             force_saving_xsloader() if $use_xsloader;
8849 0 0       0  
8850 0 0       0 return if $check;
8851 0         0 warn "Writing output\n" if $verbose;
8852             output_boilerplate();
8853              
8854 0         0 # add static modules like " Win32CORE"
8855 0 0       0 foreach my $stashname ( split /\s+/, $Config{static_ext} ) {
8856 0         0 next if $stashname =~ /^\s*$/; # often a leading space
8857 0         0 $static_ext{$stashname}++;
8858 0         0 my $stashxsub = $stashname;
8859 0         0 $stashxsub =~ s/::/__/g;
8860             print "EXTERN_C void boot_$stashxsub (pTHX_ CV* cv);\n";
8861 0         0 }
8862 0   0     0 print "\n";
8863 0         0 output_all($init_name || "perl_init");
8864 0         0 print "\n";
8865             output_main_rest();
8866 0 0       0  
8867 0 0       0 if ( defined($module) ) {
8868 0         0 my $cmodule = $module ? $module : "main";
8869             $cmodule =~ s/::/__/g;
8870 0         0  
8871 0 0       0 my $start = "op_list[0]";
8872 0         0 warn "curpad syms:\n" if $verbose;
8873 0         0 $init->add("/* curpad syms */");
8874             my $curpad_sym = ( comppadlist->ARRAY )[1]->save;
8875 0         0  
8876             print <<"EOT";
8877              
8878             #include "XSUB.h"
8879             XS(boot_$cmodule)
8880             {
8881             dXSARGS;
8882             perl_init();
8883             ENTER;
8884             SAVETMPS;
8885             SAVEVPTR(PL_curpad);
8886             SAVEVPTR(PL_op);
8887             dl_init(aTHX);
8888             PL_curpad = AvARRAY($curpad_sym);
8889             PL_comppad = $curpad_sym;
8890             PL_op = $start;
8891             perl_run( aTHX ); /* Perl_runops_standard(aTHX); */
8892             FREETMPS;
8893             LEAVE;
8894             ST(0) = &PL_sv_yes;
8895             XSRETURN(1);
8896             }
8897             EOT
8898              
8899 0         0 } else {
8900             output_main();
8901             }
8902             }
8903              
8904 0     0 0 0 sub init_sections {
8905             my @sections = (
8906             decl => \$decl,
8907             init0 => \$init0,
8908             free => \$free,
8909             sym => \$symsect,
8910             hek => \$heksect,
8911             binop => \$binopsect,
8912             condop => \$condopsect,
8913             cop => \$copsect,
8914             padop => \$padopsect,
8915             listop => \$listopsect,
8916             logop => \$logopsect,
8917             loop => \$loopsect,
8918             op => \$opsect,
8919             pmop => \$pmopsect,
8920             pvop => \$pvopsect,
8921             svop => \$svopsect,
8922             unop => \$unopsect,
8923             unopaux => \$unopauxsect,
8924             methop => \$methopsect,
8925             sv => \$svsect,
8926             xpv => \$xpvsect,
8927             xpvav => \$xpvavsect,
8928             xpvhv => \$xpvhvsect,
8929             xpvcv => \$xpvcvsect,
8930             xpviv => \$xpvivsect,
8931             xpvuv => \$xpvuvsect,
8932             xpvnv => \$xpvnvsect,
8933             xpvmg => \$xpvmgsect,
8934             xpvlv => \$xpvlvsect,
8935             xrv => \$xrvsect,
8936             xpvbm => \$xpvbmsect,
8937             xpvio => \$xpviosect,
8938             padlist => \$padlistsect,
8939             padnamelist => \$padnlsect,
8940             padname => \$padnamesect,
8941 0 0       0 );
8942 0         0 if ($PERL522) {
8943             pop @sections;
8944 0         0 }
8945 0         0 my ( $name, $sectref );
8946 0         0 while ( ( $name, $sectref ) = splice( @sections, 0, 2 ) ) {
8947             $$sectref = new B::C::Section $name, \%symtable, 0;
8948 0 0       0 }
8949 0         0 if ($PERL522) {
8950 0         0 for my $size (@padnamesect_sizes) {
8951 0         0 my $name = "padname_$size";
8952             $padnamesect{$size} = new B::C::Section $name, \%symtable, 0;
8953             }
8954 0         0 }
8955 0         0 $init = new B::C::InitSection 'init', \%symtable, 0;
8956 0         0 $init1 = new B::C::InitSection 'init1', \%symtable, 0;
8957 0         0 $init2 = new B::C::InitSection 'init2', \%symtable, 0;
8958             %savINC = %curINC = %INC;
8959             }
8960              
8961 0     0 0 0 sub mark_unused {
8962 0         0 my ( $pkg, $val ) = @_;
8963             $include_package{$pkg} = $val;
8964             }
8965              
8966 15     15 0 66 sub mark_skip {
8967 225         543 for (@_) {
8968             delete_unsaved_hashINC($_);
8969 225 50       671 # $include_package{$_} = 0;
8970             $skip_package{$_} = 1 unless $include_package{$_};
8971             }
8972             }
8973              
8974 0     0 0   sub compile {
8975             my @options = @_;
8976 0 0         # Allow debugging in CHECK blocks without Od
8977 0           $DB::single = 1 if defined &DB::DB;
8978 0           my ( $option, $opt, $arg );
8979 0           my @eval_at_startup;
8980 0           $B::C::can_delete_pkg = 1;
8981 0           $B::C::save_sig = 1;
8982 0           $B::C::destruct = 1;
8983 0           $B::C::stash = 0;
8984 0 0         $B::C::cow = 0;
8985 0 0         $B::C::fold = 1 if $] >= 5.013009; # always include utf8::Cased tables
8986 0 0 0       $B::C::warnings = 1 if $] >= 5.013005; # always include Carp warnings categories and B
8987 0 0         $B::C::optimize_warn_sv = 1 if $^O ne 'MSWin32' or $Config{cc} !~ m/^cl/i;
8988 0           $B::C::dyn_padlist = 1 if $] >= 5.017; # default is dynamic and safe, disable with -O4
8989             $B::C::walkall = 1;
8990 0            
8991             mark_skip qw(B::C B::C::Config B::CC B::Asmdata B::FAKEOP O
8992             B::Pseudoreg B::Shadow B::C::InitSection);
8993             #mark_skip('DB', 'Term::ReadLine') if defined &DB::DB;
8994              
8995 0           OPTION:
8996 0 0         while ( $option = shift @options ) {
8997 0           if ( $option =~ /^-(.)(.*)/ ) {
8998 0           $opt = $1;
8999             $arg = $2;
9000             }
9001 0           else {
9002 0           unshift @options, $option;
9003             last OPTION;
9004 0 0 0       }
9005 0           if ( $opt eq "-" && $arg eq "-" ) {
9006 0           shift @options;
9007             last OPTION;
9008 0 0         }
9009 0           if ( $opt eq "w" ) {
9010             $warn_undefined_syms = 1;
9011 0 0 0       }
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
9012 0           if ( $opt eq "c" ) {
9013             $check = 1;
9014             }
9015 0   0       elsif ( $opt eq "D" ) {
9016 0 0         $arg ||= shift @options;
    0          
9017 0           if ($arg eq 'full') {
9018 0           $arg = 'OcAHCMGSPpsWF';
9019             $all_bc_deps{'B::Flags'}++;
9020             }
9021 0           elsif ($arg eq 'ufull') {
9022 0           $arg = 'uOcAHCMGSPpsWF';
9023             $all_bc_deps{'B::Flags'}++;
9024 0           }
9025 0 0         foreach my $arg ( split( //, $arg ) ) {
    0          
    0          
    0          
9026 0           if (exists $debug_map{$arg}) {
9027             $debug{ $debug_map{$arg} }++;
9028             }
9029 0           elsif ( $arg eq "o" ) {
9030 0           $verbose++;
9031             B->debug(1);
9032             }
9033 0 0 0       elsif ( $arg eq "F" ) {
9034 0           $debug{flags}++ if $] > 5.008 and eval "require B::Flags;";
9035             $all_bc_deps{'B::Flags'}++;
9036             # $debug{flags}++ if require B::Flags;
9037             }
9038 0           elsif ( $arg eq "r" ) {
9039             $debug{runtime}++;
9040 0     0     $SIG{__WARN__} = sub {
9041 0           warn @_;
9042 0           my $s = join(" ", @_);
9043 0 0         chomp $s;
9044 0           $init->add("/* ".$s." */") if $init;
9045             };
9046             }
9047 0           else {
9048             warn "ignoring unknown debug option: $arg\n";
9049             }
9050             }
9051             }
9052 0   0       elsif ( $opt eq "o" ) {
9053 0           $arg ||= shift @options;
9054 0 0         $outfile = $arg;
9055 0           if ($check) {
9056             warn "Warning: -o argument ignored with -c\n";
9057 0 0         } else {
9058             open( STDOUT, ">", $arg ) or return "$arg: $!\n";
9059             }
9060             }
9061 0 0         elsif ( $opt eq "s" and $arg eq "taticxs" ) {
9062 0           $outfile = "perlcc" unless $outfile;
9063             $staticxs = 1;
9064             }
9065 0   0       elsif ( $opt eq "n" ) {
9066 0           $arg ||= shift @options;
9067             $init_name = $arg;
9068             }
9069             elsif ( $opt eq "m" ) {
9070 0           # $arg ||= shift @options;
9071 0           $module = $arg;
9072             mark_unused( $arg, 1 );
9073             }
9074 0           elsif ( $opt eq "v" ) {
9075             $verbose = 1;
9076             }
9077 0   0       elsif ( $opt eq "u" ) {
9078 0 0         $arg ||= shift @options;
9079 0           if ($arg =~ /\.p[lm]$/) {
9080             eval "require(\"$arg\");"; # path as string
9081 0           } else {
9082             eval "require $arg;"; # package as bareword with ::
9083 0           }
9084             mark_unused( $arg, 1 );
9085             }
9086 0   0       elsif ( $opt eq "U" ) {
9087 0           $arg ||= shift @options;
9088             mark_skip( $arg );
9089             }
9090 0   0       elsif ( $opt eq "f" ) {
9091 0           $arg ||= shift @options;
9092 0   0       $arg =~ m/(no-)?(.*)/;
9093 0 0         my $no = defined($1) && $1 eq 'no-';
9094 0 0         $arg = $no ? $2 : $arg;
9095 0           if ( exists $option_map{$arg} ) {
  0            
9096             ${ $option_map{$arg} } = !$no;
9097             }
9098 0           else {
9099             die "Invalid optimization '$arg'";
9100             }
9101             }
9102 0 0         elsif ( $opt eq "O" ) {
9103 0           $arg = 1 if $arg eq "";
9104 0           my @opt;
9105 0           foreach my $i ( 1 .. $arg ) {
9106 0 0         push @opt, @{ $optimization_map{$i} }
9107             if exists $optimization_map{$i};
9108 0           }
9109 0 0         unshift @options, @opt;
9110             warn "options : ".(join " ",@opt)."\n" if $verbose;
9111             }
9112 0           elsif ( $opt eq "e" ) {
9113             push @eval_at_startup, $arg;
9114             }
9115 0           elsif ( $opt eq "l" ) {
9116             $max_string_len = $arg;
9117             }
9118 0 0 0       }
    0          
9119 0 0         if (!$B::C::Config::have_independent_comalloc) {
    0          
9120 0           if ($B::C::av_init2) {
9121 0           $B::C::av_init = 1;
9122             $B::C::av_init2 = 0;
9123 0           } elsif ($B::C::av_init) {
9124             $B::C::av_init2 = 0;
9125             }
9126 0           } elsif ($B::C::av_init2 and $B::C::av_init) {
9127             $B::C::av_init = 0;
9128 0 0 0       }
      0        
9129 0 0 0       $B::C::save_data_fh = 1 if $] >= 5.008 and (($] < 5.009004) or $MULTI);
9130             $B::C::destruct = 1 if $] < 5.008 or $^O eq 'MSWin32'; # skip -ffast-destruct there
9131 0            
9132 0           init_sections();
9133 0           foreach my $i (@eval_at_startup) {
9134             $init2->add_eval($i);
9135 0 0         }
9136             if (@options) { # modules or main?
9137 0     0     return sub {
9138 0           my $objname;
9139 0           foreach $objname (@options) {
9140             eval "save_object(\\$objname)";
9141 0   0       }
9142             output_all($init_name || "init_module");
9143 0           }
9144             }
9145 0     0     else {
  0            
9146             return sub { save_main() };
9147             }
9148             }
9149              
9150             1;
9151              
9152             __END__