line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# C.pm |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# Copyright (c) 1996, 1997, 1998 Malcolm Beattie |
4
|
|
|
|
|
|
|
# Copyright (c) 2008, 2009, 2010, 2011 Reini Urban |
5
|
|
|
|
|
|
|
# Copyright (c) 2010 Nick Koston |
6
|
|
|
|
|
|
|
# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 cPanel Inc |
7
|
|
|
|
|
|
|
# |
8
|
|
|
|
|
|
|
# You may distribute under the terms of either the GNU General Public |
9
|
|
|
|
|
|
|
# License or the Artistic License, as specified in the README file. |
10
|
|
|
|
|
|
|
# |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
package B::C; |
13
|
55
|
|
|
55
|
|
5433350
|
use strict; |
|
55
|
|
|
|
|
82
|
|
|
55
|
|
|
|
|
6439
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our $VERSION = '1.55'; |
16
|
|
|
|
|
|
|
our (%debug, $check, %Config); |
17
|
|
|
|
|
|
|
BEGIN { |
18
|
55
|
|
|
55
|
|
862
|
require B::C::Config; |
19
|
55
|
|
|
|
|
146
|
*Config = \%B::C::Config::Config; |
20
|
55
|
50
|
33
|
|
|
3263
|
if (!keys %Config or !exists $Config{usecperl}) { |
21
|
0
|
|
|
|
|
0
|
warn "Empty \%B::C::Config::Config"; |
22
|
0
|
|
|
|
|
0
|
require Config; |
23
|
0
|
|
|
|
|
0
|
Config->import; |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
# make it a restricted hash |
26
|
55
|
50
|
|
|
|
4997
|
Internals::SvREADONLY(%Config, 1) if $] >= 5.008004; |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# Thanks to Mattia Barbon for the C99 tip to init any union members |
30
|
|
|
|
|
|
|
my $C99 = $Config{d_c99_variadic_macros}; # http://docs.sun.com/source/819-3688/c99.app.html#pgfId-1003962 |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
package B::C::Section; |
33
|
55
|
|
|
55
|
|
256
|
use strict; |
|
55
|
|
|
|
|
59
|
|
|
55
|
|
|
|
|
44983
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
my %sections; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
sub new { |
38
|
0
|
|
|
0
|
|
0
|
my ($class, $section, $symtable, $default) = @_; |
39
|
0
|
|
|
|
|
0
|
my $o = bless [-1, $section, $symtable, $default], $class; |
40
|
0
|
|
|
|
|
0
|
$sections{$section} = $o; |
41
|
|
|
|
|
|
|
|
42
|
0
|
|
|
|
|
0
|
push @$o, { values => [] }; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# if sv add a dummy sv_arenaroot to support global destruction |
45
|
0
|
0
|
|
|
|
0
|
if ($section eq 'sv') { |
46
|
|
|
|
|
|
|
# 0 refcnt placeholder for the static arenasize later adjusted |
47
|
0
|
0
|
|
|
|
0
|
$o->add( "NULL, 0, SVTYPEMASK|0x01000000".($] >= 5.009005?", {0}":'')); # SVf_FAKE |
48
|
0
|
|
|
|
|
0
|
$o->[-1]{dbg}->[0] = "PL_sv_arenaroot"; |
49
|
|
|
|
|
|
|
} |
50
|
0
|
|
|
|
|
0
|
return $o; |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub get { |
54
|
0
|
|
|
0
|
|
0
|
my ($class, $section) = @_; |
55
|
0
|
|
|
|
|
0
|
return $sections{$section}; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub add { |
59
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
60
|
0
|
|
|
|
|
0
|
push( @{ $section->[-1]{values} }, @_ ); |
|
0
|
|
|
|
|
0
|
|
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub remove { |
64
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
65
|
0
|
|
|
|
|
0
|
pop @{ $section->[-1]{values} }; |
|
0
|
|
|
|
|
0
|
|
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub index { |
69
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
70
|
0
|
|
|
|
|
0
|
return scalar( @{ $section->[-1]{values} } ) - 1; |
|
0
|
|
|
|
|
0
|
|
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub name { |
74
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
75
|
0
|
|
|
|
|
0
|
return $section->[1]; |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub symtable { |
79
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
80
|
0
|
|
|
|
|
0
|
return $section->[2]; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub default { |
84
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
85
|
0
|
|
|
|
|
0
|
return $section->[3]; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub typename { |
89
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
90
|
0
|
|
|
|
|
0
|
my $name = $section->name; |
91
|
0
|
|
|
|
|
0
|
my $typename = uc($name); |
92
|
|
|
|
|
|
|
# -fcog hack to statically initialize PVs (SVPV for 5.10-5.11 only) |
93
|
0
|
0
|
0
|
|
|
0
|
$typename = 'SVPV' if $typename eq 'SV' and $] > 5.009005 and $] < 5.012 and !$C99; |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
94
|
|
|
|
|
|
|
# $typename = 'const '.$typename if $name !~ /^(cop_|sv_)/; |
95
|
0
|
0
|
|
|
|
0
|
$typename = 'UNOP_AUX' if $typename eq 'UNOPAUX'; |
96
|
0
|
0
|
|
|
|
0
|
$typename = 'SV*' if $typename =~ /^AVCO[WG]_/; |
97
|
|
|
|
|
|
|
#$typename = 'MyPADNAME' if $typename eq 'PADNAME' and $] >= 5.018; |
98
|
0
|
|
|
|
|
0
|
return $typename; |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub comment { |
102
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
103
|
0
|
0
|
|
|
|
0
|
$section->[-1]{comment} = join( "", @_ ) if @_; |
104
|
0
|
|
|
|
|
0
|
$section->[-1]{comment}; |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# add debugging info - stringified flags on -DF |
108
|
|
|
|
|
|
|
sub debug { |
109
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
110
|
0
|
|
|
|
|
0
|
my $dbg = join( " ", @_ ); |
111
|
0
|
0
|
|
|
|
0
|
$section->[-1]{dbg}->[ $section->index ] = $dbg if $dbg; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub output { |
115
|
0
|
|
|
0
|
|
0
|
my ( $section, $fh, $format ) = @_; |
116
|
0
|
|
0
|
|
|
0
|
my $sym = $section->symtable || {}; |
117
|
0
|
|
|
|
|
0
|
my $default = $section->default; |
118
|
0
|
0
|
|
|
|
0
|
return if $B::C::check; |
119
|
0
|
|
|
|
|
0
|
my $i = 0; |
120
|
0
|
0
|
0
|
|
|
0
|
my $dodbg = 1 if $debug{flags} and $section->[-1]{dbg}; |
121
|
0
|
0
|
|
|
|
0
|
if ($section->name eq 'sv') { #fixup arenaroot refcnt |
122
|
0
|
|
|
|
|
0
|
my $len = scalar @{ $section->[-1]{values} }; |
|
0
|
|
|
|
|
0
|
|
123
|
0
|
|
|
|
|
0
|
$section->[-1]{values}->[0] =~ s/^NULL, 0/NULL, $len/; |
124
|
|
|
|
|
|
|
} |
125
|
0
|
|
|
|
|
0
|
foreach ( @{ $section->[-1]{values} } ) { |
|
0
|
|
|
|
|
0
|
|
126
|
0
|
|
|
|
|
0
|
my $dbg = ""; |
127
|
0
|
|
|
|
|
0
|
my $ref = ""; |
128
|
0
|
0
|
|
|
|
0
|
if (m/(s\\_[0-9a-f]+)/) { |
129
|
0
|
0
|
0
|
|
|
0
|
if (!exists($sym->{$1}) and $1 ne 's\_0') { |
130
|
0
|
|
|
|
|
0
|
$ref = $1; |
131
|
0
|
|
|
|
|
0
|
$B::C::unresolved_count++; |
132
|
0
|
0
|
|
|
|
0
|
if ($B::C::verbose) { |
133
|
0
|
|
|
|
|
0
|
my $caller = caller(1); |
134
|
0
|
0
|
|
|
|
0
|
warn "Warning: unresolved ".$section->name." symbol $ref\n" |
135
|
|
|
|
|
|
|
if $caller eq 'B::C'; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
} |
139
|
0
|
0
|
|
|
|
0
|
s{(s\\_[0-9a-f]+)}{ exists($sym->{$1}) ? $sym->{$1} : $default; }ge; |
|
0
|
|
|
|
|
0
|
|
140
|
0
|
0
|
0
|
|
|
0
|
if ($dodbg and $section->[-1]{dbg}->[$i]) { |
141
|
0
|
|
|
|
|
0
|
$dbg = " /* ".$section->[-1]{dbg}->[$i]." ".$ref." */"; |
142
|
|
|
|
|
|
|
} |
143
|
0
|
0
|
|
|
|
0
|
if ($format eq "\t{ %s }, /* %s_list[%d] %s */%s\n") { |
144
|
0
|
|
|
|
|
0
|
printf $fh $format, $_, $section->name, $i, $ref, $dbg; |
145
|
|
|
|
|
|
|
} else { |
146
|
0
|
|
|
|
|
0
|
printf $fh $format, $_; |
147
|
|
|
|
|
|
|
} |
148
|
0
|
|
|
|
|
0
|
++$i; |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
package B::C::InitSection; |
153
|
55
|
|
|
55
|
|
276
|
use strict; |
|
55
|
|
|
|
|
70
|
|
|
55
|
|
|
|
|
39018
|
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
# avoid use vars |
156
|
|
|
|
|
|
|
@B::C::InitSection::ISA = qw(B::C::Section); |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
sub new { |
159
|
0
|
|
|
0
|
|
0
|
my $class = shift; |
160
|
0
|
|
|
|
|
0
|
my $max_lines = 10000; #pop; |
161
|
0
|
|
|
|
|
0
|
my $section = $class->SUPER::new(@_); |
162
|
|
|
|
|
|
|
|
163
|
0
|
|
|
|
|
0
|
$section->[-1]{evals} = []; |
164
|
0
|
|
|
|
|
0
|
$section->[-1]{initav} = []; |
165
|
0
|
|
|
|
|
0
|
$section->[-1]{chunks} = []; |
166
|
0
|
|
|
|
|
0
|
$section->[-1]{nosplit} = 0; |
167
|
0
|
|
|
|
|
0
|
$section->[-1]{current} = []; |
168
|
0
|
|
|
|
|
0
|
$section->[-1]{count} = 0; |
169
|
0
|
|
|
|
|
0
|
$section->[-1]{size} = 0; |
170
|
0
|
|
|
|
|
0
|
$section->[-1]{max_lines} = $max_lines; |
171
|
|
|
|
|
|
|
|
172
|
0
|
|
|
|
|
0
|
return $section; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
sub split { |
176
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
177
|
|
|
|
|
|
|
$section->[-1]{nosplit}-- |
178
|
0
|
0
|
|
|
|
0
|
if $section->[-1]{nosplit} > 0; |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
sub no_split { |
182
|
0
|
|
|
0
|
|
0
|
shift->[-1]{nosplit}++; |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub inc_count { |
186
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
187
|
|
|
|
|
|
|
|
188
|
0
|
|
|
|
|
0
|
$section->[-1]{count} += $_[0]; |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# this is cheating |
191
|
0
|
|
|
|
|
0
|
$section->add(); |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub add { |
195
|
0
|
|
|
0
|
|
0
|
my $section = shift->[-1]; |
196
|
0
|
|
|
|
|
0
|
my $current = $section->{current}; |
197
|
0
|
|
|
|
|
0
|
my $nosplit = $section->{nosplit}; |
198
|
|
|
|
|
|
|
|
199
|
0
|
|
|
|
|
0
|
push @$current, @_; |
200
|
0
|
|
|
|
|
0
|
$section->{count} += scalar(@_); |
201
|
0
|
0
|
0
|
|
|
0
|
if ( !$nosplit && $section->{count} >= $section->{max_lines} ) { |
202
|
0
|
|
|
|
|
0
|
push @{ $section->{chunks} }, $current; |
|
0
|
|
|
|
|
0
|
|
203
|
0
|
|
|
|
|
0
|
$section->{current} = []; |
204
|
0
|
|
|
|
|
0
|
$section->{count} = 0; |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
sub add_eval { |
209
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
210
|
0
|
|
|
|
|
0
|
my @strings = @_; |
211
|
|
|
|
|
|
|
|
212
|
0
|
|
|
|
|
0
|
foreach my $i (@strings) { |
213
|
0
|
|
|
|
|
0
|
$i =~ s/\"/\\\"/g; |
214
|
|
|
|
|
|
|
} |
215
|
0
|
|
|
|
|
0
|
push @{ $section->[-1]{evals} }, @strings; |
|
0
|
|
|
|
|
0
|
|
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
sub pre_destruct { |
219
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
220
|
0
|
|
|
|
|
0
|
push @{ $section->[-1]{pre_destruct} }, @_; |
|
0
|
|
|
|
|
0
|
|
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub add_initav { |
224
|
0
|
|
|
0
|
|
0
|
my $section = shift; |
225
|
0
|
|
|
|
|
0
|
push @{ $section->[-1]{initav} }, @_; |
|
0
|
|
|
|
|
0
|
|
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
sub output { |
229
|
0
|
|
|
0
|
|
0
|
my ( $section, $fh, $format, $init_name ) = @_; |
230
|
0
|
|
0
|
|
|
0
|
my $sym = $section->symtable || {}; |
231
|
0
|
|
|
|
|
0
|
my $default = $section->default; |
232
|
0
|
0
|
|
|
|
0
|
return if $B::C::check; |
233
|
0
|
|
|
|
|
0
|
push @{ $section->[-1]{chunks} }, $section->[-1]{current}; |
|
0
|
|
|
|
|
0
|
|
234
|
|
|
|
|
|
|
|
235
|
0
|
|
|
|
|
0
|
my $name = "aaaa"; |
236
|
0
|
|
|
|
|
0
|
foreach my $i ( @{ $section->[-1]{chunks} } ) { |
|
0
|
|
|
|
|
0
|
|
237
|
|
|
|
|
|
|
# dTARG and dSP unused -nt |
238
|
0
|
|
|
|
|
0
|
print $fh <<"EOT"; |
239
|
|
|
|
|
|
|
static void ${init_name}_${name}(pTHX) |
240
|
|
|
|
|
|
|
{ |
241
|
|
|
|
|
|
|
EOT |
242
|
0
|
|
|
|
|
0
|
foreach my $i ( @{ $section->[-1]{initav} } ) { |
|
0
|
|
|
|
|
0
|
|
243
|
0
|
|
|
|
|
0
|
print $fh "\t",$i,"\n"; |
244
|
|
|
|
|
|
|
} |
245
|
0
|
|
|
|
|
0
|
foreach my $j (@$i) { |
246
|
0
|
|
|
|
|
0
|
$j =~ s{(s\\_[0-9a-f]+)} |
247
|
0
|
0
|
|
|
|
0
|
{ exists($sym->{$1}) ? $sym->{$1} : $default; }ge; |
248
|
0
|
|
|
|
|
0
|
print $fh "\t$j\n"; |
249
|
|
|
|
|
|
|
} |
250
|
0
|
0
|
|
|
|
0
|
if (@{ $section->[-1]{evals} }) { |
|
0
|
|
|
|
|
0
|
|
251
|
|
|
|
|
|
|
# We need to output evals after dl_init, in init2 |
252
|
0
|
0
|
|
|
|
0
|
if ($section->name ne 'init2') { |
253
|
0
|
|
|
|
|
0
|
die "Invalid section ".$section->name."->add_eval, use init2"; |
254
|
|
|
|
|
|
|
} else { |
255
|
0
|
|
|
|
|
0
|
foreach my $s ( @{ $section->[-1]{evals} } ) { |
|
0
|
|
|
|
|
0
|
|
256
|
0
|
|
|
|
|
0
|
print $fh "\teval_pv(\"$s\",1);\n"; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
} |
260
|
0
|
|
|
|
|
0
|
print $fh "}\n"; |
261
|
|
|
|
|
|
|
|
262
|
0
|
|
|
|
|
0
|
$section->SUPER::add("${init_name}_${name}(aTHX);"); |
263
|
0
|
|
|
|
|
0
|
++$name; |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
|
266
|
0
|
|
|
|
|
0
|
print $fh <<"EOT"; |
267
|
|
|
|
|
|
|
PERL_STATIC_INLINE int ${init_name}(pTHX) |
268
|
|
|
|
|
|
|
{ |
269
|
|
|
|
|
|
|
EOT |
270
|
0
|
0
|
|
|
|
0
|
if ($section->name eq 'init') { |
271
|
0
|
|
|
|
|
0
|
print $fh "\tperl_init0(aTHX);\n"; |
272
|
|
|
|
|
|
|
} |
273
|
0
|
|
|
|
|
0
|
$section->SUPER::output( $fh, $format ); |
274
|
0
|
|
|
|
|
0
|
print $fh "\treturn 0;\n}\n"; |
275
|
|
|
|
|
|
|
} |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
package B::C; |
278
|
55
|
|
|
55
|
|
255
|
use strict; |
|
55
|
|
|
|
|
703
|
|
|
55
|
|
|
|
|
2490
|
|
279
|
55
|
|
|
55
|
|
509
|
use Exporter (); |
|
55
|
|
|
|
|
69
|
|
|
55
|
|
|
|
|
725
|
|
280
|
55
|
|
|
55
|
|
24780
|
use Errno (); #needed since 5.14 |
|
55
|
|
|
|
|
70468
|
|
|
55
|
|
|
|
|
5559
|
|
281
|
|
|
|
|
|
|
our %Regexp; |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
{ # block necessary for caller to work |
284
|
|
|
|
|
|
|
my $caller = caller; |
285
|
|
|
|
|
|
|
if ( $caller eq 'O' or $caller eq 'Od' ) { |
286
|
|
|
|
|
|
|
require XSLoader; |
287
|
|
|
|
|
|
|
XSLoader::load('B::C'); # for r-magic and for utf8-keyed B::HV->ARRAY |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
292
|
|
|
|
|
|
|
our @EXPORT_OK = |
293
|
|
|
|
|
|
|
qw(output_all output_boilerplate output_main output_main_rest mark_unused mark_skip |
294
|
|
|
|
|
|
|
init_sections set_callback save_unused_subs objsym save_context fixup_ppaddr |
295
|
|
|
|
|
|
|
save_sig svop_or_padop_pv inc_cleanup ivx nvx curcv set_curcv); |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
# for 5.6.[01] better use the native B::C |
298
|
|
|
|
|
|
|
# but 5.6.2 works fine |
299
|
|
|
|
|
|
|
use B |
300
|
55
|
|
|
|
|
24783
|
qw(minus_c sv_undef walkoptree walkoptree_slow main_root main_start peekop |
301
|
|
|
|
|
|
|
cchar svref_2object compile_stats comppadlist hash |
302
|
|
|
|
|
|
|
threadsv_names main_cv init_av end_av opnumber cstring |
303
|
55
|
|
|
55
|
|
252
|
HEf_SVKEY SVf_POK SVp_POK SVf_ROK SVf_IOK SVf_NOK SVf_IVisUV SVf_READONLY); |
|
55
|
|
|
|
|
64
|
|
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
# usually 0x400000, but can be as low as 0x10000 |
306
|
|
|
|
|
|
|
# http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/compdirsimagebaseaddress_xml.html |
307
|
|
|
|
|
|
|
# called mapped_base on linux (usually 0xa38000) |
308
|
|
|
|
|
|
|
sub LOWEST_IMAGEBASE() {0x10000} |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
sub _load_mro { |
311
|
0
|
0
|
0
|
0
|
|
0
|
eval q/require mro; 1/ or die if $] >= 5.010; |
312
|
0
|
|
|
0
|
|
0
|
*_load_mro = sub {}; |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
sub is_using_mro { |
316
|
0
|
0
|
|
0
|
0
|
0
|
return keys %{mro::} > 10 ? 1 : 0; |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
BEGIN { |
320
|
55
|
50
|
|
55
|
|
217
|
if ($] >= 5.008) { |
321
|
55
|
|
|
|
|
6254
|
@B::NV::ISA = 'B::IV'; # add IVX to nv. This fixes test 23 for Perl 5.8 |
322
|
55
|
|
|
|
|
2307
|
B->import(qw(regex_padav SVp_NOK SVp_IOK CVf_CONST CVf_ANON |
323
|
|
|
|
|
|
|
SVf_FAKE)); # both unsupported for 5.6 |
324
|
55
|
|
|
|
|
2802
|
eval q[ |
325
|
|
|
|
|
|
|
sub SVs_OBJECT() {0x00100000} |
326
|
|
|
|
|
|
|
sub SVf_AMAGIC() {0x10000000} |
327
|
|
|
|
|
|
|
]; |
328
|
|
|
|
|
|
|
} else { |
329
|
0
|
|
|
|
|
0
|
eval q[ |
330
|
|
|
|
|
|
|
sub SVp_NOK() {0}; # unused |
331
|
|
|
|
|
|
|
sub SVp_IOK() {0}; |
332
|
|
|
|
|
|
|
sub CVf_ANON() {4}; |
333
|
|
|
|
|
|
|
sub CVf_CONST() {0}; # unused |
334
|
|
|
|
|
|
|
sub PMf_ONCE() {0xff}; # unused |
335
|
|
|
|
|
|
|
sub SVf_FAKE() {0x00100000}; # unused |
336
|
|
|
|
|
|
|
sub SVs_OBJECT() {0x00001000} |
337
|
|
|
|
|
|
|
sub SVf_AMAGIC() {0x10000000} |
338
|
|
|
|
|
|
|
]; |
339
|
0
|
|
|
|
|
0
|
@B::PVMG::ISA = qw(B::PVNV B::RV); |
340
|
|
|
|
|
|
|
} |
341
|
0
|
|
|
0
|
0
|
0
|
sub SVf_UTF8 { 0x20000000 } |
342
|
55
|
50
|
|
|
|
214
|
if ($] >= 5.008001) { |
343
|
55
|
|
|
|
|
1157
|
B->import(qw(SVt_PVGV CVf_WEAKOUTSIDE)); # added with 5.8.1 |
344
|
|
|
|
|
|
|
} else { |
345
|
0
|
|
|
|
|
0
|
eval q[sub SVt_PVGV() {13}]; |
346
|
0
|
|
|
|
|
0
|
eval q[sub CVf_WEAKOUTSIDE() { 0x0 }]; # unused |
347
|
|
|
|
|
|
|
} |
348
|
55
|
50
|
|
|
|
135
|
if ($] >= 5.010) { |
349
|
|
|
|
|
|
|
#require mro; # mro->import(); |
350
|
|
|
|
|
|
|
# not exported: |
351
|
0
|
|
|
0
|
0
|
0
|
sub SVf_OOK { 0x02000000 } |
352
|
55
|
|
|
|
|
2226
|
eval q[sub SVs_GMG() { 0x00200000 } |
353
|
|
|
|
|
|
|
sub SVs_SMG() { 0x00400000 }]; |
354
|
55
|
50
|
|
|
|
172
|
if ($] >= 5.018) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
355
|
55
|
|
|
|
|
985
|
B->import(qw(PMf_EVAL RXf_EVAL_SEEN)); |
356
|
55
|
|
|
|
|
1419
|
eval q[sub PMf_ONCE(){ 0x10000 }]; # PMf_ONCE also not exported |
357
|
|
|
|
|
|
|
} elsif ($] >= 5.014) { |
358
|
0
|
|
|
|
|
0
|
eval q[sub PMf_ONCE(){ 0x8000 }]; |
359
|
|
|
|
|
|
|
} elsif ($] >= 5.012) { |
360
|
0
|
|
|
|
|
0
|
eval q[sub PMf_ONCE(){ 0x0080 }]; |
361
|
|
|
|
|
|
|
} else { # 5.10. not used with <= 5.8 |
362
|
0
|
|
|
|
|
0
|
eval q[sub PMf_ONCE(){ 0x0002 }]; |
363
|
|
|
|
|
|
|
} |
364
|
55
|
50
|
|
|
|
175
|
if ($] > 5.021006) { |
365
|
55
|
|
|
|
|
1028
|
B->import(qw(SVf_PROTECT CVf_ANONCONST SVs_PADSTALE)); |
366
|
|
|
|
|
|
|
} else { |
367
|
0
|
|
|
|
|
0
|
eval q[sub SVf_PROTECT() { 0x0 } |
368
|
|
|
|
|
|
|
sub CVf_ANONCONST(){ 0x0 } |
369
|
|
|
|
|
|
|
sub SVs_PADSTALE() { 0x0 } |
370
|
|
|
|
|
|
|
]; # unused |
371
|
|
|
|
|
|
|
} |
372
|
|
|
|
|
|
|
} else { |
373
|
0
|
|
|
|
|
0
|
eval q[sub SVs_GMG() { 0x00002000 } |
374
|
|
|
|
|
|
|
sub SVs_SMG() { 0x00004000 } |
375
|
|
|
|
|
|
|
sub SVf_PROTECT(){ 0x0 } |
376
|
|
|
|
|
|
|
sub CVf_ANONCONST(){ 0x0 } |
377
|
|
|
|
|
|
|
sub SVs_PADSTALE() { 0x0 } |
378
|
|
|
|
|
|
|
]; # unused |
379
|
|
|
|
|
|
|
} |
380
|
55
|
50
|
|
|
|
143
|
if ($] < 5.018) { |
381
|
0
|
|
|
|
|
0
|
eval q[sub RXf_EVAL_SEEN() { 0x0 } |
382
|
|
|
|
|
|
|
sub PMf_EVAL() { 0x0 } |
383
|
|
|
|
|
|
|
sub SVf_IsCOW() { 0x0 } |
384
|
|
|
|
|
|
|
]; # unused |
385
|
|
|
|
|
|
|
} else { |
386
|
|
|
|
|
|
|
# 5.18 |
387
|
55
|
|
|
|
|
767
|
B->import(qw(SVf_IsCOW)); |
388
|
|
|
|
|
|
|
#if (exists ${B::}{PADNAME::}) { |
389
|
55
|
|
|
|
|
496
|
@B::PADNAME::ISA = qw(B::PV); |
390
|
|
|
|
|
|
|
#} |
391
|
|
|
|
|
|
|
#if (exists ${B::}{PADLIST::}) { |
392
|
55
|
|
|
|
|
588
|
@B::PADLIST::ISA = qw(B::AV); |
393
|
|
|
|
|
|
|
#} |
394
|
|
|
|
|
|
|
#if (exists ${B::}{PADNAMELIST::}) { |
395
|
55
|
50
|
|
|
|
209
|
if ($] > 5.021005) { # 5.22 |
396
|
55
|
|
|
|
|
266
|
@B::PADNAME::ISA = (); |
397
|
55
|
|
|
|
|
422
|
@B::PADNAMELIST::ISA = qw(B::AV); |
398
|
|
|
|
|
|
|
} |
399
|
55
|
50
|
33
|
|
|
1303
|
if ($Config{usecperl} and $] >= 5.022002) { |
400
|
0
|
|
|
|
|
0
|
eval q[sub SVpav_REAL () { 0x40000000 } |
401
|
|
|
|
|
|
|
sub SVpav_REIFY (){ 0x80000000 } |
402
|
|
|
|
|
|
|
]; |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
} |
405
|
|
|
|
|
|
|
} |
406
|
55
|
|
|
55
|
|
22427
|
use B::Asmdata qw(@specialsv_name); |
|
55
|
|
|
|
|
107
|
|
|
55
|
|
|
|
|
5116
|
|
407
|
|
|
|
|
|
|
|
408
|
55
|
|
|
55
|
|
23595
|
use FileHandle; |
|
55
|
|
|
|
|
413204
|
|
|
55
|
|
|
|
|
266
|
|
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
my $hv_index = 0; |
411
|
|
|
|
|
|
|
my $gv_index = 0; |
412
|
|
|
|
|
|
|
my $re_index = 0; |
413
|
|
|
|
|
|
|
my $pv_index = 0; |
414
|
|
|
|
|
|
|
my $cv_index = 0; |
415
|
|
|
|
|
|
|
my $hek_index = 0; |
416
|
|
|
|
|
|
|
my $anonsub_index = 0; |
417
|
|
|
|
|
|
|
my $initsub_index = 0; |
418
|
|
|
|
|
|
|
my $padlist_index = 0; |
419
|
|
|
|
|
|
|
my $padname_index = 0; |
420
|
|
|
|
|
|
|
my $padnl_index = 0; |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
# exclude all not B::C:: prefixed subs |
423
|
|
|
|
|
|
|
my %all_bc_subs = map {$_=>1} |
424
|
|
|
|
|
|
|
qw(B::AV::save B::BINOP::save B::BM::save B::COP::save B::CV::save |
425
|
|
|
|
|
|
|
B::FAKEOP::fake_ppaddr B::FAKEOP::flags B::FAKEOP::new B::FAKEOP::next |
426
|
|
|
|
|
|
|
B::FAKEOP::ppaddr B::FAKEOP::private B::FAKEOP::save B::FAKEOP::sibling |
427
|
|
|
|
|
|
|
B::FAKEOP::targ B::FAKEOP::type B::GV::save B::GV::savecv B::HV::save |
428
|
|
|
|
|
|
|
B::IO::save B::IO::save_data B::IV::save B::LISTOP::save B::LOGOP::save |
429
|
|
|
|
|
|
|
B::LOOP::save B::NULL::save B::NV::save B::OBJECT::save |
430
|
|
|
|
|
|
|
B::OP::_save_common B::OP::fake_ppaddr B::OP::isa B::OP::save |
431
|
|
|
|
|
|
|
B::PADOP::save B::PMOP::save B::PV::save |
432
|
|
|
|
|
|
|
B::PVIV::save B::PVLV::save B::PVMG::save B::PVMG::save_magic B::PVNV::save |
433
|
|
|
|
|
|
|
B::PVOP::save B::REGEXP::save B::RV::save B::SPECIAL::save B::SPECIAL::savecv |
434
|
|
|
|
|
|
|
B::SV::save B::SVOP::save B::UNOP::save B::UV::save B::REGEXP::EXTFLAGS); |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
# track all internally used packages. all other may not be deleted automatically |
437
|
|
|
|
|
|
|
# - hidden methods |
438
|
|
|
|
|
|
|
# uses now @B::C::Config::deps |
439
|
|
|
|
|
|
|
our %all_bc_deps = map {$_=>1} |
440
|
|
|
|
|
|
|
@B::C::Config::deps ? @B::C::Config::deps |
441
|
|
|
|
|
|
|
: qw(AnyDBM_File AutoLoader B B::AV B::Asmdata B::BINOP B::BM B::C B::C::Config B::C::InitSection B::C::Section B::CC B::COP B::CV B::FAKEOP B::FM B::GV B::HE B::HV B::IO B::IV B::LEXWARN B::LISTOP B::LOGOP B::LOOP B::MAGIC B::NULL B::NV B::OBJECT B::OP B::PADLIST B::PADNAME B::PADNAMELIST B::PADOP B::PMOP B::PV B::PVIV B::PVLV B::PVMG B::PVNV B::PVOP B::REGEXP B::RHE B::RV B::SPECIAL B::STASHGV B::SV B::SVOP B::UNOP B::UV CORE CORE::GLOBAL Carp DB DynaLoader Errno Exporter Exporter::Heavy ExtUtils ExtUtils::Constant ExtUtils::Constant::ProxySubs Fcntl FileHandle IO IO::File IO::Handle IO::Poll IO::Seekable IO::Socket Internals O POSIX PerlIO PerlIO::Layer PerlIO::scalar Regexp SelectSaver Symbol UNIVERSAL XSLoader __ANON__ arybase arybase::mg base fields main maybe maybe::next mro next overload re strict threads utf8 vars version warnings warnings::register); |
442
|
|
|
|
|
|
|
$all_bc_deps{Socket} = 1 if !@B::C::Config::deps and $] > 5.021; |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
# B::C stash footprint: mainly caused by blib, warnings, and Carp loaded with DynaLoader |
445
|
|
|
|
|
|
|
# perl5.15.7d-nt -MO=C,-o/dev/null -MO=Stash -e0 |
446
|
|
|
|
|
|
|
# -umain,-ure,-umro,-ustrict,-uAnyDBM_File,-uFcntl,-uRegexp,-uoverload,-uErrno,-uExporter,-uExporter::Heavy,-uConfig,-uwarnings,-uwarnings::register,-uDB,-unext,-umaybe,-umaybe::next,-uFileHandle,-ufields,-uvars,-uAutoLoader,-uCarp,-uSymbol,-uPerlIO,-uPerlIO::scalar,-uSelectSaver,-uExtUtils,-uExtUtils::Constant,-uExtUtils::Constant::ProxySubs,-uthreads,-ubase |
447
|
|
|
|
|
|
|
# perl5.15.7d-nt -MErrno -MO=Stash -e0 |
448
|
|
|
|
|
|
|
# -umain,-ure,-umro,-ustrict,-uRegexp,-uoverload,-uErrno,-uExporter,-uExporter::Heavy,-uwarnings,-uwarnings::register,-uConfig,-uDB,-uvars,-uCarp,-uPerlIO,-uthreads |
449
|
|
|
|
|
|
|
# perl5.15.7d-nt -Mblib -MO=Stash -e0 |
450
|
|
|
|
|
|
|
# -umain,-ure,-umro,-ustrict,-uCwd,-uRegexp,-uoverload,-uFile,-uFile::Spec,-uFile::Spec::Unix,-uDos,-uExporter,-uExporter::Heavy,-uConfig,-uwarnings,-uwarnings::register,-uDB,-uEPOC,-ublib,-uScalar,-uScalar::Util,-uvars,-uCarp,-uVMS,-uVMS::Filespec,-uVMS::Feature,-uWin32,-uPerlIO,-uthreads |
451
|
|
|
|
|
|
|
# perl -MO=Stash -e0 |
452
|
|
|
|
|
|
|
# -umain,-uTie,-uTie::Hash,-ure,-umro,-ustrict,-uRegexp,-uoverload,-uExporter,-uExporter::Heavy,-uwarnings,-uDB,-uCarp,-uPerlIO,-uthreads |
453
|
|
|
|
|
|
|
# pb -MB::Stash -e0 |
454
|
|
|
|
|
|
|
# -umain,-ure,-umro,-uRegexp,-uPerlIO,-uExporter,-uDB |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
my ($prev_op, $package_pv, @package_pv); # global stash for methods since 5.13 |
457
|
|
|
|
|
|
|
my (%symtable, %cvforward, %lexwarnsym); |
458
|
|
|
|
|
|
|
my (%strtable, %stashtable, %hektable, %statichektable, %gptable, %cophhtable, %copgvtable); |
459
|
|
|
|
|
|
|
my (%xsub, %init2_remap); |
460
|
|
|
|
|
|
|
my ($warn_undefined_syms, $swash_init, $swash_ToCf); |
461
|
|
|
|
|
|
|
my ($staticxs, $outfile); |
462
|
|
|
|
|
|
|
my (%include_package, %dumped_package, %skip_package, %isa_cache, %static_ext); |
463
|
|
|
|
|
|
|
my ($use_xsloader, $Devel_Peek_Dump_added); |
464
|
|
|
|
|
|
|
my $nullop_count = 0; |
465
|
|
|
|
|
|
|
my $unresolved_count = 0; |
466
|
|
|
|
|
|
|
# options and optimizations shared with B::CC |
467
|
|
|
|
|
|
|
our ($module, $init_name, %savINC, %curINC, $mainfile, @static_free); |
468
|
|
|
|
|
|
|
our ($use_av_undef_speedup, $use_svpop_speedup) = (1, 1); |
469
|
|
|
|
|
|
|
our ($optimize_ppaddr, $optimize_warn_sv, $use_perl_script_name, |
470
|
|
|
|
|
|
|
$save_data_fh, $save_sig, $optimize_cop, $av_init, $av_init2, $ro_inc, $destruct, |
471
|
|
|
|
|
|
|
$fold, $warnings, $const_strings, $stash, $can_delete_pkg, $pv_copy_on_grow, $dyn_padlist, |
472
|
|
|
|
|
|
|
$walkall, $cow); |
473
|
|
|
|
|
|
|
our $verbose = 0; |
474
|
|
|
|
|
|
|
our %option_map = ( |
475
|
|
|
|
|
|
|
#ignored until IsCOW has a seperate COWREFCNT field (5.22 maybe) |
476
|
|
|
|
|
|
|
'cog' => \$B::C::pv_copy_on_grow, |
477
|
|
|
|
|
|
|
'const-strings' => \$B::C::const_strings, |
478
|
|
|
|
|
|
|
'save-data' => \$B::C::save_data_fh, |
479
|
|
|
|
|
|
|
'ppaddr' => \$B::C::optimize_ppaddr, |
480
|
|
|
|
|
|
|
'walkall' => \$B::C::walkall, |
481
|
|
|
|
|
|
|
'warn-sv' => \$B::C::optimize_warn_sv, |
482
|
|
|
|
|
|
|
'av-init' => \$B::C::av_init, |
483
|
|
|
|
|
|
|
'av-init2' => \$B::C::av_init2, |
484
|
|
|
|
|
|
|
'delete-pkg' => \$B::C::can_delete_pkg, |
485
|
|
|
|
|
|
|
'ro-inc' => \$B::C::ro_inc, |
486
|
|
|
|
|
|
|
# if to disable the COW flag since 5.18 |
487
|
|
|
|
|
|
|
'cow' => \$B::C::cow, # enable with -O2 |
488
|
|
|
|
|
|
|
'stash' => \$B::C::stash, # enable with -fstash |
489
|
|
|
|
|
|
|
'destruct' => \$B::C::destruct, # disable with -fno-destruct |
490
|
|
|
|
|
|
|
'fold' => \$B::C::fold, # disable with -fno-fold |
491
|
|
|
|
|
|
|
'warnings' => \$B::C::warnings, # disable with -fno-warnings |
492
|
|
|
|
|
|
|
'use-script-name' => \$use_perl_script_name, |
493
|
|
|
|
|
|
|
'save-sig-hash' => \$B::C::save_sig, |
494
|
|
|
|
|
|
|
'dyn-padlist' => \$B::C::dyn_padlist, # with -O4, needed for cv cleanup with non-local exits since 5.18 |
495
|
|
|
|
|
|
|
'cop' => \$optimize_cop, # XXX very unsafe! |
496
|
|
|
|
|
|
|
# Better do it in CC, but get rid of |
497
|
|
|
|
|
|
|
# NULL cops also there. |
498
|
|
|
|
|
|
|
); |
499
|
|
|
|
|
|
|
our %optimization_map = ( |
500
|
|
|
|
|
|
|
0 => [qw()], # special case |
501
|
|
|
|
|
|
|
1 => [qw(-fppaddr -fav-init2)], # falls back to -fav-init |
502
|
|
|
|
|
|
|
2 => [qw(-fro-inc -fsave-data)], |
503
|
|
|
|
|
|
|
3 => [qw(-fno-destruct -fconst-strings -fno-fold -fno-warnings)], |
504
|
|
|
|
|
|
|
4 => [qw(-fcop -fno-dyn-padlist)], |
505
|
|
|
|
|
|
|
); |
506
|
|
|
|
|
|
|
push @{$optimization_map{2}}, '-fcow' if $] >= 5.020; |
507
|
|
|
|
|
|
|
our %debug_map = ( |
508
|
|
|
|
|
|
|
'O' => 'op', |
509
|
|
|
|
|
|
|
'A' => 'av', |
510
|
|
|
|
|
|
|
'H' => 'hv', |
511
|
|
|
|
|
|
|
'C' => 'cv', |
512
|
|
|
|
|
|
|
'M' => 'mg', |
513
|
|
|
|
|
|
|
'R' => 'rx', |
514
|
|
|
|
|
|
|
'G' => 'gv', |
515
|
|
|
|
|
|
|
'S' => 'sv', |
516
|
|
|
|
|
|
|
'P' => 'pv', |
517
|
|
|
|
|
|
|
'W' => 'walk', |
518
|
|
|
|
|
|
|
'c' => 'cops', |
519
|
|
|
|
|
|
|
's' => 'sub', |
520
|
|
|
|
|
|
|
'p' => 'pkg', |
521
|
|
|
|
|
|
|
# 'm' => 'meth', |
522
|
|
|
|
|
|
|
'u' => 'unused', |
523
|
|
|
|
|
|
|
); |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
my @xpvav_sizes; |
526
|
|
|
|
|
|
|
my ($max_string_len, $in_endav); |
527
|
|
|
|
|
|
|
my %static_core_pkg; # = map {$_ => 1} static_core_packages(); |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
my $MULTI = $Config{usemultiplicity}; |
530
|
|
|
|
|
|
|
my $ITHREADS = $Config{useithreads}; |
531
|
|
|
|
|
|
|
my $DEBUGGING = ($Config{ccflags} =~ m/-DDEBUGGING/); |
532
|
|
|
|
|
|
|
my $DEBUG_LEAKING_SCALARS = $Config{ccflags} =~ m/-DDEBUG_LEAKING_SCALARS/; |
533
|
|
|
|
|
|
|
my $CPERL56 = ( $Config{usecperl} and $] >= 5.025003 ); #sibparent, xpad_cop_seq |
534
|
|
|
|
|
|
|
my $CPERL55 = ( $Config{usecperl} and $] >= 5.025001 ); #HVMAX_T, RITER_T, ... |
535
|
|
|
|
|
|
|
my $CPERL52 = ( $Config{usecperl} and $] >= 5.022002 ); #sv_objcount, AvSTATIC, sigs |
536
|
|
|
|
|
|
|
my $CPERL51 = ( $Config{usecperl} ); |
537
|
|
|
|
|
|
|
my $PERL524 = ( $] >= 5.023005 ); #xpviv sharing assertion |
538
|
|
|
|
|
|
|
my $PERL522 = ( $] >= 5.021006 ); #PADNAMELIST, IsCOW, padname_with_str, compflags |
539
|
|
|
|
|
|
|
my $PERL518 = ( $] >= 5.017010 ); |
540
|
|
|
|
|
|
|
my $PERL514 = ( $] >= 5.013002 ); |
541
|
|
|
|
|
|
|
my $PERL512 = ( $] >= 5.011 ); |
542
|
|
|
|
|
|
|
my $PERL510 = ( $] >= 5.009005 ); |
543
|
|
|
|
|
|
|
my $PERL56 = ( $] < 5.008001 ); # yes. 5.8.0 is a 5.6.x |
544
|
|
|
|
|
|
|
#my $C99 = $Config{d_c99_variadic_macros}; # http://docs.sun.com/source/819-3688/c99.app.html#pgfId-1003962 |
545
|
|
|
|
|
|
|
my $MAD = $Config{mad}; |
546
|
|
|
|
|
|
|
my $MYMALLOC = $Config{usemymalloc} eq 'define'; |
547
|
|
|
|
|
|
|
my $HAVE_DLFCN_DLOPEN = $Config{i_dlfcn} && $Config{d_dlopen}; |
548
|
|
|
|
|
|
|
# %Lu is not supported on older 32bit systems |
549
|
|
|
|
|
|
|
my $u32fmt = $Config{ivsize} == 4 ? "%lu" : "%u"; |
550
|
0
|
0
|
|
0
|
0
|
0
|
sub IS_MSVC () { $^O eq 'MSWin32' and $Config{cc} eq 'cl' } |
551
|
|
|
|
|
|
|
my $have_sibparent = ($] >= 5.025006 |
552
|
|
|
|
|
|
|
or $Config{ccflags} =~ /-DPERL_OP_PARENT/ |
553
|
|
|
|
|
|
|
or ($CPERL55 && $] >= 5.025003)) ? 1 : 0; |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
my @threadsv_names; |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
BEGIN { |
558
|
55
|
|
|
55
|
|
106387
|
@threadsv_names = threadsv_names(); |
559
|
|
|
|
|
|
|
} |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
# This the Carp free workaround for DynaLoader::bootstrap |
562
|
0
|
|
|
0
|
0
|
0
|
sub DynaLoader::croak {die @_} |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
# needed for init2 remap and Dynamic annotation |
565
|
|
|
|
|
|
|
sub dl_module_to_sofile { |
566
|
0
|
0
|
|
0
|
0
|
0
|
my $module = shift or die "missing module name"; |
567
|
0
|
0
|
|
|
|
0
|
my $modlibname = shift or die "missing module filepath"; |
568
|
0
|
|
|
|
|
0
|
my @modparts = split(/::/,$module); |
569
|
0
|
|
|
|
|
0
|
my $modfname = $modparts[-1]; |
570
|
0
|
|
|
|
|
0
|
my $modpname = join('/',@modparts); |
571
|
0
|
|
|
|
|
0
|
my $c = @modparts; |
572
|
0
|
|
|
|
|
0
|
$modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename |
573
|
0
|
0
|
|
|
|
0
|
die "missing module filepath" unless $modlibname; |
574
|
0
|
|
|
|
|
0
|
my $sofile = "$modlibname/auto/$modpname/$modfname.".$Config{dlext}; |
575
|
0
|
|
|
|
|
0
|
return $sofile; |
576
|
|
|
|
|
|
|
} |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
# 5.15.3 workaround [perl #101336], without .bs support |
579
|
|
|
|
|
|
|
# XSLoader::load_file($module, $modlibname, ...) |
580
|
|
|
|
|
|
|
my $dlext = $Config{dlext}; |
581
|
0
|
0
|
0
|
0
|
0
|
0
|
eval q| |
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
0
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
582
|
|
|
|
|
|
|
sub XSLoader::load_file { |
583
|
|
|
|
|
|
|
#package DynaLoader; |
584
|
|
|
|
|
|
|
my $module = shift or die "missing module name"; |
585
|
|
|
|
|
|
|
my $modlibname = shift or die "missing module filepath"; |
586
|
|
|
|
|
|
|
print STDOUT "XSLoader::load_file(\"$module\", \"$modlibname\" @_)\n" |
587
|
|
|
|
|
|
|
if ${DynaLoader::dl_debug}; |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
push @_, $module; |
590
|
|
|
|
|
|
|
# works with static linking too |
591
|
|
|
|
|
|
|
my $boots = "$module\::bootstrap"; |
592
|
|
|
|
|
|
|
goto &$boots if defined &$boots; |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
my @modparts = split(/::/,$module); # crashes threaded, issue 100 |
595
|
|
|
|
|
|
|
my $modfname = $modparts[-1]; |
596
|
|
|
|
|
|
|
my $modpname = join('/',@modparts); |
597
|
|
|
|
|
|
|
my $c = @modparts; |
598
|
|
|
|
|
|
|
$modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename |
599
|
|
|
|
|
|
|
die "missing module filepath" unless $modlibname; |
600
|
|
|
|
|
|
|
my $file = "$modlibname/auto/$modpname/$modfname."|.qq(."$dlext").q|; |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
# skip the .bs "bullshit" part, needed for some old solaris ages ago |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
print STDOUT "goto DynaLoader::bootstrap_inherit\n" |
605
|
|
|
|
|
|
|
if ${DynaLoader::dl_debug} and not -f $file; |
606
|
|
|
|
|
|
|
goto \&DynaLoader::bootstrap_inherit if not -f $file; |
607
|
|
|
|
|
|
|
my $modxsname = $module; |
608
|
|
|
|
|
|
|
$modxsname =~ s/\W/_/g; |
609
|
|
|
|
|
|
|
my $bootname = "boot_".$modxsname; |
610
|
|
|
|
|
|
|
@DynaLoader::dl_require_symbols = ($bootname); |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
my $boot_symbol_ref; |
613
|
|
|
|
|
|
|
if ($boot_symbol_ref = DynaLoader::dl_find_symbol(0, $bootname)) { |
614
|
|
|
|
|
|
|
print STDOUT "dl_find_symbol($bootname) ok => goto boot\n" |
615
|
|
|
|
|
|
|
if ${DynaLoader::dl_debug}; |
616
|
|
|
|
|
|
|
goto boot; #extension library has already been loaded, e.g. darwin |
617
|
|
|
|
|
|
|
} |
618
|
|
|
|
|
|
|
# Many dynamic extension loading problems will appear to come from |
619
|
|
|
|
|
|
|
# this section of code: XYZ failed at line 123 of DynaLoader.pm. |
620
|
|
|
|
|
|
|
# Often these errors are actually occurring in the initialisation |
621
|
|
|
|
|
|
|
# C code of the extension XS file. Perl reports the error as being |
622
|
|
|
|
|
|
|
# in this perl code simply because this was the last perl code |
623
|
|
|
|
|
|
|
# it executed. |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
my $libref = DynaLoader::dl_load_file($file, 0) or do { |
626
|
|
|
|
|
|
|
die("Can't load '$file' for module $module: " . DynaLoader::dl_error()); |
627
|
|
|
|
|
|
|
}; |
628
|
|
|
|
|
|
|
push(@DynaLoader::dl_librefs,$libref); # record loaded object |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
my @unresolved = DynaLoader::dl_undef_symbols(); |
631
|
|
|
|
|
|
|
if (@unresolved) { |
632
|
|
|
|
|
|
|
die("Undefined symbols present after loading $file: @unresolved\n"); |
633
|
|
|
|
|
|
|
} |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
$boot_symbol_ref = DynaLoader::dl_find_symbol($libref, $bootname) or do { |
636
|
|
|
|
|
|
|
die("Can't find '$bootname' symbol in $file\n"); |
637
|
|
|
|
|
|
|
}; |
638
|
|
|
|
|
|
|
print STDOUT "dl_find_symbol($libref, $bootname) ok => goto boot\n" |
639
|
|
|
|
|
|
|
if ${DynaLoader::dl_debug}; |
640
|
|
|
|
|
|
|
push(@DynaLoader::dl_modules, $module); # record loaded module |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
boot: |
643
|
|
|
|
|
|
|
my $xs = DynaLoader::dl_install_xsub($boots, $boot_symbol_ref, $file); |
644
|
|
|
|
|
|
|
print STDOUT "dl_install_xsub($boots, $boot_symbol_ref, $file)\n" |
645
|
|
|
|
|
|
|
if ${DynaLoader::dl_debug}; |
646
|
|
|
|
|
|
|
# See comment block above |
647
|
|
|
|
|
|
|
push(@DynaLoader::dl_shared_objects, $file); # record files loaded |
648
|
|
|
|
|
|
|
return &$xs(@_); |
649
|
|
|
|
|
|
|
} |
650
|
|
|
|
|
|
|
| if $] >= 5.015003 and !$CPERL51; |
651
|
|
|
|
|
|
|
# Note: cperl uses a different API: the 2nd arg is the sofile directly |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
# Code sections |
654
|
|
|
|
|
|
|
my ( |
655
|
|
|
|
|
|
|
$init, $decl, $symsect, $binopsect, $condopsect, |
656
|
|
|
|
|
|
|
$copsect, $padopsect, $listopsect, $logopsect, $loopsect, |
657
|
|
|
|
|
|
|
$opsect, $pmopsect, $pvopsect, $svopsect, $unopsect, |
658
|
|
|
|
|
|
|
$methopsect, $unopauxsect, |
659
|
|
|
|
|
|
|
$svsect, $xpvsect, $xpvavsect, $xpvhvsect, $xpvcvsect, |
660
|
|
|
|
|
|
|
$xpvivsect, $xpvuvsect, $xpvnvsect, $xpvmgsect, $xpvlvsect, |
661
|
|
|
|
|
|
|
$xrvsect, $xpvbmsect, $xpviosect, $heksect, $free, |
662
|
|
|
|
|
|
|
$padlistsect, $padnamesect, $padnlsect, $init0, $init1, $init2 |
663
|
|
|
|
|
|
|
); |
664
|
|
|
|
|
|
|
my (%padnamesect, %avcowsect, %avcogsect); |
665
|
|
|
|
|
|
|
my @padnamesect_sizes = (8, 16, 24, 32, 40, 48, 56, 64); |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
my @op_sections = |
668
|
|
|
|
|
|
|
\( |
669
|
|
|
|
|
|
|
$binopsect, $condopsect, $copsect, $padopsect, |
670
|
|
|
|
|
|
|
$listopsect, $logopsect, $loopsect, $opsect, |
671
|
|
|
|
|
|
|
$pmopsect, $pvopsect, $svopsect, $unopsect, |
672
|
|
|
|
|
|
|
$methopsect, $unopauxsect |
673
|
|
|
|
|
|
|
); |
674
|
|
|
|
|
|
|
# push @op_sections, ($resect) if $PERL512; |
675
|
|
|
|
|
|
|
sub walk_and_save_optree; |
676
|
|
|
|
|
|
|
my $saveoptree_callback = \&walk_and_save_optree; |
677
|
14
|
|
|
14
|
0
|
105034
|
sub set_callback { $saveoptree_callback = shift } |
678
|
0
|
|
|
0
|
0
|
0
|
sub saveoptree { &$saveoptree_callback(@_) } |
679
|
|
|
|
|
|
|
sub save_main_rest; |
680
|
0
|
0
|
|
0
|
0
|
0
|
sub verbose { if (@_) { $verbose = shift; } else { $verbose; } } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
681
|
0
|
0
|
|
0
|
0
|
0
|
sub module { if (@_) { $module = shift; } else { $module; } } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
sub walk_and_save_optree { |
684
|
0
|
|
|
0
|
0
|
0
|
my ( $name, $root, $start ) = @_; |
685
|
0
|
0
|
|
|
|
0
|
if ($root) { |
686
|
|
|
|
|
|
|
# B.xs: walkoptree does more, reifying refs. rebless or recreating it. |
687
|
|
|
|
|
|
|
# TODO: add walkoptree_debug support. |
688
|
0
|
0
|
|
|
|
0
|
$verbose ? walkoptree_slow( $root, "save" ) : walkoptree( $root, "save" ); |
689
|
|
|
|
|
|
|
} |
690
|
0
|
|
|
|
|
0
|
return objsym($start); |
691
|
|
|
|
|
|
|
} |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
# Look this up here so we can do just a number compare |
694
|
|
|
|
|
|
|
# rather than looking up the name of every BASEOP in B::OP |
695
|
|
|
|
|
|
|
my $OP_THREADSV = opnumber('threadsv'); |
696
|
|
|
|
|
|
|
my $OP_DBMOPEN = opnumber('dbmopen'); |
697
|
|
|
|
|
|
|
my $OP_FORMLINE = opnumber('formline'); |
698
|
|
|
|
|
|
|
my $OP_UCFIRST = opnumber('ucfirst'); |
699
|
|
|
|
|
|
|
my $OP_CUSTOM = opnumber('custom'); |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
# special handling for nullified COP's. |
702
|
|
|
|
|
|
|
my %OP_COP = ( opnumber('nextstate') => 1 ); |
703
|
|
|
|
|
|
|
$OP_COP{ opnumber('setstate') } = 1 if $] > 5.005003 and $] < 5.005062; |
704
|
|
|
|
|
|
|
$OP_COP{ opnumber('dbstate') } = 1 unless $PERL512; |
705
|
|
|
|
|
|
|
warn %OP_COP if $debug{cops}; |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
# 1. called from method_named, so hashp should be defined |
708
|
|
|
|
|
|
|
# 2. called from svop before method_named to cache the $package_pv |
709
|
|
|
|
|
|
|
sub svop_or_padop_pv { |
710
|
0
|
|
|
0
|
0
|
0
|
my $op = shift; |
711
|
0
|
|
|
|
|
0
|
my $sv; |
712
|
0
|
0
|
|
|
|
0
|
if (!$op->can("sv")) { |
713
|
0
|
0
|
0
|
|
|
0
|
if ($op->can('name') and $op->name eq 'padsv') { |
714
|
0
|
|
|
|
|
0
|
my @c = comppadlist->ARRAY; |
715
|
0
|
|
|
|
|
0
|
my @pad = $c[1]->ARRAY; |
716
|
0
|
0
|
0
|
|
|
0
|
return $pad[$op->targ]->PV if $pad[$op->targ] and $pad[$op->targ]->can("PV"); |
717
|
|
|
|
|
|
|
# This might fail with B::NULL (optimized ex-const pv) entries in the pad. |
718
|
|
|
|
|
|
|
} |
719
|
|
|
|
|
|
|
# $op->can('pmreplroot') fails for 5.14 |
720
|
0
|
0
|
0
|
|
|
0
|
if (ref($op) eq 'B::PMOP' and $op->pmreplroot->can("sv")) { |
721
|
0
|
|
|
|
|
0
|
$sv = $op->pmreplroot->sv; |
722
|
|
|
|
|
|
|
} else { |
723
|
0
|
0
|
|
|
|
0
|
return $package_pv unless $op->flags & 4; |
724
|
|
|
|
|
|
|
# op->first is disallowed for !KIDS and OPpCONST_BARE |
725
|
0
|
0
|
0
|
|
|
0
|
return $package_pv if $op->name eq 'const' and $op->flags & 64; |
726
|
0
|
0
|
|
|
|
0
|
return $package_pv unless $op->first->can("sv"); |
727
|
0
|
|
|
|
|
0
|
$sv = $op->first->sv; |
728
|
|
|
|
|
|
|
} |
729
|
|
|
|
|
|
|
} else { |
730
|
0
|
|
|
|
|
0
|
$sv = $op->sv; |
731
|
|
|
|
|
|
|
} |
732
|
|
|
|
|
|
|
# XXX see SvSHARED_HEK_FROM_PV for the stash in S_method_common pp_hot.c |
733
|
|
|
|
|
|
|
# In this hash the CV is stored directly |
734
|
0
|
0
|
0
|
|
|
0
|
if ($sv and $$sv) { |
735
|
|
|
|
|
|
|
#if ($PERL510) { # PVX->hek_hash - STRUCT_OFFSET(struct hek, hek_key) |
736
|
|
|
|
|
|
|
#} else { # UVX |
737
|
|
|
|
|
|
|
#} |
738
|
0
|
0
|
|
|
|
0
|
return $sv->PV if $sv->can("PV"); |
739
|
0
|
0
|
|
|
|
0
|
if (ref($sv) eq "B::SPECIAL") { # DateTime::TimeZone |
740
|
|
|
|
|
|
|
# XXX null -> method_named |
741
|
0
|
0
|
|
|
|
0
|
warn "NYI S_method_common op->sv==B::SPECIAL, keep $package_pv\n" if $debug{gv}; |
742
|
0
|
|
|
|
|
0
|
return $package_pv; |
743
|
|
|
|
|
|
|
} |
744
|
0
|
0
|
|
|
|
0
|
if ($sv->FLAGS & SVf_ROK) { |
745
|
0
|
0
|
|
|
|
0
|
goto missing if $sv->isa("B::NULL"); |
746
|
0
|
|
|
|
|
0
|
my $rv = $sv->RV; |
747
|
0
|
0
|
|
|
|
0
|
if ($rv->isa("B::PVGV")) { |
748
|
0
|
|
|
|
|
0
|
my $o = $rv->IO; |
749
|
0
|
0
|
|
|
|
0
|
return $o->STASH->NAME if $$o; |
750
|
|
|
|
|
|
|
} |
751
|
0
|
0
|
|
|
|
0
|
goto missing if $rv->isa("B::PVMG"); |
752
|
0
|
|
|
|
|
0
|
return $rv->STASH->NAME; |
753
|
|
|
|
|
|
|
} else { |
754
|
|
|
|
|
|
|
missing: |
755
|
0
|
0
|
|
|
|
0
|
if ($op->name ne 'method_named') { |
|
|
0
|
|
|
|
|
|
756
|
|
|
|
|
|
|
# Called from first const/padsv before method_named. no magic pv string, so a method arg. |
757
|
|
|
|
|
|
|
# The first const pv as method_named arg is always the $package_pv. |
758
|
0
|
|
|
|
|
0
|
return $package_pv; |
759
|
|
|
|
|
|
|
} elsif ($sv->isa("B::IV")) { |
760
|
0
|
|
|
|
|
0
|
warn sprintf("Experimentally try method_cv(sv=$sv,$package_pv) flags=0x%x", |
761
|
|
|
|
|
|
|
$sv->FLAGS); |
762
|
|
|
|
|
|
|
# XXX untested! |
763
|
0
|
|
|
|
|
0
|
return svref_2object(method_cv($$sv, $package_pv)); |
764
|
|
|
|
|
|
|
} |
765
|
|
|
|
|
|
|
} |
766
|
|
|
|
|
|
|
} else { |
767
|
0
|
|
|
|
|
0
|
my @c = comppadlist->ARRAY; |
768
|
0
|
|
|
|
|
0
|
my @pad = $c[1]->ARRAY; |
769
|
0
|
0
|
0
|
|
|
0
|
return $pad[$op->targ]->PV if $pad[$op->targ] and $pad[$op->targ]->can("PV"); |
770
|
|
|
|
|
|
|
} |
771
|
|
|
|
|
|
|
} |
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
sub IsCOW { |
774
|
0
|
0
|
|
0
|
0
|
0
|
if ($PERL522) { |
775
|
0
|
|
|
|
|
0
|
return $_[0]->FLAGS & SVf_IsCOW; |
776
|
|
|
|
|
|
|
} |
777
|
0
|
|
0
|
|
|
0
|
return ($] >= 5.017008 and $_[0]->FLAGS & SVf_IsCOW); # since 5.17.8 |
778
|
|
|
|
|
|
|
} |
779
|
|
|
|
|
|
|
sub IsCOW_hek { |
780
|
0
|
|
0
|
0
|
0
|
0
|
return IsCOW($_[0]) && !$_[0]->LEN; |
781
|
|
|
|
|
|
|
} |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
if ($Config{usecperl} and $] >= 5.022002) { |
784
|
|
|
|
|
|
|
eval q[sub isAvSTATIC { |
785
|
|
|
|
|
|
|
my $flags = shift->FLAGS; |
786
|
|
|
|
|
|
|
return !($flags & SVpav_REAL) && !($flags & SVpav_REIFY) |
787
|
|
|
|
|
|
|
}]; |
788
|
|
|
|
|
|
|
} else { |
789
|
|
|
|
|
|
|
eval q[sub isAvSTATIC () { 0 }]; |
790
|
|
|
|
|
|
|
} |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
sub canAvSTATIC { |
793
|
0
|
|
|
0
|
0
|
0
|
my ($av, $fullname) = @_; |
794
|
0
|
|
|
|
|
0
|
my $flags = $av->FLAGS; |
795
|
0
|
|
|
|
|
0
|
return 1; |
796
|
|
|
|
|
|
|
} |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
sub savesym { |
799
|
0
|
|
|
0
|
0
|
0
|
my ( $obj, $value ) = @_; |
800
|
55
|
|
|
55
|
|
322
|
no strict 'refs'; |
|
55
|
|
|
|
|
66
|
|
|
55
|
|
|
|
|
3942
|
|
801
|
0
|
|
|
|
|
0
|
my $sym = sprintf( "s\\_%x", $$obj ); |
802
|
0
|
|
|
|
|
0
|
$symtable{$sym} = $value; |
803
|
0
|
|
|
|
|
0
|
return $value; |
804
|
|
|
|
|
|
|
} |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
sub objsym { |
807
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
808
|
55
|
|
|
55
|
|
222
|
no strict 'refs'; |
|
55
|
|
|
|
|
75
|
|
|
55
|
|
|
|
|
17759
|
|
809
|
0
|
|
|
|
|
0
|
return $symtable{ sprintf( "s\\_%x", $$obj ) }; |
810
|
|
|
|
|
|
|
} |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
sub getsym { |
813
|
0
|
|
|
0
|
0
|
0
|
my $sym = shift; |
814
|
0
|
|
|
|
|
0
|
my $value; |
815
|
|
|
|
|
|
|
|
816
|
0
|
0
|
|
|
|
0
|
return 0 if $sym eq "sym_0"; # special case |
817
|
0
|
|
|
|
|
0
|
$value = $symtable{$sym}; |
818
|
0
|
0
|
|
|
|
0
|
if ( defined($value) ) { |
819
|
0
|
|
|
|
|
0
|
return $value; |
820
|
|
|
|
|
|
|
} |
821
|
|
|
|
|
|
|
else { |
822
|
0
|
0
|
|
|
|
0
|
warn "warning: undefined symbol $sym\n" if $warn_undefined_syms; |
823
|
0
|
|
|
|
|
0
|
return "UNUSED"; |
824
|
|
|
|
|
|
|
} |
825
|
|
|
|
|
|
|
} |
826
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
sub delsym { |
828
|
0
|
|
|
0
|
0
|
0
|
my ( $obj ) = @_; |
829
|
0
|
|
|
|
|
0
|
my $sym = sprintf( "s\\_%x", $$obj ); |
830
|
0
|
|
|
|
|
0
|
delete $symtable{$sym}; |
831
|
|
|
|
|
|
|
} |
832
|
|
|
|
|
|
|
|
833
|
0
|
|
|
0
|
0
|
0
|
sub curcv { $B::C::curcv } |
834
|
0
|
|
|
0
|
0
|
0
|
sub set_curcv($) { $B::C::curcv = shift; } |
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
# returns cstring, len, utf8 flags of a string |
837
|
|
|
|
|
|
|
sub strlen_flags { |
838
|
0
|
|
|
0
|
0
|
0
|
my $s = shift; |
839
|
0
|
|
|
|
|
0
|
my ($len, $flags) = (0,"0"); |
840
|
0
|
0
|
0
|
|
|
0
|
if (!$PERL56 and utf8::is_utf8($s)) { |
841
|
0
|
|
|
|
|
0
|
my $us = $s; |
842
|
0
|
|
|
|
|
0
|
$flags = 'SVf_UTF8'; |
843
|
0
|
|
|
|
|
0
|
$len = utf8::upgrade($us); |
844
|
|
|
|
|
|
|
} else { |
845
|
0
|
|
|
|
|
0
|
$len = length $s; |
846
|
|
|
|
|
|
|
} |
847
|
0
|
|
|
|
|
0
|
return (cstring($s), $len, $flags); |
848
|
|
|
|
|
|
|
} |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
sub savestash_flags { |
851
|
0
|
|
|
0
|
0
|
0
|
my ($name, $cstring, $len, $flags) = @_; |
852
|
0
|
0
|
|
|
|
0
|
return $stashtable{$name} if exists $stashtable{$name}; |
853
|
|
|
|
|
|
|
#return '(HV*)&PL_sv_undef' if $name =~ /^(|B::CC?)$/; # protect against empty stashes |
854
|
0
|
0
|
|
|
|
0
|
$flags = $flags ? "$flags|GV_ADD" : "GV_ADD"; |
855
|
0
|
|
|
|
|
0
|
my $sym = "hv$hv_index"; |
856
|
0
|
|
|
|
|
0
|
$decl->add("Static HV *$sym;"); |
857
|
0
|
|
|
|
|
0
|
$hv_index++; |
858
|
0
|
0
|
0
|
|
|
0
|
if ($PERL518 and $name) { # since 5.18 save @ISA before calling stashpv |
859
|
0
|
|
|
|
|
0
|
my @isa = get_isa($name); |
860
|
55
|
|
|
55
|
|
236
|
no strict 'refs'; |
|
55
|
|
|
|
|
67
|
|
|
55
|
|
|
|
|
46485
|
|
861
|
0
|
0
|
0
|
|
|
0
|
if (@isa and exists ${$name.'::'}{ISA} ) { |
|
0
|
|
|
|
|
0
|
|
862
|
0
|
|
|
|
|
0
|
svref_2object( \@{"$name\::ISA"} )->save("$name\::ISA"); |
|
0
|
|
|
|
|
0
|
|
863
|
|
|
|
|
|
|
} |
864
|
|
|
|
|
|
|
} |
865
|
0
|
0
|
|
|
|
0
|
my $pvsym = $len ? constpv($name) : '""'; |
866
|
0
|
|
|
|
|
0
|
$stashtable{$name} = $sym; |
867
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "%s = gv_stashpvn(%s, %u, %s); /* $name */", |
868
|
|
|
|
|
|
|
$sym, $pvsym, $len, $flags)); |
869
|
0
|
|
|
|
|
0
|
return $sym; |
870
|
|
|
|
|
|
|
} |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
sub savestashpv { |
873
|
0
|
|
|
0
|
0
|
0
|
my $name = shift; |
874
|
0
|
|
|
|
|
0
|
return savestash_flags($name, strlen_flags($name)); |
875
|
|
|
|
|
|
|
} |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
sub savere { |
878
|
0
|
|
|
0
|
0
|
0
|
my $re = shift; |
879
|
0
|
|
0
|
|
|
0
|
my $flags = shift || 0; |
880
|
0
|
|
|
|
|
0
|
my $sym; |
881
|
0
|
|
|
|
|
0
|
my $pv = $re; |
882
|
0
|
|
|
|
|
0
|
my ($cstring, $cur, $utf8) = strlen_flags($pv); |
883
|
0
|
|
|
|
|
0
|
my $len = 0; # static buffer |
884
|
0
|
0
|
|
|
|
0
|
if ($PERL514) { |
|
|
0
|
|
|
|
|
|
885
|
0
|
|
|
|
|
0
|
$xpvsect->add( sprintf( "Nullhv, {0}, %u, %u", $cur, $len ) ); |
886
|
0
|
0
|
|
|
|
0
|
$svsect->add( sprintf( "&xpv_list[%d], 1, %x, {%s}", $xpvsect->index, |
887
|
|
|
|
|
|
|
0x4405, ($C99?".svu_pv=":"").'(char*)'.savepv($pv) ) ); |
888
|
0
|
|
|
|
|
0
|
$sym = sprintf( "&sv_list[%d]", $svsect->index ); |
889
|
|
|
|
|
|
|
} |
890
|
|
|
|
|
|
|
elsif ($PERL510) { |
891
|
|
|
|
|
|
|
# BUG! Should be the same as newSVpvn($resym, $relen) but is not |
892
|
|
|
|
|
|
|
#$sym = sprintf("re_list[%d]", $re_index++); |
893
|
|
|
|
|
|
|
#$resect->add(sprintf("0,0,0,%s", $cstring)); |
894
|
0
|
0
|
|
|
|
0
|
my $s1 = ($PERL514 ? "NULL," : "") . "{0}, %u, %u"; |
895
|
0
|
|
|
|
|
0
|
$xpvsect->add( sprintf( $s1, $cur, $len ) ); |
896
|
0
|
0
|
|
|
|
0
|
$svsect->add( sprintf( "&xpv_list[%d], 1, %x, {%s}", $xpvsect->index, |
897
|
|
|
|
|
|
|
0x4405, ($C99?".svu_pv=":"").'(char*)'.savepv($pv) ) ); |
898
|
0
|
|
|
|
|
0
|
my $s = "sv_list[".$svsect->index."]"; |
899
|
0
|
|
|
|
|
0
|
$sym = "&$s"; |
900
|
0
|
0
|
|
|
|
0
|
push @B::C::static_free, $s if $len; # and $B::C::pv_copy_on_grow; |
901
|
|
|
|
|
|
|
# $resect->add(sprintf("&xpv_list[%d], $u32fmt, 0x%x", $xpvsect->index, 1, 0x4405)); |
902
|
|
|
|
|
|
|
} |
903
|
|
|
|
|
|
|
else { |
904
|
0
|
|
|
|
|
0
|
$sym = sprintf( "re%d", $re_index++ ); |
905
|
0
|
|
|
|
|
0
|
$decl->add( sprintf( "Static const char *%s = %s;", $sym, $cstring ) ); |
906
|
|
|
|
|
|
|
} |
907
|
0
|
|
|
|
|
0
|
return ( $sym, $cur ); |
908
|
|
|
|
|
|
|
} |
909
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
sub constpv { |
911
|
0
|
|
|
0
|
0
|
0
|
return savepv(shift, 1); |
912
|
|
|
|
|
|
|
} |
913
|
|
|
|
|
|
|
|
914
|
|
|
|
|
|
|
sub savepv { |
915
|
0
|
|
|
0
|
0
|
0
|
my $pv = shift; |
916
|
0
|
|
|
|
|
0
|
my $const = shift; |
917
|
0
|
|
|
|
|
0
|
my ($cstring, $cur, $utf8) = strlen_flags($pv); |
918
|
|
|
|
|
|
|
# $decl->add( sprintf( "/* %s */", $cstring) ) if $debug{pv}; |
919
|
0
|
0
|
|
|
|
0
|
return $strtable{$cstring} if defined $strtable{$cstring}; |
920
|
0
|
|
|
|
|
0
|
my $pvsym = sprintf( "pv%d", $pv_index++ ); |
921
|
0
|
0
|
|
|
|
0
|
$const = $const ? " const" : ""; |
922
|
0
|
0
|
0
|
|
|
0
|
if ( defined $max_string_len && $cur > $max_string_len ) { |
923
|
0
|
|
|
|
|
0
|
my $chars = join ', ', map { cchar $_ } split //, pack("a*", $pv); |
|
0
|
|
|
|
|
0
|
|
924
|
0
|
|
|
|
|
0
|
$decl->add( sprintf( "Static%s char %s[] = { %s };", $const, $pvsym, $chars ) ); |
925
|
0
|
|
|
|
|
0
|
$strtable{$cstring} = $pvsym; |
926
|
|
|
|
|
|
|
} else { |
927
|
0
|
0
|
|
|
|
0
|
if ( $cstring ne "0" ) { # sic |
928
|
0
|
|
|
|
|
0
|
$decl->add( sprintf( "Static%s char %s[] = %s;", $const, $pvsym, $cstring ) ); |
929
|
0
|
|
|
|
|
0
|
$strtable{$cstring} = $pvsym; |
930
|
|
|
|
|
|
|
} |
931
|
|
|
|
|
|
|
} |
932
|
0
|
|
|
|
|
0
|
return $pvsym; |
933
|
|
|
|
|
|
|
} |
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
sub save_rv { |
936
|
0
|
|
|
0
|
0
|
0
|
my ($sv, $fullname) = @_; |
937
|
0
|
0
|
|
|
|
0
|
if (!$fullname) { |
938
|
0
|
|
|
|
|
0
|
$fullname = '(unknown)'; |
939
|
|
|
|
|
|
|
} |
940
|
|
|
|
|
|
|
# confess "Can't save RV: not ROK" unless $sv->FLAGS & SVf_ROK; |
941
|
|
|
|
|
|
|
# 5.6: Can't locate object method "RV" via package "B::PVMG" |
942
|
|
|
|
|
|
|
# since 5.11 it must be a PV, the RV was removed from the IV |
943
|
0
|
|
|
|
|
0
|
my $rv; |
944
|
|
|
|
|
|
|
#if ($] >= 5.011 and ref($sv) =~ /^B::[IP]V$/) { |
945
|
|
|
|
|
|
|
# warn "$sv is no IV nor PV\n" if $debug{sv}; |
946
|
|
|
|
|
|
|
# $sv = bless $sv, 'B::PV'; # only observed with DB::args[0] |
947
|
|
|
|
|
|
|
#} |
948
|
|
|
|
|
|
|
#elsif ($] < 5.011 and ref($sv) =~ /^B::[RP]V$/) { |
949
|
|
|
|
|
|
|
# warn "$sv is no RV nor PV\n" if $debug{sv}; |
950
|
|
|
|
|
|
|
# $sv = bless $sv, 'B::RV'; |
951
|
|
|
|
|
|
|
#} |
952
|
0
|
|
|
|
|
0
|
$rv = $sv->RV->save($fullname); |
953
|
0
|
|
|
|
|
0
|
$rv =~ s/^\(([AGHS]V|IO)\s*\*\)\s*(\&sv_list.*)$/$2/; |
954
|
|
|
|
|
|
|
|
955
|
0
|
|
|
|
|
0
|
return $rv; |
956
|
|
|
|
|
|
|
} |
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
# => savesym, cur, len, pv, static, flags |
959
|
|
|
|
|
|
|
sub save_pv_or_rv { |
960
|
0
|
|
|
0
|
0
|
0
|
my ($sv, $fullname) = @_; |
961
|
|
|
|
|
|
|
|
962
|
0
|
|
|
|
|
0
|
my $flags = $sv->FLAGS; |
963
|
0
|
|
|
|
|
0
|
my $rok = $flags & SVf_ROK; |
964
|
0
|
|
|
|
|
0
|
my $pok = $flags & SVf_POK; |
965
|
0
|
|
|
|
|
0
|
my $gmg = $flags & SVs_GMG; |
966
|
0
|
0
|
0
|
|
|
0
|
my $iscow = (IsCOW($sv) or ($B::C::cow and $PERL518)) ? 1 : 0; |
967
|
|
|
|
|
|
|
#my $wascow = IsCOW($sv) ? 1 : 0; |
968
|
0
|
|
|
|
|
0
|
my ( $cur, $len, $savesym, $pv ) = ( 0, 1, 'NULL', "" ); |
969
|
0
|
|
|
|
|
0
|
my ($static, $shared_hek); |
970
|
|
|
|
|
|
|
# overloaded VERSION symbols fail to xs boot: ExtUtils::CBuilder with Fcntl::VERSION (i91) |
971
|
|
|
|
|
|
|
# 5.6: Can't locate object method "RV" via package "B::PV" Carp::Clan |
972
|
0
|
0
|
0
|
|
|
0
|
if ($rok and !$PERL56) { |
973
|
|
|
|
|
|
|
# this returns us a SV*. 5.8 expects a char* in xpvmg.xpv_pv |
974
|
0
|
0
|
|
|
|
0
|
warn "save_pv_or_rv: save_rv(",$sv,")\n" if $debug{sv}; |
975
|
0
|
0
|
|
|
|
0
|
$savesym = ($PERL510 ? "" : "(char*)") . save_rv($sv, $fullname); |
976
|
0
|
|
|
|
|
0
|
$static = 1; # avoid run-time overwrite of the PV/RV slot (#273) |
977
|
0
|
0
|
|
|
|
0
|
if ($savesym =~ /get_cv/) { # Moose::Util::TypeConstraints::Builtins::_RegexpRef |
978
|
0
|
|
|
|
|
0
|
$static = 0; |
979
|
0
|
|
|
|
|
0
|
$pv = $savesym; |
980
|
0
|
|
|
|
|
0
|
$savesym = 'NULL'; |
981
|
|
|
|
|
|
|
} |
982
|
|
|
|
|
|
|
} |
983
|
|
|
|
|
|
|
else { |
984
|
0
|
0
|
|
|
|
0
|
if ($pok) { |
985
|
0
|
|
|
|
|
0
|
$pv = pack "a*", $sv->PV; # XXX! |
986
|
0
|
0
|
0
|
|
|
0
|
$cur = ($sv and $sv->can('CUR') and ref($sv) ne 'B::GV') ? $sv->CUR : length($pv); |
987
|
|
|
|
|
|
|
# comppadname bug with overlong strings |
988
|
0
|
0
|
0
|
|
|
0
|
if ($] < 5.008008 and $cur > 100 and $fullname =~ m/ :pad\[0\]/ and $pv =~ m/\0\0/) { |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
989
|
0
|
|
|
|
|
0
|
my $i = index($pv,"\0"); |
990
|
0
|
0
|
|
|
|
0
|
if ($i > -1) { |
991
|
0
|
|
|
|
|
0
|
$pv = substr($pv,0,$i); |
992
|
0
|
|
|
|
|
0
|
$cur = $i; |
993
|
0
|
0
|
|
|
|
0
|
warn "Warning: stripped wrong comppad name for $fullname to ".cstring($pv)."\n" |
994
|
|
|
|
|
|
|
if $verbose; |
995
|
|
|
|
|
|
|
} |
996
|
|
|
|
|
|
|
} |
997
|
|
|
|
|
|
|
} else { |
998
|
0
|
0
|
0
|
|
|
0
|
if ($gmg && $fullname) { |
999
|
55
|
|
|
55
|
|
265
|
no strict 'refs'; |
|
55
|
|
|
|
|
65
|
|
|
55
|
|
|
|
|
102147
|
|
1000
|
0
|
0
|
0
|
|
|
0
|
$pv = ($fullname and ref($fullname)) ? "${$fullname}" : ''; |
|
0
|
|
|
|
|
0
|
|
1001
|
0
|
|
|
|
|
0
|
$cur = length (pack "a*", $pv); |
1002
|
0
|
|
|
|
|
0
|
$pok = 1; |
1003
|
|
|
|
|
|
|
} else { |
1004
|
0
|
|
|
|
|
0
|
($pv,$cur) = ("",0); |
1005
|
|
|
|
|
|
|
} |
1006
|
|
|
|
|
|
|
} |
1007
|
0
|
0
|
|
|
|
0
|
$shared_hek = $PERL510 ? (($flags & 0x09000000) == 0x09000000) : undef; |
1008
|
0
|
0
|
|
|
|
0
|
$shared_hek = $shared_hek ? 1 : IsCOW_hek($sv); |
1009
|
0
|
0
|
0
|
|
|
0
|
$static = ($B::C::const_strings or $iscow or ($flags & SVf_READONLY)) |
1010
|
|
|
|
|
|
|
? 1 : 0; |
1011
|
0
|
0
|
0
|
|
|
0
|
$static = 0 if $shared_hek |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1012
|
|
|
|
|
|
|
or ($fullname and ($fullname =~ m/ :pad/ |
1013
|
|
|
|
|
|
|
or ($fullname =~ m/^DynaLoader/ and $pv =~ m/^boot_/))); |
1014
|
0
|
0
|
0
|
|
|
0
|
$static = 0 if $static and $pv =~ /::bootstrap$/; |
1015
|
0
|
0
|
0
|
|
|
0
|
$static = 0 if $static and $] > 5.017 and ref($sv) eq 'B::PVMG'; # 242: e.g. $1 |
|
|
|
0
|
|
|
|
|
1016
|
0
|
0
|
0
|
|
|
0
|
$static = 0 if $static and $B::C::const_strings and $fullname and |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1017
|
|
|
|
|
|
|
($fullname =~ /^warnings::(Dead)?Bits/ or $fullname =~ /::AUTOLOAD$/); |
1018
|
0
|
0
|
0
|
|
|
0
|
if ($shared_hek and $pok and !$cur) { #272 empty key |
|
|
|
0
|
|
|
|
|
1019
|
0
|
0
|
0
|
|
|
0
|
warn "use emptystring for empty shared key $fullname\n" if $debug{pv} or $debug{hv}; |
1020
|
0
|
0
|
|
|
|
0
|
$savesym = "emptystring" unless $fullname =~ /unopaux_item.* const/; |
1021
|
0
|
|
|
|
|
0
|
$static = 0; |
1022
|
|
|
|
|
|
|
} |
1023
|
0
|
0
|
0
|
|
|
0
|
if ($static and $PERL510) { # force dynamic PADNAME strings |
1024
|
0
|
0
|
0
|
|
|
0
|
if ($] < 5.016) { $static = 0 if $flags & 0x40000000; } # SVpad_NAME |
|
0
|
0
|
0
|
|
|
0
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
# w. 5.18 even const and VERSION |
1026
|
|
|
|
|
|
|
elsif ($] < 5.020 and $fullname =~ /(^svop const|::VERSION)$/) { |
1027
|
0
|
0
|
|
|
|
0
|
warn "static=0 for $fullname\n" if $debug{pv}; |
1028
|
0
|
|
|
|
|
0
|
$static = 0; |
1029
|
|
|
|
|
|
|
} |
1030
|
|
|
|
|
|
|
elsif ($] < 5.022 and ($flags & 0x40008000 == 0x40008000)) { # SVpad_NAME |
1031
|
0
|
0
|
|
|
|
0
|
warn "static=0 for SVpad_NAME $fullname\n" if $debug{pv}; |
1032
|
0
|
|
|
|
|
0
|
$static = 0; |
1033
|
|
|
|
|
|
|
} |
1034
|
|
|
|
|
|
|
} |
1035
|
0
|
0
|
|
|
|
0
|
if ($pok) { |
1036
|
0
|
|
|
|
|
0
|
my $s = "sv_list[" . ($svsect->index + 1) . "]"; |
1037
|
|
|
|
|
|
|
# static pv (!SvLEN) only valid since cd84013aab030da47b76a44fb3 (sv.c: !SvLEN does not mean undefined) |
1038
|
|
|
|
|
|
|
# i.e. since v5.17.6. because conversion to IV would fail. |
1039
|
|
|
|
|
|
|
# But a "" or "0" or "[a-z]+" string can have SvLEN=0 |
1040
|
|
|
|
|
|
|
# since its is converted to 0. |
1041
|
|
|
|
|
|
|
# Only a readonly "" or "0" string can have SvLEN=0 since it's |
1042
|
|
|
|
|
|
|
# converted to 0, which leads to the same result. |
1043
|
|
|
|
|
|
|
# perlcc -O3 -r -e'print "ok" if 1 == "1"' |
1044
|
|
|
|
|
|
|
# vs |
1045
|
|
|
|
|
|
|
# perlcc -O2 -r -e'print "ok" if 1 == "1"' |
1046
|
|
|
|
|
|
|
# ok |
1047
|
0
|
0
|
0
|
|
|
0
|
if ($static and $] < 5.017006 and $pv !~ /^0?$/) { |
|
|
|
0
|
|
|
|
|
1048
|
0
|
|
|
|
|
0
|
$static = 0; |
1049
|
|
|
|
|
|
|
} |
1050
|
|
|
|
|
|
|
# but we can optimize static set-magic ISA entries. #263, #91 |
1051
|
0
|
0
|
0
|
|
|
0
|
if ($B::C::const_strings and ref($sv) eq 'B::PVMG' |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1052
|
|
|
|
|
|
|
and $flags & SVs_SMG and $fullname =~ /ISA/) { |
1053
|
0
|
|
|
|
|
0
|
$static = 1; # warn "static $fullname"; |
1054
|
|
|
|
|
|
|
} |
1055
|
0
|
0
|
|
|
|
0
|
if ($static) { |
1056
|
0
|
|
|
|
|
0
|
$len = 0; |
1057
|
|
|
|
|
|
|
#warn cstring($sv->PV)." $iscow $wascow"; |
1058
|
0
|
0
|
0
|
|
|
0
|
if ($iscow and $PERL518) { # 5.18 COW logic |
1059
|
0
|
0
|
|
|
|
0
|
if ($B::C::Config::have_HEK_STATIC) { |
|
|
0
|
|
|
|
|
|
1060
|
0
|
|
|
|
|
0
|
$iscow = 1; |
1061
|
0
|
|
|
|
|
0
|
$shared_hek = 1; |
1062
|
|
|
|
|
|
|
# $pv .= "\000\001"; |
1063
|
0
|
|
|
|
|
0
|
$savesym = save_hek($pv,$fullname,0); |
1064
|
|
|
|
|
|
|
# warn "static shared hek: $savesym"; |
1065
|
|
|
|
|
|
|
# $savesym =~ s/&\(HEK\)(hek\d+)/&($1.hek_key)/; |
1066
|
|
|
|
|
|
|
} elsif ($B::C::cow) { |
1067
|
|
|
|
|
|
|
# wrong in many cases but saves a lot of memory, only do this with -O2 |
1068
|
0
|
|
|
|
|
0
|
$len = $cur+2; |
1069
|
0
|
|
|
|
|
0
|
$pv .= "\000\001"; |
1070
|
0
|
|
|
|
|
0
|
$savesym = savepv($pv); |
1071
|
|
|
|
|
|
|
} else { |
1072
|
0
|
|
|
|
|
0
|
$iscow = 0; |
1073
|
0
|
|
|
|
|
0
|
$savesym = constpv($pv); |
1074
|
|
|
|
|
|
|
} |
1075
|
|
|
|
|
|
|
} else { |
1076
|
0
|
|
|
|
|
0
|
$savesym = constpv($pv); |
1077
|
|
|
|
|
|
|
} |
1078
|
0
|
0
|
|
|
|
0
|
if ($savesym =~ /\)?get_cv/) { # Moose::Util::TypeConstraints::Builtins::_RegexpRef |
1079
|
0
|
|
|
|
|
0
|
$static = 0; |
1080
|
0
|
|
|
|
|
0
|
$len = $cur +1; |
1081
|
0
|
|
|
|
|
0
|
$pv = $savesym; |
1082
|
0
|
|
|
|
|
0
|
$savesym = 'NULL'; |
1083
|
|
|
|
|
|
|
} |
1084
|
0
|
0
|
|
|
|
0
|
if ($iscow) { |
1085
|
0
|
|
|
|
|
0
|
$flags |= SVf_IsCOW; |
1086
|
|
|
|
|
|
|
} else { |
1087
|
0
|
|
|
|
|
0
|
$flags &= ~SVf_IsCOW; |
1088
|
|
|
|
|
|
|
} |
1089
|
|
|
|
|
|
|
#push @B::C::static_free, $savesym if $len and $savesym =~ /^pv/ and !$B::C::in_endav; |
1090
|
|
|
|
|
|
|
} else { |
1091
|
0
|
|
|
|
|
0
|
$len = $cur+1; |
1092
|
0
|
0
|
|
|
|
0
|
if ($shared_hek) { |
1093
|
0
|
0
|
|
|
|
0
|
if ($savesym eq "emptystring") { |
1094
|
0
|
|
|
|
|
0
|
$free->add(" SvLEN(&$s) = 0;"); |
1095
|
0
|
0
|
|
|
|
0
|
$len = 0 if $PERL518; |
1096
|
|
|
|
|
|
|
} else { |
1097
|
0
|
|
|
|
|
0
|
$len = 0; |
1098
|
|
|
|
|
|
|
} |
1099
|
0
|
|
|
|
|
0
|
$free->add(" SvFAKE_off(&$s);"); |
1100
|
|
|
|
|
|
|
} else { |
1101
|
0
|
0
|
0
|
|
|
0
|
if ($iscow and $cur and $PERL518) { |
|
|
|
0
|
|
|
|
|
1102
|
0
|
|
|
|
|
0
|
$len++; |
1103
|
0
|
|
|
|
|
0
|
$pv .= "\000\001"; |
1104
|
0
|
|
|
|
|
0
|
$flags |= SVf_IsCOW; |
1105
|
|
|
|
|
|
|
} |
1106
|
|
|
|
|
|
|
} |
1107
|
|
|
|
|
|
|
} |
1108
|
|
|
|
|
|
|
} else { |
1109
|
0
|
|
|
|
|
0
|
$len = 0; |
1110
|
|
|
|
|
|
|
} |
1111
|
|
|
|
|
|
|
} |
1112
|
|
|
|
|
|
|
#if ($iscow and $len and $PERL518) { # 5.18 COW logic |
1113
|
|
|
|
|
|
|
# my $offset = $len % $Config{ptrsize}; |
1114
|
|
|
|
|
|
|
# $len += $Config{ptrsize} - $offset if $offset; |
1115
|
|
|
|
|
|
|
#} |
1116
|
|
|
|
|
|
|
warn sprintf("Saving pv as %s %s cur=%d, len=%d, static=%d cow=%d %s flags=0x%x\n", |
1117
|
|
|
|
|
|
|
$savesym, cstring($pv), $cur, $len, |
1118
|
|
|
|
|
|
|
$static, $iscow, $shared_hek ? "shared, $fullname" : $fullname, $flags) |
1119
|
0
|
0
|
|
|
|
0
|
if $debug{pv}; |
|
|
0
|
|
|
|
|
|
1120
|
0
|
|
|
|
|
0
|
return ( $savesym, $cur, $len, $pv, $static, $flags ); |
1121
|
|
|
|
|
|
|
} |
1122
|
|
|
|
|
|
|
|
1123
|
|
|
|
|
|
|
# Shared global string in PL_strtab. |
1124
|
|
|
|
|
|
|
# Mostly GvNAME and GvFILE, but also CV prototypes or bareword hash keys. |
1125
|
|
|
|
|
|
|
# Note: currently not used in list context |
1126
|
|
|
|
|
|
|
sub save_hek { |
1127
|
0
|
|
|
0
|
0
|
0
|
my ($str, $fullname, $dynamic) = @_; # not cstring'ed |
1128
|
|
|
|
|
|
|
# $dynamic: see lexsub CvNAME in CV::save |
1129
|
|
|
|
|
|
|
# force empty string for CV prototypes |
1130
|
0
|
0
|
|
|
|
0
|
return "NULL" unless defined $str; |
1131
|
0
|
0
|
0
|
|
|
0
|
return "NULL" if $dynamic and !length $str and !@_ |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1132
|
|
|
|
|
|
|
and $fullname !~ /unopaux_item.* const/; |
1133
|
|
|
|
|
|
|
# The first assigment is already refcount bumped, we have to manually |
1134
|
|
|
|
|
|
|
# do it for all others |
1135
|
0
|
|
|
|
|
0
|
my ($cstr, $cur, $utf8) = strlen_flags($str); |
1136
|
0
|
|
|
|
|
0
|
my $hek_key = $str.":".$utf8; |
1137
|
0
|
0
|
0
|
|
|
0
|
if ($dynamic and defined $hektable{$hek_key}) { |
1138
|
0
|
|
|
|
|
0
|
return sprintf("share_hek_hek(%s)", $hektable{$hek_key}); |
1139
|
|
|
|
|
|
|
} |
1140
|
0
|
0
|
0
|
|
|
0
|
if (!$dynamic and defined $statichektable{$hek_key}) { |
1141
|
0
|
|
|
|
|
0
|
return $statichektable{$hek_key}; |
1142
|
|
|
|
|
|
|
} |
1143
|
0
|
0
|
|
|
|
0
|
$cur = - $cur if $utf8; |
1144
|
0
|
0
|
|
|
|
0
|
$cstr = '""' if $cstr eq "0"; |
1145
|
0
|
|
|
|
|
0
|
my $sym = sprintf( "hek%d", $hek_index++ ); |
1146
|
0
|
0
|
|
|
|
0
|
if (!$dynamic) { |
1147
|
0
|
|
|
|
|
0
|
$statichektable{$hek_key} = $sym; |
1148
|
0
|
|
|
|
|
0
|
my $key = $cstr; |
1149
|
0
|
|
|
|
|
0
|
my $len = abs($cur); |
1150
|
|
|
|
|
|
|
# strip CowREFCNT |
1151
|
0
|
0
|
|
|
|
0
|
if ($key =~ /\\000\\001"$/) { |
1152
|
0
|
|
|
|
|
0
|
$key =~ s/\\000\\001"$/"/; |
1153
|
0
|
|
|
|
|
0
|
$len -= 2; |
1154
|
|
|
|
|
|
|
} |
1155
|
|
|
|
|
|
|
# add the flags. a static hek is unshared |
1156
|
0
|
0
|
|
|
|
0
|
if (!$utf8) { # 0x88: HVhek_STATIC + HVhek_UNSHARED |
1157
|
0
|
|
|
|
|
0
|
$key =~ s/"$/\\000\\210"/; |
1158
|
|
|
|
|
|
|
} else { # 0x89: + HVhek_UTF8 |
1159
|
0
|
|
|
|
|
0
|
$key =~ s/"$/\\000\\211"/; |
1160
|
|
|
|
|
|
|
} |
1161
|
|
|
|
|
|
|
#warn sprintf("Saving static hek %s %s cur=%d\n", $sym, $cstr, $cur) |
1162
|
|
|
|
|
|
|
# if $debug{pv}; |
1163
|
|
|
|
|
|
|
# not const because we need to set the HASH at init |
1164
|
0
|
|
|
|
|
0
|
$decl->add(sprintf("Static struct hek_ptr %s = { %u, %d, %s};", |
1165
|
|
|
|
|
|
|
$sym, 0, $len, $key)); |
1166
|
0
|
|
|
|
|
0
|
$init->add(sprintf("PERL_HASH(%s.hek_hash, %s.hek_key, %u);", $sym, $sym, $len)); |
1167
|
|
|
|
|
|
|
} else { |
1168
|
0
|
|
|
|
|
0
|
$hektable{$hek_key} = $sym; |
1169
|
0
|
|
|
|
|
0
|
$decl->add(sprintf("Static HEK *%s;", $sym)); |
1170
|
|
|
|
|
|
|
warn sprintf("Saving hek %s %s cur=%d\n", $sym, $cstr, $cur) |
1171
|
0
|
0
|
|
|
|
0
|
if $debug{pv}; |
1172
|
|
|
|
|
|
|
# randomized global shared hash keys: |
1173
|
|
|
|
|
|
|
# share_hek needs a non-zero hash parameter, unlike hv_store. |
1174
|
|
|
|
|
|
|
# Vulnerable to oCERT-2011-003 style DOS attacks? |
1175
|
|
|
|
|
|
|
# user-input (object fields) do not affect strtab, it is pretty safe. |
1176
|
|
|
|
|
|
|
# But we need to randomize them to avoid run-time conflicts |
1177
|
|
|
|
|
|
|
# e.g. "Prototype mismatch: sub bytes::length (_) vs (_)" |
1178
|
|
|
|
|
|
|
#if (0 and $PERL510) { # no refcount |
1179
|
|
|
|
|
|
|
# $init->add(sprintf("%s = my_share_hek_0(%s, %d);", $sym, $cstr, $cur)); |
1180
|
|
|
|
|
|
|
#} else { # vs. bump the refcount |
1181
|
0
|
|
|
|
|
0
|
$init->add(sprintf("%s = share_hek(%s, %d);", $sym, $cstr, $cur)); |
1182
|
|
|
|
|
|
|
#} |
1183
|
|
|
|
|
|
|
# protect against Unbalanced string table refcount warning with PERL_DESTRUCT_LEVEL=2 |
1184
|
|
|
|
|
|
|
# $free->add(" $sym = NULL;"); |
1185
|
|
|
|
|
|
|
} |
1186
|
0
|
|
|
|
|
0
|
return $sym; |
1187
|
|
|
|
|
|
|
} |
1188
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
sub gv_fetchpvn { |
1190
|
0
|
|
|
0
|
0
|
0
|
my ($name, $flags, $type) = @_; |
1191
|
0
|
0
|
|
|
|
0
|
warn 'undefined flags' unless defined $flags; |
1192
|
0
|
0
|
|
|
|
0
|
warn 'undefined type' unless defined $type; |
1193
|
0
|
|
|
|
|
0
|
my ($cname, $cur, $utf8) = strlen_flags($name); |
1194
|
0
|
0
|
|
|
|
0
|
if ($] >= 5.009002) { |
1195
|
0
|
0
|
|
|
|
0
|
$flags .= length($flags) ? "|$utf8" : $utf8 if $utf8; |
|
|
0
|
|
|
|
|
|
1196
|
0
|
|
|
|
|
0
|
return "gv_fetchpvn_flags($cname, $cur, $flags, $type)"; |
1197
|
|
|
|
|
|
|
} else { |
1198
|
0
|
|
|
|
|
0
|
return "gv_fetchpv($cname, $flags, $type)"; |
1199
|
|
|
|
|
|
|
} |
1200
|
|
|
|
|
|
|
} |
1201
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
# get_cv() returns a CV* |
1203
|
|
|
|
|
|
|
sub get_cv { |
1204
|
0
|
|
|
0
|
0
|
0
|
my ($name, $flags) = @_; |
1205
|
0
|
0
|
|
|
|
0
|
$name = "" if $name eq "__ANON__"; |
1206
|
0
|
|
|
|
|
0
|
my ($cname, $cur, $utf8) = strlen_flags($name); |
1207
|
0
|
0
|
|
|
|
0
|
warn 'undefined flags' unless defined $flags; |
1208
|
0
|
0
|
|
|
|
0
|
if ($] >= 5.009002) { |
1209
|
0
|
0
|
|
|
|
0
|
$flags .= length($flags) ? "|$utf8" : $utf8 if $utf8; |
|
|
0
|
|
|
|
|
|
1210
|
0
|
|
|
|
|
0
|
return qq[get_cvn_flags($cname, $cur, $flags)]; |
1211
|
|
|
|
|
|
|
} else { |
1212
|
0
|
|
|
|
|
0
|
return qq[get_cv($cname, $flags)]; |
1213
|
|
|
|
|
|
|
} |
1214
|
|
|
|
|
|
|
} |
1215
|
|
|
|
|
|
|
|
1216
|
|
|
|
|
|
|
sub ivx ($) { |
1217
|
0
|
|
|
0
|
0
|
0
|
my $ivx = shift; |
1218
|
0
|
|
|
|
|
0
|
my $ivdformat = $Config{ivdformat}; |
1219
|
0
|
|
|
|
|
0
|
$ivdformat =~ s/["\0]//g; #" poor editor |
1220
|
0
|
|
|
|
|
0
|
$ivdformat =~ s/".$/"/; # cperl bug 5.22.2 #61 (never released) |
1221
|
0
|
0
|
|
|
|
0
|
unless ($ivdformat) { |
1222
|
0
|
0
|
|
|
|
0
|
$ivdformat = $Config{ivsize} == 4 ? 'd' : 'ld'; |
1223
|
|
|
|
|
|
|
} |
1224
|
0
|
|
|
|
|
0
|
my $POW = ( $Config{ivsize} * 4 - 1 ); # poor editor |
1225
|
0
|
|
|
|
|
0
|
my $intmax = (1 << $POW) - 1; |
1226
|
0
|
|
|
|
|
0
|
my $L = 'L'; |
1227
|
|
|
|
|
|
|
# LL for 32bit -2147483648L or 64bit -9223372036854775808L |
1228
|
0
|
0
|
|
|
|
0
|
$L = 'LL' if $Config{ivsize} == 2*$Config{ptrsize}; |
1229
|
|
|
|
|
|
|
# UL if > INT32_MAX = 2147483647 |
1230
|
0
|
0
|
|
|
|
0
|
my $sval = sprintf("%${ivdformat}%s", $ivx, $ivx > $intmax ? "U$L" : ""); |
1231
|
0
|
0
|
|
|
|
0
|
if ($ivx < -$intmax) { |
1232
|
0
|
|
|
|
|
0
|
$sval = sprintf("%${ivdformat}%s", $ivx, 'LL'); # DateTime |
1233
|
|
|
|
|
|
|
} |
1234
|
0
|
0
|
|
|
|
0
|
if ($INC{'POSIX.pm'}) { |
1235
|
|
|
|
|
|
|
# i262: LONG_MIN -9223372036854775808L integer constant is so large that it is unsigned |
1236
|
0
|
0
|
|
|
|
0
|
if ($ivx == POSIX::LONG_MIN()) { |
|
|
0
|
|
|
|
|
|
1237
|
0
|
|
|
|
|
0
|
$sval = "PERL_LONG_MIN"; |
1238
|
|
|
|
|
|
|
} |
1239
|
|
|
|
|
|
|
elsif ($ivx == POSIX::LONG_MAX()) { |
1240
|
0
|
|
|
|
|
0
|
$sval = "PERL_LONG_MAX"; |
1241
|
|
|
|
|
|
|
} |
1242
|
|
|
|
|
|
|
#elsif ($ivx == POSIX::HUGE_VAL()) { |
1243
|
|
|
|
|
|
|
# $sval = "HUGE_VAL"; |
1244
|
|
|
|
|
|
|
#} |
1245
|
|
|
|
|
|
|
} |
1246
|
0
|
0
|
|
|
|
0
|
$sval = '0' if $sval =~ /(NAN|inf)$/i; |
1247
|
0
|
|
|
|
|
0
|
return $sval; |
1248
|
|
|
|
|
|
|
#return $C99 ? ".xivu_uv = $sval" : $sval; # this is version dependent |
1249
|
|
|
|
|
|
|
} |
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
# protect from warning: floating constant exceeds range of ‘double’ [-Woverflow] |
1252
|
|
|
|
|
|
|
sub nvx ($) { |
1253
|
0
|
|
|
0
|
0
|
0
|
my $nvx = shift; |
1254
|
|
|
|
|
|
|
|
1255
|
|
|
|
|
|
|
# Handle infinite and NaN values |
1256
|
0
|
0
|
|
|
|
0
|
if ( defined $nvx ) { |
1257
|
0
|
0
|
0
|
|
|
0
|
if ( $Config{d_isinf} or $] < 5.012 ) { |
1258
|
0
|
0
|
|
|
|
0
|
return 'INFINITY' if $nvx =~ /^Inf/i; |
1259
|
0
|
0
|
|
|
|
0
|
return '-INFINITY' if $nvx =~ /^-Inf/i; |
1260
|
|
|
|
|
|
|
} |
1261
|
0
|
0
|
0
|
|
|
0
|
return 'NAN' if $nvx =~ /^NaN/i and ($Config{d_isnan} or $] < 5.012); |
|
|
|
0
|
|
|
|
|
1262
|
|
|
|
|
|
|
# TODO NANL for long double |
1263
|
|
|
|
|
|
|
} |
1264
|
|
|
|
|
|
|
|
1265
|
0
|
|
|
|
|
0
|
my $nvgformat = $Config{nvgformat}; |
1266
|
0
|
|
|
|
|
0
|
$nvgformat =~ s/["\0]//g; #" poor editor |
1267
|
0
|
|
|
|
|
0
|
$nvgformat =~ s/".$/"/; # cperl bug 5.22.2 #61 |
1268
|
0
|
0
|
|
|
|
0
|
unless ($nvgformat) { |
1269
|
0
|
|
|
|
|
0
|
$nvgformat = 'g'; |
1270
|
|
|
|
|
|
|
} |
1271
|
0
|
|
|
|
|
0
|
my $dblmax = "1.79769313486232e+308"; |
1272
|
0
|
|
|
|
|
0
|
my $ldblmax = "1.18973149535723176502e+4932"; |
1273
|
0
|
0
|
|
|
|
0
|
if ($nvgformat eq 'g') { # a very poor choice to keep precision |
1274
|
|
|
|
|
|
|
# on intel 17-18, on ppc 31, on sparc64/s390 34 |
1275
|
|
|
|
|
|
|
# TODO: rather use the binary representation of our union |
1276
|
0
|
0
|
|
|
|
0
|
$nvgformat = $Config{uselongdouble} ? '.18Lg' : '.17g'; |
1277
|
|
|
|
|
|
|
} |
1278
|
0
|
0
|
|
|
|
0
|
my $sval = sprintf("%${nvgformat}%s", $nvx, $nvx > $dblmax ? "L" : ""); |
1279
|
0
|
0
|
|
|
|
0
|
$sval = sprintf("%${nvgformat}%s", $nvx, "L") if $nvx < -$dblmax; |
1280
|
0
|
0
|
|
|
|
0
|
if ($INC{'POSIX.pm'}) { |
1281
|
0
|
0
|
|
|
|
0
|
if ($nvx == POSIX::DBL_MIN()) { |
|
|
0
|
|
|
|
|
|
1282
|
0
|
|
|
|
|
0
|
$sval = "DBL_MIN"; |
1283
|
|
|
|
|
|
|
} |
1284
|
|
|
|
|
|
|
elsif ($nvx == POSIX::DBL_MAX()) { #1.797693134862316e+308 |
1285
|
0
|
|
|
|
|
0
|
$sval = "DBL_MAX"; |
1286
|
|
|
|
|
|
|
} |
1287
|
|
|
|
|
|
|
} |
1288
|
|
|
|
|
|
|
else { |
1289
|
0
|
0
|
|
|
|
0
|
if ($nvx == $dblmax) { |
1290
|
0
|
|
|
|
|
0
|
$sval = "DBL_MAX"; |
1291
|
|
|
|
|
|
|
} |
1292
|
|
|
|
|
|
|
} |
1293
|
|
|
|
|
|
|
|
1294
|
0
|
0
|
|
|
|
0
|
if ($Config{d_longdbl}) { |
1295
|
0
|
|
|
|
|
0
|
my $posix; |
1296
|
0
|
0
|
|
|
|
0
|
if ($INC{'POSIX.pm'}) { |
1297
|
0
|
|
|
|
|
0
|
eval { $posix = POSIX::LDBL_MIN(); }; |
|
0
|
|
|
|
|
0
|
|
1298
|
|
|
|
|
|
|
} |
1299
|
0
|
0
|
|
|
|
0
|
if ($posix) { # linux does not have these, darwin does |
|
|
0
|
|
|
|
|
|
1300
|
0
|
0
|
|
|
|
0
|
if ($nvx == $posix) { |
|
|
0
|
|
|
|
|
|
1301
|
0
|
|
|
|
|
0
|
$sval = "NV_MIN"; |
1302
|
|
|
|
|
|
|
} |
1303
|
|
|
|
|
|
|
elsif ($nvx == POSIX::LDBL_MAX()) { |
1304
|
0
|
|
|
|
|
0
|
$sval = "NV_MAX"; |
1305
|
|
|
|
|
|
|
} |
1306
|
|
|
|
|
|
|
} elsif ($nvx == $ldblmax) { |
1307
|
0
|
|
|
|
|
0
|
$sval = "NV_MAX"; |
1308
|
|
|
|
|
|
|
} |
1309
|
|
|
|
|
|
|
} |
1310
|
0
|
0
|
|
|
|
0
|
$sval = '0' if $sval =~ /(NAN|inf)$/i; |
1311
|
0
|
0
|
|
|
|
0
|
$sval .= '.00' if $sval =~ /^-?\d+$/; |
1312
|
0
|
|
|
|
|
0
|
return $sval; |
1313
|
|
|
|
|
|
|
} |
1314
|
|
|
|
|
|
|
|
1315
|
|
|
|
|
|
|
sub mg_RC_off { |
1316
|
0
|
|
|
0
|
0
|
0
|
my ($mg, $sym, $type) = @_; |
1317
|
0
|
0
|
|
|
|
0
|
warn "MG->FLAGS ",$mg->FLAGS," turn off MGf_REFCOUNTED\n" if $debug{mg}; |
1318
|
0
|
0
|
|
|
|
0
|
if (!ref $sym) { |
1319
|
0
|
|
|
|
|
0
|
$init->add(sprintf("my_mg_RC_off(aTHX_ (SV*)$sym, %s);", cchar($type))); |
1320
|
|
|
|
|
|
|
} else { |
1321
|
0
|
|
|
|
|
0
|
$init->add(sprintf("my_mg_RC_off(aTHX_ (SV*)s\\_%x, %s);", $$sym, cchar($type))); |
1322
|
|
|
|
|
|
|
} |
1323
|
|
|
|
|
|
|
} |
1324
|
|
|
|
|
|
|
|
1325
|
|
|
|
|
|
|
# for bytes and utf8 only |
1326
|
|
|
|
|
|
|
# TODO: Carp::Heavy, Exporter::Heavy |
1327
|
|
|
|
|
|
|
# special case: warnings::register via -fno-warnings |
1328
|
|
|
|
|
|
|
sub force_heavy { |
1329
|
0
|
|
|
0
|
0
|
0
|
my $pkg = shift; |
1330
|
0
|
|
|
|
|
0
|
my $pkg_heavy = $pkg."_heavy.pl"; |
1331
|
55
|
|
|
55
|
|
328
|
no strict 'refs'; |
|
55
|
|
|
|
|
71
|
|
|
55
|
|
|
|
|
104086
|
|
1332
|
0
|
0
|
0
|
|
|
0
|
if (!$include_package{$pkg_heavy} and !exists $savINC{$pkg_heavy}) { |
1333
|
|
|
|
|
|
|
#eval qq[sub $pkg\::AUTOLOAD { |
1334
|
|
|
|
|
|
|
# require '$pkg_heavy'; |
1335
|
|
|
|
|
|
|
# goto &\$AUTOLOAD if defined &\$AUTOLOAD; |
1336
|
|
|
|
|
|
|
# warn("Undefined subroutine \$AUTOLOAD called"); |
1337
|
|
|
|
|
|
|
# }]; |
1338
|
|
|
|
|
|
|
#warn "Redefined $pkg\::AUTOLOAD to omit Carp\n" if $debug{gv}; |
1339
|
0
|
0
|
|
|
|
0
|
warn "Forcing early $pkg_heavy\n" if $debug{pkg}; |
1340
|
0
|
|
|
|
|
0
|
require $pkg_heavy; |
1341
|
0
|
|
|
|
|
0
|
mark_package($pkg_heavy, 1); |
1342
|
|
|
|
|
|
|
#walk_syms($pkg); #before we stub unloaded CVs |
1343
|
|
|
|
|
|
|
} |
1344
|
0
|
|
|
|
|
0
|
return svref_2object( \*{$pkg."::AUTOLOAD"} ); |
|
0
|
|
|
|
|
0
|
|
1345
|
|
|
|
|
|
|
} |
1346
|
|
|
|
|
|
|
|
1347
|
|
|
|
|
|
|
# See also init_op_ppaddr below; initializes the ppaddr to the |
1348
|
|
|
|
|
|
|
# OpTYPE; init_op_ppaddr iterates over the ops and sets |
1349
|
|
|
|
|
|
|
# op_ppaddr to PL_ppaddr[op_ppaddr]; this avoids an explicit assignment |
1350
|
|
|
|
|
|
|
# in perl_init ( ~10 bytes/op with GCC/i386 ) |
1351
|
|
|
|
|
|
|
sub B::OP::fake_ppaddr { |
1352
|
0
|
|
|
0
|
|
0
|
my $op = shift; |
1353
|
0
|
0
|
|
|
|
0
|
return "NULL" unless $op->can('name'); |
1354
|
0
|
0
|
|
|
|
0
|
if ($op->type == $OP_CUSTOM) { |
1355
|
0
|
0
|
|
|
|
0
|
return ( $verbose ? sprintf( "/*XOP %s*/NULL", $op->name) : "NULL" ); |
1356
|
|
|
|
|
|
|
} |
1357
|
0
|
0
|
|
|
|
0
|
return $B::C::optimize_ppaddr |
|
|
0
|
|
|
|
|
|
1358
|
|
|
|
|
|
|
? sprintf( "INT2PTR(void*,OP_%s)", uc( $op->name ) ) |
1359
|
|
|
|
|
|
|
: ( $verbose ? sprintf( "/*OP_%s*/NULL", uc( $op->name ) ) : "NULL" ); |
1360
|
|
|
|
|
|
|
} |
1361
|
0
|
|
|
0
|
|
0
|
sub B::FAKEOP::fake_ppaddr { "NULL" } |
1362
|
|
|
|
|
|
|
# XXX HACK! duct-taping around compiler problems |
1363
|
0
|
|
|
0
|
|
0
|
sub B::OP::isa { UNIVERSAL::isa(@_) } # walkoptree_slow misses that |
1364
|
70218
|
|
|
70218
|
|
3959624
|
sub B::OP::can { UNIVERSAL::can(@_) } |
1365
|
0
|
|
|
0
|
|
0
|
sub B::OBJECT::name { "" } # B misses that |
1366
|
|
|
|
|
|
|
$isa_cache{'B::OBJECT::can'} = 'UNIVERSAL'; |
1367
|
|
|
|
|
|
|
|
1368
|
|
|
|
|
|
|
# This pair is needed because B::FAKEOP::save doesn't scalar dereference |
1369
|
|
|
|
|
|
|
# $op->next and $op->sibling |
1370
|
|
|
|
|
|
|
my $opsect_common = |
1371
|
|
|
|
|
|
|
"next, sibling, ppaddr, " . ( $MAD ? "madprop, " : "" ) . "targ, type, "; |
1372
|
|
|
|
|
|
|
#$opsect_common =~ s/, sibling/, _OP_SIBPARENT_FIELDNAME/ if $] > 5.021007; |
1373
|
|
|
|
|
|
|
$opsect_common =~ s/, sibling/, sibparent/ if $have_sibparent; |
1374
|
|
|
|
|
|
|
{ |
1375
|
|
|
|
|
|
|
|
1376
|
|
|
|
|
|
|
# For 5.8: |
1377
|
|
|
|
|
|
|
# Current workaround/fix for op_free() trying to free statically |
1378
|
|
|
|
|
|
|
# defined OPs is to set op_seq = -1 and check for that in op_free(). |
1379
|
|
|
|
|
|
|
# Instead of hardwiring -1 in place of $op->seq, we use $op_seq |
1380
|
|
|
|
|
|
|
# so that it can be changed back easily if necessary. In fact, to |
1381
|
|
|
|
|
|
|
# stop compilers from moaning about a U16 being initialised with an |
1382
|
|
|
|
|
|
|
# uncast -1 (the printf format is %d so we can't tweak it), we have |
1383
|
|
|
|
|
|
|
# to "know" that op_seq is a U16 and use 65535. Ugh. |
1384
|
|
|
|
|
|
|
|
1385
|
|
|
|
|
|
|
# For 5.9 the hard coded text is the values for op_opt and op_static in each |
1386
|
|
|
|
|
|
|
# op. The value of op_opt is irrelevant, and the value of op_static needs to |
1387
|
|
|
|
|
|
|
# be 1 to tell op_free that this is a statically defined op and that is |
1388
|
|
|
|
|
|
|
# shouldn't be freed. |
1389
|
|
|
|
|
|
|
|
1390
|
|
|
|
|
|
|
# For 5.10 op_seq = -1 is gone, the temp. op_static also, but we |
1391
|
|
|
|
|
|
|
# have something better, we can set op_latefree to 1, which frees the children |
1392
|
|
|
|
|
|
|
# (e.g. savepvn), but not the static op. |
1393
|
|
|
|
|
|
|
|
1394
|
|
|
|
|
|
|
# 5.8: U16 op_seq; |
1395
|
|
|
|
|
|
|
# 5.9.4: unsigned op_opt:1; unsigned op_static:1; unsigned op_spare:5; |
1396
|
|
|
|
|
|
|
# 5.10: unsigned op_opt:1; unsigned op_latefree:1; unsigned op_latefreed:1; unsigned op_attached:1; unsigned op_spare:3; |
1397
|
|
|
|
|
|
|
# 5.18: unsigned op_opt:1; unsigned op_slabbed:1; unsigned op_savefree:1; unsigned op_static:1; unsigned op_spare:3; |
1398
|
|
|
|
|
|
|
# 5.19: unsigned op_opt:1; unsigned op_slabbed:1; unsigned op_savefree:1; unsigned op_static:1; unsigned op_folded:1; unsigned op_spare:2; |
1399
|
|
|
|
|
|
|
# 5.21.2: unsigned op_opt:1; unsigned op_slabbed:1; unsigned op_savefree:1; unsigned op_static:1; unsigned op_folded:1; unsigned op_lastesib:1; unsigned op_spare:1; |
1400
|
|
|
|
|
|
|
# 5.21.11: unsigned op_opt:1; unsigned op_slabbed:1; unsigned op_savefree:1; unsigned op_static:1; unsigned op_folded:1; unsigned op_moresib:1; unsigned op_spare:1; |
1401
|
|
|
|
|
|
|
my $static; |
1402
|
|
|
|
|
|
|
if ( $] < 5.009004 ) { |
1403
|
|
|
|
|
|
|
$static = sprintf "%u", 65535; |
1404
|
|
|
|
|
|
|
$opsect_common .= "seq"; |
1405
|
|
|
|
|
|
|
} |
1406
|
|
|
|
|
|
|
elsif ( $] < 5.010 ) { |
1407
|
|
|
|
|
|
|
$static = '0, 1, 0'; |
1408
|
|
|
|
|
|
|
$opsect_common .= "opt, static, spare"; |
1409
|
|
|
|
|
|
|
} |
1410
|
|
|
|
|
|
|
elsif ($] < 5.017002) { |
1411
|
|
|
|
|
|
|
$static = '0, 1, 0, 0, 0'; |
1412
|
|
|
|
|
|
|
$opsect_common .= "opt, latefree, latefreed, attached, spare"; |
1413
|
|
|
|
|
|
|
} |
1414
|
|
|
|
|
|
|
elsif ($] < 5.017004) { |
1415
|
|
|
|
|
|
|
$static = '0, 1, 0, 0, 0, 0, 0'; |
1416
|
|
|
|
|
|
|
$opsect_common .= "opt, latefree, latefreed, attached, slabbed, savefree, spare"; |
1417
|
|
|
|
|
|
|
} |
1418
|
|
|
|
|
|
|
elsif ($] < 5.017006) { |
1419
|
|
|
|
|
|
|
$static = '0, 1, 0, 0, 0, 0, 0'; |
1420
|
|
|
|
|
|
|
$opsect_common .= "opt, latefree, latefreed, attached, slabbed, savefree, spare"; |
1421
|
|
|
|
|
|
|
} |
1422
|
|
|
|
|
|
|
elsif ($] < 5.019002) { # 90840c5d1d 5.17.6 |
1423
|
|
|
|
|
|
|
$static = '0, 0, 0, 1, 0'; |
1424
|
|
|
|
|
|
|
$opsect_common .= "opt, slabbed, savefree, static, spare"; |
1425
|
|
|
|
|
|
|
} |
1426
|
|
|
|
|
|
|
elsif ($] < 5.021002) { |
1427
|
|
|
|
|
|
|
$static = '0, 0, 0, 1, 0, 0'; |
1428
|
|
|
|
|
|
|
$opsect_common .= "opt, slabbed, savefree, static, folded, spare"; |
1429
|
|
|
|
|
|
|
} |
1430
|
|
|
|
|
|
|
elsif ($] < 5.0210011) { |
1431
|
|
|
|
|
|
|
$static = '0, 0, 0, 1, 0, %d, 0'; |
1432
|
|
|
|
|
|
|
$opsect_common .= "opt, slabbed, savefree, static, folded, lastsib, spare"; |
1433
|
|
|
|
|
|
|
} |
1434
|
|
|
|
|
|
|
else { |
1435
|
|
|
|
|
|
|
$static = '0, 0, 0, 1, 0, %d, 0'; |
1436
|
|
|
|
|
|
|
$opsect_common .= "opt, slabbed, savefree, static, folded, moresib, spare"; |
1437
|
|
|
|
|
|
|
} |
1438
|
|
|
|
|
|
|
|
1439
|
|
|
|
|
|
|
sub B::OP::_save_common_middle { |
1440
|
0
|
|
|
0
|
|
0
|
my $op = shift; |
1441
|
0
|
0
|
|
|
|
0
|
my $madprop = $MAD ? "0," : ""; |
1442
|
0
|
|
|
|
|
0
|
my $ret; |
1443
|
0
|
0
|
|
|
|
0
|
if ($static =~ / %d,/) { |
1444
|
0
|
|
|
|
|
0
|
my $has_sib; |
1445
|
0
|
0
|
|
|
|
0
|
if (ref($op) eq 'B::FAKEOP') { |
|
|
0
|
|
|
|
|
|
1446
|
0
|
|
|
|
|
0
|
$has_sib = 0; |
1447
|
|
|
|
|
|
|
} elsif ($] < 5.0210011) { |
1448
|
0
|
|
|
|
|
0
|
$has_sib = $op->lastsib; |
1449
|
|
|
|
|
|
|
} else { |
1450
|
0
|
|
|
|
|
0
|
$has_sib = $op->moresib; |
1451
|
|
|
|
|
|
|
} |
1452
|
0
|
|
|
|
|
0
|
$ret = sprintf( "%s, %s %u, %u, $static, 0x%x, 0x%x", |
1453
|
|
|
|
|
|
|
$op->fake_ppaddr, $madprop, $op->targ, $op->type, |
1454
|
|
|
|
|
|
|
$has_sib, |
1455
|
|
|
|
|
|
|
$op->flags, $op->private ); |
1456
|
|
|
|
|
|
|
} else { |
1457
|
0
|
|
|
|
|
0
|
$ret = sprintf( "%s, %s %u, %u, $static, 0x%x, 0x%x", |
1458
|
|
|
|
|
|
|
$op->fake_ppaddr, $madprop, $op->targ, $op->type, |
1459
|
|
|
|
|
|
|
$op->flags, $op->private ); |
1460
|
|
|
|
|
|
|
} |
1461
|
|
|
|
|
|
|
# XXX maybe add a ix=opindex string for debugging if $debug{flags} |
1462
|
0
|
0
|
|
|
|
0
|
if ($B::C::Config::have_op_rettype) { |
1463
|
0
|
|
|
|
|
0
|
$ret .= sprintf(", 0x%x", $op->rettype); |
1464
|
|
|
|
|
|
|
} |
1465
|
0
|
|
|
|
|
0
|
$ret; |
1466
|
|
|
|
|
|
|
} |
1467
|
|
|
|
|
|
|
$opsect_common .= ", flags, private"; |
1468
|
|
|
|
|
|
|
if ($B::C::Config::have_op_rettype) { |
1469
|
|
|
|
|
|
|
$opsect_common .= ", rettype"; |
1470
|
|
|
|
|
|
|
} |
1471
|
|
|
|
|
|
|
} |
1472
|
|
|
|
|
|
|
|
1473
|
|
|
|
|
|
|
sub B::OP::_save_common { |
1474
|
0
|
|
|
0
|
|
0
|
my $op = shift; |
1475
|
|
|
|
|
|
|
# compile-time method_named packages are always const PV sM/BARE, they should be optimized. |
1476
|
|
|
|
|
|
|
# run-time packages are in gvsv/padsv. This is difficult to optimize. |
1477
|
|
|
|
|
|
|
# my Foo $obj = shift; $obj->bar(); # TODO typed $obj |
1478
|
|
|
|
|
|
|
# entersub -> pushmark -> package -> args... |
1479
|
|
|
|
|
|
|
# See perl -MO=Terse -e '$foo->bar("var")' |
1480
|
|
|
|
|
|
|
# See also http://www.perl.com/pub/2000/06/dougpatch.html |
1481
|
|
|
|
|
|
|
# XXX TODO 5.8 ex-gvsv |
1482
|
|
|
|
|
|
|
# XXX TODO Check for method_named as last argument |
1483
|
0
|
0
|
0
|
|
|
0
|
if ($op->type > 0 and |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1484
|
|
|
|
|
|
|
$op->name eq 'entersub' and $op->first and $op->first->can('name') and |
1485
|
|
|
|
|
|
|
$op->first->name eq 'pushmark' and |
1486
|
|
|
|
|
|
|
# Foo->bar() compile-time lookup, 34 = BARE in all versions |
1487
|
|
|
|
|
|
|
(($op->first->next->name eq 'const' and $op->first->next->flags == 34) |
1488
|
|
|
|
|
|
|
or $op->first->next->name eq 'padsv' # or $foo->bar() run-time lookup |
1489
|
|
|
|
|
|
|
or ($] < 5.010 and $op->first->next->name eq 'gvsv' and !$op->first->next->type # 5.8 ex-gvsv |
1490
|
|
|
|
|
|
|
and $op->first->next->next->name eq 'const' and $op->first->next->next->flags == 34)) |
1491
|
|
|
|
|
|
|
) { |
1492
|
0
|
|
|
|
|
0
|
my $pkgop = $op->first->next; |
1493
|
0
|
0
|
0
|
|
|
0
|
if ($] < 5.010 and !$op->first->next->type) { # 5.8 ex-gvsv |
1494
|
0
|
|
|
|
|
0
|
$pkgop = $op->first->next->next; |
1495
|
|
|
|
|
|
|
} |
1496
|
0
|
0
|
|
|
|
0
|
warn "check package_pv ".$pkgop->name." for method_name\n" if $debug{cv}; |
1497
|
0
|
|
|
|
|
0
|
my $pv = svop_or_padop_pv($pkgop); # 5.13: need to store away the pkg pv |
1498
|
0
|
0
|
0
|
|
|
0
|
if ($pv and $pv !~ /[! \(]/) { |
1499
|
0
|
|
|
|
|
0
|
$package_pv = $pv; |
1500
|
0
|
|
|
|
|
0
|
push_package($package_pv); |
1501
|
|
|
|
|
|
|
} else { |
1502
|
|
|
|
|
|
|
# mostly optimized-away padsv NULL pads with 5.8 |
1503
|
0
|
0
|
|
|
|
0
|
warn "package_pv for method_name not found\n" if $debug{cv}; |
1504
|
|
|
|
|
|
|
} |
1505
|
|
|
|
|
|
|
} |
1506
|
0
|
0
|
|
|
|
0
|
if ($op->type == $OP_CUSTOM) { |
1507
|
0
|
0
|
|
|
|
0
|
warn sprintf("CUSTOM OP %s $op\n", $op->name) if $verbose; |
1508
|
|
|
|
|
|
|
} |
1509
|
0
|
|
|
|
|
0
|
$prev_op = $op; |
1510
|
0
|
|
|
|
|
0
|
my $sibling; |
1511
|
0
|
0
|
0
|
|
|
0
|
if ($have_sibparent and !$op->moresib) { # HAS_SIBLING |
1512
|
0
|
|
|
|
|
0
|
$sibling = $op->parent; |
1513
|
0
|
0
|
0
|
|
|
0
|
warn "sibparent ",$op->name," $sibling\n" if $verbose and $debug{op}; |
1514
|
|
|
|
|
|
|
} else { |
1515
|
0
|
|
|
|
|
0
|
$sibling = $op->sibling; |
1516
|
|
|
|
|
|
|
} |
1517
|
|
|
|
|
|
|
return sprintf( "s\\_%x, s\\_%x, %s", |
1518
|
0
|
|
|
|
|
0
|
${ $op->next }, |
|
0
|
|
|
|
|
0
|
|
1519
|
|
|
|
|
|
|
$$sibling, |
1520
|
|
|
|
|
|
|
$op->_save_common_middle |
1521
|
|
|
|
|
|
|
); |
1522
|
|
|
|
|
|
|
} |
1523
|
|
|
|
|
|
|
|
1524
|
|
|
|
|
|
|
sub B::OP::save { |
1525
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
1526
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
1527
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
1528
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
1529
|
0
|
|
|
|
|
0
|
my $type = $op->type; |
1530
|
0
|
0
|
|
|
|
0
|
$nullop_count++ unless $type; |
1531
|
0
|
0
|
|
|
|
0
|
if ( $type == $OP_THREADSV ) { |
1532
|
|
|
|
|
|
|
# saves looking up ppaddr but it's a bit naughty to hard code this |
1533
|
0
|
|
|
|
|
0
|
$init->add(sprintf( "(void)find_threadsv(%s);", cstring( $threadsv_names[ $op->targ ]))); |
1534
|
|
|
|
|
|
|
} |
1535
|
0
|
0
|
|
|
|
0
|
if ( $type == $OP_UCFIRST ) { |
1536
|
0
|
|
|
|
|
0
|
$B::C::fold = 1; |
1537
|
0
|
0
|
|
|
|
0
|
if ($] >= 5.013009) { |
1538
|
0
|
0
|
|
|
|
0
|
warn "enabling -ffold with ucfirst\n" if $verbose; |
1539
|
0
|
0
|
|
|
|
0
|
require "utf8.pm" unless $savINC{"utf8.pm"}; |
1540
|
0
|
|
|
|
|
0
|
mark_package("utf8"); |
1541
|
0
|
|
|
|
|
0
|
load_utf8_heavy(); |
1542
|
|
|
|
|
|
|
} |
1543
|
|
|
|
|
|
|
} |
1544
|
0
|
0
|
|
|
|
0
|
if (ref($op) eq 'B::OP') { # check wrong BASEOPs |
1545
|
|
|
|
|
|
|
# [perl #80622] Introducing the entrytry hack, needed since 5.12, fixed with 5.13.8 a425677 |
1546
|
|
|
|
|
|
|
# ck_eval upgrades the UNOP entertry to a LOGOP, but B gets us just a B::OP (BASEOP). |
1547
|
|
|
|
|
|
|
# op->other points to the leavetry op, which is needed for the eval scope. |
1548
|
0
|
0
|
|
|
|
0
|
if ($op->name eq 'entertry') { |
1549
|
0
|
0
|
|
|
|
0
|
warn "[perl #80622] Upgrading entertry from BASEOP to LOGOP...\n" if $verbose; |
1550
|
0
|
|
|
|
|
0
|
bless $op, 'B::LOGOP'; |
1551
|
0
|
|
|
|
|
0
|
return $op->save($level); |
1552
|
|
|
|
|
|
|
} |
1553
|
|
|
|
|
|
|
} |
1554
|
|
|
|
|
|
|
|
1555
|
|
|
|
|
|
|
# since 5.10 nullified cops free their additional fields |
1556
|
0
|
0
|
0
|
|
|
0
|
if ( $PERL510 and !$type and $OP_COP{ $op->targ } ) { |
|
|
|
0
|
|
|
|
|
1557
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Null COP: %d\n", $op->targ ) if $debug{cops}; |
1558
|
0
|
|
|
|
|
0
|
if (0 and $optimize_cop) { |
1559
|
|
|
|
|
|
|
# XXX when is the NULL COP save to skip? |
1560
|
|
|
|
|
|
|
# unsafe after entersub, entereval, anoncode, sort block (pushmark pushmark) |
1561
|
|
|
|
|
|
|
# Rather skip this with CC not with C because we need the context. |
1562
|
|
|
|
|
|
|
# XXX we dont have the prevop, it can be any op type. |
1563
|
|
|
|
|
|
|
if ($verbose or $debug{cops}) { |
1564
|
|
|
|
|
|
|
my $prevop = getsym(sprintf("&op_list[%d]", $opsect->index)); |
1565
|
|
|
|
|
|
|
warn sprintf( "Skip Null COP: %d, prev=\\s%x\n", |
1566
|
|
|
|
|
|
|
$op->targ, $prevop); |
1567
|
|
|
|
|
|
|
} |
1568
|
|
|
|
|
|
|
return savesym( $op, $op->next->save ); |
1569
|
|
|
|
|
|
|
} |
1570
|
0
|
0
|
0
|
|
|
0
|
if ($ITHREADS and $] >= 5.017) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1571
|
0
|
|
|
|
|
0
|
$copsect->comment( |
1572
|
|
|
|
|
|
|
"$opsect_common, line, stashoff, file, hints, seq, warnings, hints_hash"); |
1573
|
0
|
|
|
|
|
0
|
$copsect->add(sprintf("%s, 0, 0, (char *)NULL, 0, 0, NULL, NULL", |
1574
|
|
|
|
|
|
|
$op->_save_common)); |
1575
|
|
|
|
|
|
|
} |
1576
|
|
|
|
|
|
|
elsif ($ITHREADS and $] >= 5.016) { |
1577
|
0
|
|
|
|
|
0
|
$copsect->comment( |
1578
|
|
|
|
|
|
|
"$opsect_common, line, stashpv, file, stashlen, hints, seq, warnings, hints_hash"); |
1579
|
0
|
|
|
|
|
0
|
$copsect->add(sprintf("%s, 0, (char *)NULL, NULL, 0, 0, 0, NULL, NULL", |
1580
|
|
|
|
|
|
|
$op->_save_common)); |
1581
|
|
|
|
|
|
|
} |
1582
|
|
|
|
|
|
|
elsif ($ITHREADS and $] >= 5.015004) { |
1583
|
0
|
|
|
|
|
0
|
$copsect->comment( |
1584
|
|
|
|
|
|
|
"$opsect_common, line, stash, file, hints, seq, warnings, hints_hash"); |
1585
|
0
|
|
|
|
|
0
|
$copsect->add(sprintf("%s, 0, (char *)NULL, NULL, 0, 0, NULL, NULL", |
1586
|
|
|
|
|
|
|
$op->_save_common)); |
1587
|
|
|
|
|
|
|
} |
1588
|
|
|
|
|
|
|
elsif ($PERL512) { |
1589
|
0
|
|
|
|
|
0
|
$copsect->comment( |
1590
|
|
|
|
|
|
|
"$opsect_common, line, stash, file, hints, seq, warnings, hints_hash"); |
1591
|
0
|
0
|
|
|
|
0
|
$copsect->add(sprintf("%s, 0, %s, NULL, 0, 0, NULL, NULL", |
1592
|
|
|
|
|
|
|
$op->_save_common, $ITHREADS ? "(char *)NULL" : "Nullhv")); |
1593
|
|
|
|
|
|
|
} |
1594
|
|
|
|
|
|
|
elsif ($PERL510) { |
1595
|
0
|
|
|
|
|
0
|
$copsect->comment("$opsect_common, line, label, seq, warn_int, hints_hash"); |
1596
|
0
|
|
|
|
|
0
|
$copsect->add(sprintf("%s, %u, NULL, " . "NULL, NULL, 0, " . "%u, %d, NULL", |
1597
|
|
|
|
|
|
|
$op->_save_common, 0, 0, 0)); |
1598
|
|
|
|
|
|
|
} |
1599
|
|
|
|
|
|
|
else { |
1600
|
0
|
|
|
|
|
0
|
$copsect->comment( |
1601
|
|
|
|
|
|
|
"$opsect_common, label, seq, arybase, line, warnings, hints_hash"); |
1602
|
0
|
|
|
|
|
0
|
$copsect->add( |
1603
|
|
|
|
|
|
|
sprintf( "%s, NULL, NULL, NULL, 0, 0, 0, NULL", $op->_save_common ) ); |
1604
|
|
|
|
|
|
|
} |
1605
|
0
|
|
|
|
|
0
|
my $ix = $copsect->index; |
1606
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "cop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
1607
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
1608
|
0
|
|
|
|
|
0
|
savesym( $op, "(OP*)&cop_list[$ix]" ); |
1609
|
|
|
|
|
|
|
} |
1610
|
|
|
|
|
|
|
else { |
1611
|
0
|
|
|
|
|
0
|
$opsect->comment($opsect_common); |
1612
|
0
|
|
|
|
|
0
|
$opsect->add( $op->_save_common ); |
1613
|
|
|
|
|
|
|
|
1614
|
0
|
0
|
|
|
|
0
|
$opsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
1615
|
0
|
|
|
|
|
0
|
my $ix = $opsect->index; |
1616
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "op_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
1617
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
1618
|
|
|
|
|
|
|
warn( sprintf( " OP=%s targ=%d flags=0x%x private=0x%x\n", |
1619
|
0
|
0
|
|
|
|
0
|
peekop($op), $op->targ, $op->flags, $op->private ) ) if $debug{op}; |
1620
|
0
|
|
|
|
|
0
|
savesym( $op, "&op_list[$ix]" ); |
1621
|
|
|
|
|
|
|
} |
1622
|
|
|
|
|
|
|
} |
1623
|
|
|
|
|
|
|
|
1624
|
|
|
|
|
|
|
# needed for special GV logic: save only stashes for stashes |
1625
|
|
|
|
|
|
|
package B::STASHGV; |
1626
|
|
|
|
|
|
|
our @ISA = ('B::GV'); |
1627
|
|
|
|
|
|
|
|
1628
|
|
|
|
|
|
|
package B::FAKEOP; |
1629
|
|
|
|
|
|
|
|
1630
|
|
|
|
|
|
|
our @ISA = qw(B::OP); |
1631
|
|
|
|
|
|
|
|
1632
|
|
|
|
|
|
|
sub new { |
1633
|
0
|
|
|
0
|
|
0
|
my ( $class, %objdata ) = @_; |
1634
|
0
|
|
|
|
|
0
|
bless \%objdata, $class; |
1635
|
|
|
|
|
|
|
} |
1636
|
|
|
|
|
|
|
|
1637
|
|
|
|
|
|
|
sub save { |
1638
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
1639
|
0
|
|
|
|
|
0
|
$opsect->add( |
1640
|
|
|
|
|
|
|
sprintf( "%s, %s, %s", $op->next, $op->sibling, $op->_save_common_middle ) |
1641
|
|
|
|
|
|
|
); |
1642
|
0
|
|
|
|
|
0
|
my $ix = $opsect->index; |
1643
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "op_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
1644
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
1645
|
0
|
|
|
|
|
0
|
return "&op_list[$ix]"; |
1646
|
|
|
|
|
|
|
} |
1647
|
|
|
|
|
|
|
|
1648
|
|
|
|
|
|
|
*_save_common_middle = \&B::OP::_save_common_middle; |
1649
|
0
|
0
|
|
0
|
|
0
|
sub next { $_[0]->{"next"} || 0 } |
1650
|
0
|
0
|
|
0
|
|
0
|
sub type { $_[0]->{type} || 0 } |
1651
|
0
|
0
|
|
0
|
|
0
|
sub sibling { $_[0]->{sibling} || 0 } |
1652
|
0
|
0
|
|
0
|
|
0
|
sub moresib { $_[0]->{moresib} || 0 } |
1653
|
0
|
0
|
|
0
|
|
0
|
sub parent { $_[0]->{parent} || 0 } |
1654
|
0
|
0
|
|
0
|
|
0
|
sub ppaddr { $_[0]->{ppaddr} || 0 } |
1655
|
0
|
0
|
|
0
|
|
0
|
sub targ { $_[0]->{targ} || 0 } |
1656
|
0
|
0
|
|
0
|
|
0
|
sub flags { $_[0]->{flags} || 0 } |
1657
|
0
|
0
|
|
0
|
|
0
|
sub private { $_[0]->{private} || 0 } |
1658
|
0
|
0
|
|
0
|
|
0
|
sub rettype { $_[0]->{rettype} || 0 } |
1659
|
|
|
|
|
|
|
|
1660
|
|
|
|
|
|
|
package B::C; |
1661
|
|
|
|
|
|
|
|
1662
|
|
|
|
|
|
|
# dummy for B::C, only needed for B::CC |
1663
|
|
|
|
0
|
0
|
|
sub label {} |
1664
|
|
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
# save alternate ops if defined, and also add labels (needed for B::CC) |
1666
|
|
|
|
|
|
|
sub do_labels ($$@) { |
1667
|
0
|
|
|
0
|
0
|
0
|
my $op = shift; |
1668
|
0
|
|
|
|
|
0
|
my $level = shift; |
1669
|
0
|
|
|
|
|
0
|
for my $m (@_) { |
1670
|
55
|
|
|
55
|
|
295
|
no strict 'refs'; |
|
55
|
|
|
|
|
92
|
|
|
55
|
|
|
|
|
146331
|
|
1671
|
0
|
0
|
|
|
|
0
|
my $mo = $op->$m if $m; |
1672
|
0
|
0
|
0
|
|
|
0
|
if ( $mo and $$mo ) { |
1673
|
0
|
|
|
|
|
0
|
label($mo); |
1674
|
0
|
0
|
0
|
|
|
0
|
$mo->save($level) if $m ne 'first' |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1675
|
|
|
|
|
|
|
or ($op->flags & 4 |
1676
|
|
|
|
|
|
|
and !($op->name eq 'const' and $op->flags & 64)); #OPpCONST_BARE has no first |
1677
|
|
|
|
|
|
|
} |
1678
|
|
|
|
|
|
|
} |
1679
|
|
|
|
|
|
|
} |
1680
|
|
|
|
|
|
|
|
1681
|
|
|
|
|
|
|
sub B::UNOP::save { |
1682
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
1683
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
1684
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
1685
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
1686
|
0
|
|
|
|
|
0
|
$unopsect->comment("$opsect_common, first"); |
1687
|
0
|
|
|
|
|
0
|
$unopsect->add( sprintf( "%s, s\\_%x", $op->_save_common, ${ $op->first } ) ); |
|
0
|
|
|
|
|
0
|
|
1688
|
0
|
0
|
|
|
|
0
|
$unopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
1689
|
0
|
|
|
|
|
0
|
my $ix = $unopsect->index; |
1690
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "unop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
1691
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
1692
|
0
|
|
|
|
|
0
|
$sym = savesym( $op, "(OP*)&unop_list[$ix]" ); |
1693
|
0
|
0
|
0
|
|
|
0
|
if ($op->name eq 'method' and $op->first and $op->first->name eq 'const') { |
|
|
|
0
|
|
|
|
|
1694
|
0
|
|
|
|
|
0
|
my $method = svop_name($op->first); |
1695
|
0
|
0
|
0
|
|
|
0
|
if (!$method and $ITHREADS) { |
1696
|
0
|
|
|
|
|
0
|
$method = padop_name($op->first, curcv); # XXX (curpad[targ]) |
1697
|
|
|
|
|
|
|
} |
1698
|
0
|
0
|
0
|
|
|
0
|
warn "method -> const $method\n" if $debug{pkg} and $ITHREADS; |
1699
|
|
|
|
|
|
|
#324,#326 need to detect ->(maybe::next|maybe|next)::(method|can) |
1700
|
0
|
0
|
|
|
|
0
|
if ($method =~ /^(maybe::next|maybe|next)::(method|can)$/) { |
|
|
0
|
|
|
|
|
|
1701
|
0
|
0
|
|
|
|
0
|
warn "mark \"$1\" for method $method\n" if $debug{pkg}; |
1702
|
0
|
|
|
|
|
0
|
mark_package($1, 1); |
1703
|
0
|
|
|
|
|
0
|
mark_package("mro", 1); |
1704
|
|
|
|
|
|
|
} # and also the old 5.8 NEXT|EVERY with non-fixed method names und subpackages |
1705
|
|
|
|
|
|
|
elsif ($method =~ /^(NEXT|EVERY)::/) { |
1706
|
0
|
0
|
|
|
|
0
|
warn "mark \"$1\" for method $method\n" if $debug{pkg}; |
1707
|
0
|
|
|
|
|
0
|
mark_package($1, 1); |
1708
|
0
|
0
|
|
|
|
0
|
mark_package("NEXT", 1) if $1 ne "NEXT"; |
1709
|
|
|
|
|
|
|
} |
1710
|
|
|
|
|
|
|
} |
1711
|
0
|
|
|
|
|
0
|
do_labels ($op, $level+1, 'first'); |
1712
|
0
|
|
|
|
|
0
|
$sym; |
1713
|
|
|
|
|
|
|
} |
1714
|
|
|
|
|
|
|
|
1715
|
|
|
|
|
|
|
sub is_constant { |
1716
|
0
|
|
|
0
|
0
|
0
|
my $s = shift; |
1717
|
0
|
0
|
|
|
|
0
|
return 1 if $s =~ /^(&sv_list|\-?\d+|Nullsv)/; # not gv_list, hek |
1718
|
0
|
|
|
|
|
0
|
return 0; |
1719
|
|
|
|
|
|
|
} |
1720
|
|
|
|
|
|
|
|
1721
|
|
|
|
|
|
|
sub B::UNOP_AUX::save { |
1722
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
1723
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
1724
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
1725
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
1726
|
0
|
0
|
|
|
|
0
|
my @aux_list = $op->name eq 'multideref' |
1727
|
|
|
|
|
|
|
? $op->aux_list_thr # our own version. GH#283, GH#341 |
1728
|
|
|
|
|
|
|
: $op->aux_list; |
1729
|
0
|
|
|
|
|
0
|
my $auxlen = scalar @aux_list; |
1730
|
0
|
|
|
|
|
0
|
$unopauxsect->comment("$opsect_common, first, aux"); |
1731
|
0
|
|
|
|
|
0
|
my $ix = $unopauxsect->index + 1; |
1732
|
|
|
|
|
|
|
$unopauxsect->add( |
1733
|
|
|
|
|
|
|
sprintf("%s, s\\_%x, %s+1", |
1734
|
0
|
|
|
|
|
0
|
$op->_save_common, ${ $op->first }, "unopaux_item${ix}")); |
|
0
|
|
|
|
|
0
|
|
1735
|
0
|
0
|
|
|
|
0
|
$unopauxsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
1736
|
|
|
|
|
|
|
# This cannot be a section, as the number of elements is variable |
1737
|
0
|
|
|
|
|
0
|
my $i = 1; |
1738
|
0
|
0
|
|
|
|
0
|
my $s = "Static UNOP_AUX_item unopaux_item".$ix."[] = { /* ".$op->name." */\n\t" |
1739
|
|
|
|
|
|
|
.($C99?"{.uv=$auxlen}":$auxlen). " \t/* length prefix */\n"; |
1740
|
0
|
|
|
|
|
0
|
my $action = 0; |
1741
|
0
|
|
|
|
|
0
|
for my $item (@aux_list) { |
1742
|
0
|
0
|
|
|
|
0
|
unless (ref $item) { |
1743
|
|
|
|
|
|
|
# symbolize MDEREF and SIGNATURE actions and flags, just for the comments |
1744
|
0
|
|
|
|
|
0
|
my $cmt = 'action'; |
1745
|
0
|
0
|
|
|
|
0
|
if ($verbose) { |
1746
|
0
|
0
|
|
|
|
0
|
if ($op->name eq 'multideref') { |
|
|
0
|
|
|
|
|
|
1747
|
0
|
|
|
|
|
0
|
my $act = $item & 0xf; # MDEREF_ACTION_MASK |
1748
|
0
|
0
|
|
|
|
0
|
$cmt = 'AV_pop_rv2av_aelem' if $act == 1; |
1749
|
0
|
0
|
|
|
|
0
|
$cmt = 'AV_gvsv_vivify_rv2av_aelem' if $act == 2; |
1750
|
0
|
0
|
|
|
|
0
|
$cmt = 'AV_padsv_vivify_rv2av_aelem' if $act == 3; |
1751
|
0
|
0
|
|
|
|
0
|
$cmt = 'AV_vivify_rv2av_aelem' if $act == 4; |
1752
|
0
|
0
|
|
|
|
0
|
$cmt = 'AV_padav_aelem' if $act == 5; |
1753
|
0
|
0
|
|
|
|
0
|
$cmt = 'AV_gvav_aelem' if $act == 6; |
1754
|
0
|
0
|
|
|
|
0
|
$cmt = 'HV_pop_rv2hv_helem' if $act == 8; |
1755
|
0
|
0
|
|
|
|
0
|
$cmt = 'HV_gvsv_vivify_rv2hv_helem' if $act == 9; |
1756
|
0
|
0
|
|
|
|
0
|
$cmt = 'HV_padsv_vivify_rv2hv_helem' if $act == 10; |
1757
|
0
|
0
|
|
|
|
0
|
$cmt = 'HV_vivify_rv2hv_helem' if $act == 11; |
1758
|
0
|
0
|
|
|
|
0
|
$cmt = 'HV_padhv_helem' if $act == 12; |
1759
|
0
|
0
|
|
|
|
0
|
$cmt = 'HV_gvhv_helem' if $act == 13; |
1760
|
0
|
|
|
|
|
0
|
my $idx = $item & 0x30; # MDEREF_INDEX_MASK |
1761
|
0
|
0
|
|
|
|
0
|
$cmt .= '' if $idx == 0x0; |
1762
|
0
|
0
|
|
|
|
0
|
$cmt .= ' INDEX_const' if $idx == 0x10; |
1763
|
0
|
0
|
|
|
|
0
|
$cmt .= ' INDEX_padsv' if $idx == 0x20; |
1764
|
0
|
0
|
|
|
|
0
|
$cmt .= ' INDEX_gvsv' if $idx == 0x30; |
1765
|
|
|
|
|
|
|
} |
1766
|
|
|
|
|
|
|
elsif ($op->name eq 'signature') { |
1767
|
0
|
|
|
|
|
0
|
my $act = $item & 0xf; # SIGNATURE_ACTION_MASK |
1768
|
0
|
0
|
|
|
|
0
|
$cmt = 'reload' if $act == 0; |
1769
|
0
|
0
|
|
|
|
0
|
$cmt = 'end' if $act == 1; |
1770
|
0
|
0
|
|
|
|
0
|
$cmt = 'padintro' if $act == 2; |
1771
|
0
|
0
|
|
|
|
0
|
$cmt = 'arg' if $act == 3; |
1772
|
0
|
0
|
|
|
|
0
|
$cmt = 'arg_default_none' if $act == 4; |
1773
|
0
|
0
|
|
|
|
0
|
$cmt = 'arg_default_undef' if $act == 5; |
1774
|
0
|
0
|
|
|
|
0
|
$cmt = 'arg_default_0' if $act == 6; |
1775
|
0
|
0
|
|
|
|
0
|
$cmt = 'arg_default_1' if $act == 7; |
1776
|
0
|
0
|
|
|
|
0
|
$cmt = 'arg_default_iv' if $act == 8; |
1777
|
0
|
0
|
|
|
|
0
|
$cmt = 'arg_default_const' if $act == 9; |
1778
|
0
|
0
|
|
|
|
0
|
$cmt = 'arg_default_padsv' if $act == 10; |
1779
|
0
|
0
|
|
|
|
0
|
$cmt = 'arg_default_gvsv' if $act == 11; |
1780
|
0
|
0
|
|
|
|
0
|
$cmt = 'arg_default_op' if $act == 12; |
1781
|
0
|
0
|
|
|
|
0
|
$cmt = 'array' if $act == 13; |
1782
|
0
|
0
|
|
|
|
0
|
$cmt = 'hash' if $act == 14; |
1783
|
0
|
|
|
|
|
0
|
my $idx = $item & 0x3F; # SIGNATURE_MASK |
1784
|
0
|
0
|
|
|
|
0
|
$cmt .= '' if $idx == 0x0; |
1785
|
0
|
0
|
|
|
|
0
|
$cmt .= ' flag skip' if $idx == 0x10; |
1786
|
0
|
0
|
|
|
|
0
|
$cmt .= ' flag ref' if $idx == 0x20; |
1787
|
|
|
|
|
|
|
} else { |
1788
|
0
|
|
|
|
|
0
|
die "Unknown UNOP_AUX op {$op->name}"; |
1789
|
|
|
|
|
|
|
} |
1790
|
|
|
|
|
|
|
} |
1791
|
0
|
|
|
|
|
0
|
$action = $item; |
1792
|
0
|
0
|
|
|
|
0
|
warn "{$op->name} action $action $cmt\n" if $debug{hv}; |
1793
|
0
|
0
|
|
|
|
0
|
$s .= ($C99 ? sprintf("\t,{.uv=0x%x} \t/* %s: %u */\n", $item, $cmt, $item) |
1794
|
|
|
|
|
|
|
: sprintf("\t,0x%x \t/* %s: %u */\n", $item, $cmt, $item)); |
1795
|
|
|
|
|
|
|
} else { |
1796
|
|
|
|
|
|
|
# const and sv already at compile-time, gv deferred to init-time. |
1797
|
|
|
|
|
|
|
# testcase: $a[-1] -1 as B::IV not as -1 |
1798
|
|
|
|
|
|
|
# hmm, if const ensure that candidate CONSTs have been HEKified. (pp_multideref assertion) |
1799
|
|
|
|
|
|
|
# || SvTYPE(keysv) >= SVt_PVMG |
1800
|
|
|
|
|
|
|
# || !SvOK(keysv) |
1801
|
|
|
|
|
|
|
# || SvROK(keysv) |
1802
|
|
|
|
|
|
|
# || SvIsCOW_shared_hash(keysv)); |
1803
|
0
|
0
|
|
|
|
0
|
my $constkey = ($action & 0x30) == 0x10 ? 1 : 0; |
1804
|
0
|
0
|
|
|
|
0
|
my $itemsym = $item->save("unopaux_item".$ix."[".$i."]" . ($constkey ? " const" : "")); |
1805
|
0
|
0
|
|
|
|
0
|
if (is_constant($itemsym)) { |
1806
|
0
|
0
|
|
|
|
0
|
if (ref $item eq 'B::IV') { |
|
|
0
|
|
|
|
|
|
1807
|
0
|
|
|
|
|
0
|
my $iv = $item->IVX; |
1808
|
0
|
0
|
|
|
|
0
|
$s .= ($C99 ? "\t,{.iv=$iv}\n" |
1809
|
|
|
|
|
|
|
: "\t,PTR2IV($iv)\n"); |
1810
|
|
|
|
|
|
|
} elsif (ref $item eq 'B::UV') { # also for PAD_OFFSET |
1811
|
0
|
|
|
|
|
0
|
my $uv = $item->UVX; |
1812
|
0
|
0
|
|
|
|
0
|
$s .= ($C99 ? "\t,{.uv=$uv}\n" |
1813
|
|
|
|
|
|
|
: "\t,PTR2IV($uv)\n"); |
1814
|
|
|
|
|
|
|
} else { # SV |
1815
|
0
|
0
|
|
|
|
0
|
$s .= ($C99 ? "\t,{.sv=$itemsym}\n" |
1816
|
|
|
|
|
|
|
: "\t,PTR2UV($itemsym)\n"); |
1817
|
|
|
|
|
|
|
} |
1818
|
|
|
|
|
|
|
} else { |
1819
|
|
|
|
|
|
|
# gv or other late inits |
1820
|
0
|
0
|
|
|
|
0
|
$s .= ($C99 ? "\t,{.sv=Nullsv} \t/* $itemsym */\n" |
1821
|
|
|
|
|
|
|
: "\t,0 \t/* $itemsym */\n"); |
1822
|
0
|
|
|
|
|
0
|
$init->add("unopaux_item".$ix."[".$i."].sv = (SV*)$itemsym;"); |
1823
|
|
|
|
|
|
|
} |
1824
|
|
|
|
|
|
|
} |
1825
|
0
|
|
|
|
|
0
|
$i++; |
1826
|
|
|
|
|
|
|
} |
1827
|
0
|
|
|
|
|
0
|
$decl->add($s."};"); |
1828
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "unopaux_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
1829
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
1830
|
0
|
|
|
|
|
0
|
$sym = savesym( $op, "(OP*)&unopaux_list[$ix]" ); |
1831
|
0
|
|
|
|
|
0
|
push @B::C::static_free, $sym; |
1832
|
|
|
|
|
|
|
# $free->add(" ($sym)->op_type = OP_NULL;"); |
1833
|
0
|
|
|
|
|
0
|
do_labels ($op, $level+1, 'first'); |
1834
|
0
|
|
|
|
|
0
|
$sym; |
1835
|
|
|
|
|
|
|
} |
1836
|
|
|
|
|
|
|
|
1837
|
|
|
|
|
|
|
# cannot save it statically in a sect. need the class (ref) and the ppaddr |
1838
|
|
|
|
|
|
|
#sub B::XOP::save { |
1839
|
|
|
|
|
|
|
# my ( $op, $level ) = @_; |
1840
|
|
|
|
|
|
|
# my $sym = objsym($op); |
1841
|
|
|
|
|
|
|
# return $sym if defined $sym; |
1842
|
|
|
|
|
|
|
# # which class |
1843
|
|
|
|
|
|
|
# $binopsect->comment("$opsect_common, first, last"); |
1844
|
|
|
|
|
|
|
# $binopsect->add( |
1845
|
|
|
|
|
|
|
# sprintf( "%s, s\\_%x, s\\_%x", |
1846
|
|
|
|
|
|
|
# $op->_save_common, |
1847
|
|
|
|
|
|
|
# ${ $op->first }, |
1848
|
|
|
|
|
|
|
# ${ $op->last } )); |
1849
|
|
|
|
|
|
|
# $binopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
1850
|
|
|
|
|
|
|
# my $ix = $binopsect->index; |
1851
|
|
|
|
|
|
|
# $init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
1852
|
|
|
|
|
|
|
# unless $B::C::optimize_ppaddr; |
1853
|
|
|
|
|
|
|
# $sym = savesym( $op, "(OP*)&binop_list[$ix]" ); |
1854
|
|
|
|
|
|
|
# do_labels ($op, $level+1, 'first', 'last'); |
1855
|
|
|
|
|
|
|
# $sym; |
1856
|
|
|
|
|
|
|
#} |
1857
|
|
|
|
|
|
|
|
1858
|
|
|
|
|
|
|
sub B::BINOP::save { |
1859
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
1860
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
1861
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
1862
|
|
|
|
|
|
|
#return B::XOP::save(@_) if $op->type == $OP_CUSTOM; |
1863
|
|
|
|
|
|
|
|
1864
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
1865
|
0
|
|
|
|
|
0
|
$binopsect->comment("$opsect_common, first, last"); |
1866
|
|
|
|
|
|
|
$binopsect->add( |
1867
|
|
|
|
|
|
|
sprintf( "%s, s\\_%x, s\\_%x", |
1868
|
|
|
|
|
|
|
$op->_save_common, |
1869
|
0
|
|
|
|
|
0
|
${ $op->first }, |
1870
|
0
|
|
|
|
|
0
|
${ $op->last } )); |
|
0
|
|
|
|
|
0
|
|
1871
|
0
|
0
|
|
|
|
0
|
$binopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
1872
|
0
|
|
|
|
|
0
|
my $ix = $binopsect->index; |
1873
|
0
|
|
|
|
|
0
|
my $ppaddr = $op->ppaddr; |
1874
|
0
|
0
|
|
|
|
0
|
if ($op->type == $OP_CUSTOM) { |
1875
|
0
|
|
|
|
|
0
|
my $ptr = $$op; |
1876
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.019003 and ($op->name eq 'Devel_Peek_Dump' or $op->name eq 'Dump')){ |
|
|
|
0
|
|
|
|
|
1877
|
0
|
0
|
|
|
|
0
|
warn "custom op Devel_Peek_Dump\n" if $verbose; |
1878
|
0
|
0
|
|
|
|
0
|
$decl->add(' |
1879
|
|
|
|
|
|
|
static void |
1880
|
|
|
|
|
|
|
S_do_dump(pTHX_ SV *const sv, I32 lim) |
1881
|
|
|
|
|
|
|
{ |
1882
|
|
|
|
|
|
|
dVAR; |
1883
|
|
|
|
|
|
|
SV *pv_lim_sv = get_svs("Devel::Peek::pv_limit", 0); |
1884
|
|
|
|
|
|
|
const STRLEN pv_lim = pv_lim_sv ? SvIV(pv_lim_sv) : 0; |
1885
|
|
|
|
|
|
|
SV *dumpop = get_svs("Devel::Peek::dump_ops", 0); |
1886
|
|
|
|
|
|
|
const U16 save_dumpindent = PL_dumpindent; |
1887
|
|
|
|
|
|
|
PL_dumpindent = 2; |
1888
|
|
|
|
|
|
|
do_sv_dump(0, Perl_debug_log, sv, 0, lim, |
1889
|
|
|
|
|
|
|
(bool)(dumpop && SvTRUE(dumpop)), pv_lim); |
1890
|
|
|
|
|
|
|
PL_dumpindent = save_dumpindent; |
1891
|
|
|
|
|
|
|
} |
1892
|
|
|
|
|
|
|
static OP * |
1893
|
|
|
|
|
|
|
S_pp_dump(pTHX) |
1894
|
|
|
|
|
|
|
{ |
1895
|
|
|
|
|
|
|
dSP; |
1896
|
|
|
|
|
|
|
const I32 lim = PL_op->op_private == 2 ? (I32)POPi : 4; |
1897
|
|
|
|
|
|
|
dPOPss; |
1898
|
|
|
|
|
|
|
S_do_dump(aTHX_ sv, lim); |
1899
|
|
|
|
|
|
|
RETPUSHUNDEF; |
1900
|
|
|
|
|
|
|
}') unless $B::C::Devel_Peek_Dump_added; |
1901
|
0
|
|
|
|
|
0
|
$ppaddr = 'S_pp_dump'; |
1902
|
0
|
|
|
|
|
0
|
$B::C::Devel_Peek_Dump_added++; |
1903
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $ppaddr )); |
1904
|
|
|
|
|
|
|
} else { |
1905
|
0
|
0
|
|
|
|
0
|
warn "Warning: Unknown custom op ".$op->name."\n" if $verbose; |
1906
|
0
|
|
|
|
|
0
|
$ppaddr = sprintf('Perl_custom_op_xop(aTHX_ INT2PTR(OP*, 0x%x))', $$op); |
1907
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $ppaddr )); |
1908
|
|
|
|
|
|
|
} |
1909
|
|
|
|
|
|
|
} else { |
1910
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "binop_list[%d].op_ppaddr = %s;", $ix, $ppaddr ) ) |
1911
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
1912
|
|
|
|
|
|
|
} |
1913
|
0
|
|
|
|
|
0
|
$sym = savesym( $op, "(OP*)&binop_list[$ix]" ); |
1914
|
0
|
|
|
|
|
0
|
do_labels ($op, $level+1, 'first', 'last'); |
1915
|
0
|
|
|
|
|
0
|
$sym; |
1916
|
|
|
|
|
|
|
} |
1917
|
|
|
|
|
|
|
|
1918
|
|
|
|
|
|
|
sub B::LISTOP::save { |
1919
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
1920
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
1921
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
1922
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
1923
|
0
|
|
|
|
|
0
|
$listopsect->comment("$opsect_common, first, last"); |
1924
|
|
|
|
|
|
|
$listopsect->add( |
1925
|
|
|
|
|
|
|
sprintf( "%s, s\\_%x, s\\_%x", |
1926
|
|
|
|
|
|
|
$op->_save_common, |
1927
|
0
|
|
|
|
|
0
|
${ $op->first }, |
1928
|
0
|
|
|
|
|
0
|
${ $op->last } )); |
|
0
|
|
|
|
|
0
|
|
1929
|
0
|
0
|
|
|
|
0
|
$listopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
1930
|
0
|
|
|
|
|
0
|
my $ix = $listopsect->index; |
1931
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "listop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
1932
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
1933
|
0
|
|
|
|
|
0
|
$sym = savesym( $op, "(OP*)&listop_list[$ix]" ); |
1934
|
0
|
0
|
0
|
|
|
0
|
if ($op->type == $OP_DBMOPEN) { |
|
|
0
|
|
|
|
|
|
1935
|
|
|
|
|
|
|
# resolves it at compile-time, not at run-time |
1936
|
0
|
|
|
|
|
0
|
mark_package('AnyDBM_File'); # to save $INC{AnyDBM_File} |
1937
|
0
|
0
|
|
|
|
0
|
require AnyDBM_File unless $savINC{'AnyDBM_File.pm'}; |
1938
|
0
|
|
|
|
|
0
|
$curINC{'AnyDBM_File.pm'} = $INC{'AnyDBM_File.pm'}; |
1939
|
0
|
|
|
|
|
0
|
AnyDBM_File->import; # strip the @ISA |
1940
|
0
|
|
|
|
|
0
|
my $dbm = $AnyDBM_File::ISA[0]; # take the winner (only) |
1941
|
0
|
|
|
|
|
0
|
svref_2object( \&{"$dbm\::bootstrap"} )->save; |
|
0
|
|
|
|
|
0
|
|
1942
|
0
|
|
|
|
|
0
|
svref_2object( \&{"$dbm\::TIEHASH"} )->save; # called by pp_dbmopen |
|
0
|
|
|
|
|
0
|
|
1943
|
0
|
|
|
|
|
0
|
$curINC{$dbm.".pm"} = $INC{$dbm.".pm"}; |
1944
|
|
|
|
|
|
|
} elsif ($op->type == $OP_FORMLINE and $B::C::const_strings) { # -O3 ~ |
1945
|
|
|
|
|
|
|
# non-static only for all const strings containing ~ #277 |
1946
|
0
|
|
|
|
|
0
|
my $sv; |
1947
|
0
|
|
|
|
|
0
|
my $fop = $op; |
1948
|
0
|
|
|
|
|
0
|
my $svop = $op->first; |
1949
|
0
|
|
0
|
|
|
0
|
while ($svop != $op and ref($svop) ne 'B::NULL') { |
1950
|
0
|
0
|
0
|
|
|
0
|
if ($svop->name eq 'const' and $svop->can('sv')) { |
1951
|
0
|
|
|
|
|
0
|
$sv = $svop->sv; |
1952
|
|
|
|
|
|
|
} |
1953
|
0
|
0
|
0
|
|
|
0
|
if ($sv and $sv->can("PV") and $sv->PV and $sv->PV =~ /~/m) { |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1954
|
0
|
|
|
|
|
0
|
local $B::C::const_strings; |
1955
|
0
|
0
|
|
|
|
0
|
warn "force non-static formline arg ",cstring($sv->PV),"\n" if $debug{pv}; |
1956
|
0
|
|
|
|
|
0
|
$svop->save($level, "svop const"); |
1957
|
|
|
|
|
|
|
} |
1958
|
0
|
|
|
|
|
0
|
$svop = $svop->next; |
1959
|
|
|
|
|
|
|
} |
1960
|
|
|
|
|
|
|
} |
1961
|
0
|
|
|
|
|
0
|
do_labels ($op, $level+1, 'first', 'last'); |
1962
|
0
|
|
|
|
|
0
|
$sym; |
1963
|
|
|
|
|
|
|
} |
1964
|
|
|
|
|
|
|
|
1965
|
|
|
|
|
|
|
sub B::LOGOP::save { |
1966
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
1967
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
1968
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
1969
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
1970
|
0
|
|
|
|
|
0
|
$logopsect->comment("$opsect_common, first, other"); |
1971
|
|
|
|
|
|
|
$logopsect->add( |
1972
|
|
|
|
|
|
|
sprintf( "%s, s\\_%x, s\\_%x", |
1973
|
|
|
|
|
|
|
$op->_save_common, |
1974
|
0
|
|
|
|
|
0
|
${ $op->first }, |
1975
|
0
|
|
|
|
|
0
|
${ $op->other } )); |
|
0
|
|
|
|
|
0
|
|
1976
|
0
|
0
|
|
|
|
0
|
$logopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
1977
|
0
|
|
|
|
|
0
|
my $ix = $logopsect->index; |
1978
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "logop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
1979
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
1980
|
0
|
|
|
|
|
0
|
$sym = savesym( $op, "(OP*)&logop_list[$ix]" ); |
1981
|
0
|
|
|
|
|
0
|
do_labels ($op, $level+1, 'first', 'other'); |
1982
|
0
|
|
|
|
|
0
|
$sym; |
1983
|
|
|
|
|
|
|
} |
1984
|
|
|
|
|
|
|
|
1985
|
|
|
|
|
|
|
sub B::LOOP::save { |
1986
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
1987
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
1988
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
1989
|
|
|
|
|
|
|
|
1990
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
1991
|
|
|
|
|
|
|
#warn sprintf("LOOP: redoop %s, nextop %s, lastop %s\n", |
1992
|
|
|
|
|
|
|
# peekop($op->redoop), peekop($op->nextop), |
1993
|
|
|
|
|
|
|
# peekop($op->lastop)) if $debug{op}; |
1994
|
0
|
|
|
|
|
0
|
$loopsect->comment("$opsect_common, first, last, redoop, nextop, lastop"); |
1995
|
|
|
|
|
|
|
$loopsect->add( |
1996
|
|
|
|
|
|
|
sprintf( |
1997
|
|
|
|
|
|
|
"%s, s\\_%x, s\\_%x, s\\_%x, s\\_%x, s\\_%x", |
1998
|
|
|
|
|
|
|
$op->_save_common, |
1999
|
0
|
|
|
|
|
0
|
${ $op->first }, |
2000
|
0
|
|
|
|
|
0
|
${ $op->last }, |
2001
|
0
|
|
|
|
|
0
|
${ $op->redoop }, |
2002
|
0
|
|
|
|
|
0
|
${ $op->nextop }, |
2003
|
0
|
|
|
|
|
0
|
${ $op->lastop } |
|
0
|
|
|
|
|
0
|
|
2004
|
|
|
|
|
|
|
) |
2005
|
|
|
|
|
|
|
); |
2006
|
0
|
0
|
|
|
|
0
|
$loopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
2007
|
0
|
|
|
|
|
0
|
my $ix = $loopsect->index; |
2008
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "loop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
2009
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
2010
|
0
|
|
|
|
|
0
|
$sym = savesym( $op, "(OP*)&loop_list[$ix]" ); |
2011
|
0
|
|
|
|
|
0
|
do_labels($op, $level+1, qw(first last redoop nextop lastop)); |
2012
|
0
|
|
|
|
|
0
|
$sym; |
2013
|
|
|
|
|
|
|
} |
2014
|
|
|
|
|
|
|
|
2015
|
|
|
|
|
|
|
sub B::METHOP::save { |
2016
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
2017
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
2018
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
2019
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
2020
|
0
|
|
|
|
|
0
|
$methopsect->comment("$opsect_common, first, rclass"); |
2021
|
0
|
0
|
|
|
|
0
|
my $union = $op->name eq 'method' ? "{.op_first=(OP*)%s}" : "{.op_meth_sv=(SV*)%s}"; |
2022
|
0
|
0
|
|
|
|
0
|
$union = "%s" unless $C99; |
2023
|
0
|
0
|
|
|
|
0
|
my $s = "%s, $union, ". ($ITHREADS ? "(PADOFFSET)%s" : "(SV*)%s"); # rclass |
2024
|
0
|
|
|
|
|
0
|
my $ix = $methopsect->index + 1; |
2025
|
0
|
0
|
|
|
|
0
|
my $rclass = $ITHREADS ? $op->rclass : $op->rclass->save("op_rclass_sv"); |
2026
|
0
|
0
|
|
|
|
0
|
if ($rclass =~ /^&sv_list/) { |
2027
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "SvREFCNT_inc_simple_NN(%s); /* methop_list[%d].op_rclass_sv */", |
2028
|
|
|
|
|
|
|
$rclass, $ix )); |
2029
|
|
|
|
|
|
|
# Put this simple PV into the PL_stashcache, it has no STASH, |
2030
|
|
|
|
|
|
|
# and initialize the method cache. |
2031
|
|
|
|
|
|
|
# TODO: backref magic for next, init the next::method cache |
2032
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "Perl_mro_method_changed_in(aTHX_ gv_stashsv(%s, GV_ADD));", |
2033
|
|
|
|
|
|
|
$rclass )); |
2034
|
|
|
|
|
|
|
} |
2035
|
0
|
0
|
|
|
|
0
|
my $first = $op->name eq 'method' ? $op->first->save : $op->meth_sv->save; |
2036
|
0
|
0
|
|
|
|
0
|
if ($first =~ /^&sv_list/) { |
2037
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "SvREFCNT_inc_simple_NN(%s); /* methop_list[%d].op_meth_sv */", |
2038
|
|
|
|
|
|
|
$first, $ix )); |
2039
|
|
|
|
|
|
|
} |
2040
|
0
|
0
|
0
|
|
|
0
|
$first = 'NULL' if !$C99 and $first eq 'Nullsv'; |
2041
|
0
|
|
|
|
|
0
|
$methopsect->add(sprintf($s, $op->_save_common, $first, $rclass)); |
2042
|
0
|
0
|
|
|
|
0
|
$methopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
2043
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "methop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
2044
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
2045
|
0
|
|
|
|
|
0
|
$sym = savesym( $op, "(OP*)&methop_list[$ix]" ); |
2046
|
0
|
0
|
|
|
|
0
|
if ($op->name eq 'method') { |
2047
|
0
|
|
|
|
|
0
|
do_labels($op, $level+1, 'first', 'rclass'); |
2048
|
|
|
|
|
|
|
} else { |
2049
|
0
|
|
|
|
|
0
|
do_labels($op, $level+1, 'meth_sv', 'rclass'); |
2050
|
|
|
|
|
|
|
} |
2051
|
0
|
|
|
|
|
0
|
$sym; |
2052
|
|
|
|
|
|
|
} |
2053
|
|
|
|
|
|
|
|
2054
|
|
|
|
|
|
|
sub B::PVOP::save { |
2055
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
2056
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
2057
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
2058
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
2059
|
|
|
|
|
|
|
# op_pv must be dynamic |
2060
|
0
|
|
|
|
|
0
|
$pvopsect->comment("$opsect_common, pv"); |
2061
|
0
|
|
|
|
|
0
|
$pvopsect->add( sprintf( "%s, NULL", $op->_save_common ) ); |
2062
|
0
|
0
|
|
|
|
0
|
$pvopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
2063
|
0
|
|
|
|
|
0
|
my $ix = $pvopsect->index; |
2064
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "pvop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
2065
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
2066
|
0
|
|
|
|
|
0
|
my ($cstring,$cur,$utf8) = strlen_flags($op->pv); # utf8 in op_private as OPpPV_IS_UTF8 (0x80) |
2067
|
|
|
|
|
|
|
# do not use savepvn here #362 |
2068
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "pvop_list[%d].op_pv = savesharedpvn(%s, %u);", $ix, $cstring, $cur )); |
2069
|
0
|
|
|
|
|
0
|
savesym( $op, "(OP*)&pvop_list[$ix]" ); |
2070
|
|
|
|
|
|
|
} |
2071
|
|
|
|
|
|
|
|
2072
|
|
|
|
|
|
|
# XXX Until we know exactly the package name for a method_call |
2073
|
|
|
|
|
|
|
# we improve the method search heuristics by maintaining this mru list. |
2074
|
|
|
|
|
|
|
sub push_package ($) { |
2075
|
0
|
0
|
|
0
|
0
|
0
|
my $p = shift or return; |
2076
|
0
|
|
|
|
|
0
|
warn "save package_pv \"$package_pv\" for method_name from @{[(caller(1))[3]]}\n" |
2077
|
0
|
0
|
0
|
|
|
0
|
if $debug{cv} or $debug{pkg} and !grep { $p eq $_ } @package_pv; |
|
0
|
|
0
|
|
|
0
|
|
2078
|
0
|
0
|
|
|
|
0
|
@package_pv = grep { $p ne $_ } @package_pv if @package_pv; # remove duplicates at the end |
|
0
|
|
|
|
|
0
|
|
2079
|
0
|
|
|
|
|
0
|
unshift @package_pv, $p; # prepend at the front |
2080
|
0
|
|
|
|
|
0
|
mark_package($p); |
2081
|
|
|
|
|
|
|
} |
2082
|
|
|
|
|
|
|
|
2083
|
|
|
|
|
|
|
# method_named is in 5.6.1 |
2084
|
|
|
|
|
|
|
sub method_named { |
2085
|
0
|
|
|
0
|
0
|
0
|
my $name = shift; |
2086
|
0
|
0
|
|
|
|
0
|
return unless $name; |
2087
|
0
|
|
|
|
|
0
|
my $cop = shift; |
2088
|
0
|
0
|
|
|
|
0
|
my $loc = $cop ? " at ".$cop->file." line ".$cop->line : ""; |
2089
|
|
|
|
|
|
|
# Note: the pkg PV is unacessible(?) at PL_stack_base+TOPMARK+1. |
2090
|
|
|
|
|
|
|
# But it is also at the const or padsv after the pushmark, before all args. |
2091
|
|
|
|
|
|
|
# See L |
2092
|
|
|
|
|
|
|
# We check it in op->_save_common |
2093
|
0
|
0
|
|
|
|
0
|
if (ref($name) eq 'B::CV') { |
2094
|
0
|
|
|
|
|
0
|
warn $name; |
2095
|
0
|
|
|
|
|
0
|
return $name; |
2096
|
|
|
|
|
|
|
} |
2097
|
0
|
|
|
|
|
0
|
my $method; |
2098
|
0
|
|
|
|
|
0
|
for ($package_pv, @package_pv, 'main') { |
2099
|
55
|
|
|
55
|
|
302
|
no strict 'refs'; |
|
55
|
|
|
|
|
75
|
|
|
55
|
|
|
|
|
657008
|
|
2100
|
0
|
0
|
|
|
|
0
|
next unless defined $_; |
2101
|
0
|
|
|
|
|
0
|
$method = $_ . '::' . $name; |
2102
|
0
|
0
|
|
|
|
0
|
if (defined(&$method)) { |
2103
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Found &%s::%s\n", $_, $name ) if $debug{cv}; |
2104
|
0
|
|
|
|
|
0
|
$include_package{$_} = 1; # issue59 |
2105
|
0
|
|
|
|
|
0
|
mark_package($_, 1); |
2106
|
0
|
|
|
|
|
0
|
last; |
2107
|
|
|
|
|
|
|
} else { |
2108
|
0
|
0
|
|
|
|
0
|
if (my $parent = try_isa($_,$name)) { |
2109
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Found &%s::%s\n", $parent, $name ) if $debug{cv}; |
2110
|
0
|
|
|
|
|
0
|
$method = $parent . '::' . $name; |
2111
|
0
|
|
|
|
|
0
|
$include_package{$parent} = 1; |
2112
|
0
|
|
|
|
|
0
|
last; |
2113
|
|
|
|
|
|
|
} |
2114
|
0
|
0
|
|
|
|
0
|
warn "no definition for method_name \"$method\"\n" if $debug{cv}; |
2115
|
|
|
|
|
|
|
} |
2116
|
|
|
|
|
|
|
} |
2117
|
|
|
|
|
|
|
#my $b = $Config{archname}."/B\.pm"; |
2118
|
|
|
|
|
|
|
#if ($name !~ /^tid|can|isa|pmreplroot$/ and $loc !~ m/$b line / and $package_pv !~ /^B::/) { |
2119
|
|
|
|
|
|
|
# return undef if $ITHREADS; |
2120
|
|
|
|
|
|
|
#} |
2121
|
0
|
0
|
|
|
|
0
|
$method = $name unless $method; |
2122
|
0
|
0
|
|
|
|
0
|
if (exists &$method) { # Do not try to save non-existing methods |
2123
|
0
|
0
|
|
|
|
0
|
warn "save method_name \"$method\"$loc\n" if $debug{cv}; |
2124
|
0
|
|
|
|
|
0
|
return svref_2object( \&{$method} ); |
|
0
|
|
|
|
|
0
|
|
2125
|
|
|
|
|
|
|
} else { |
2126
|
0
|
|
|
|
|
0
|
return 0; |
2127
|
|
|
|
|
|
|
} |
2128
|
|
|
|
|
|
|
} |
2129
|
|
|
|
|
|
|
|
2130
|
|
|
|
|
|
|
|
2131
|
|
|
|
|
|
|
# scalar: pv. list: (stash,pv,sv) |
2132
|
|
|
|
|
|
|
# pads are not named, but may be typed |
2133
|
|
|
|
|
|
|
sub padop_name { |
2134
|
0
|
|
|
0
|
0
|
0
|
my $op = shift; |
2135
|
0
|
|
|
|
|
0
|
my $cv = shift; |
2136
|
0
|
0
|
0
|
|
|
0
|
if ($op->can('name') |
|
|
|
0
|
|
|
|
|
2137
|
|
|
|
|
|
|
and ($op->name eq 'padsv' or $op->name eq 'method_named' |
2138
|
|
|
|
|
|
|
or ref($op) eq 'B::SVOP')) #threaded |
2139
|
|
|
|
|
|
|
{ |
2140
|
0
|
0
|
0
|
|
|
0
|
return () if $cv and ref($cv->PADLIST) eq 'B::SPECIAL'; |
2141
|
0
|
0
|
0
|
|
|
0
|
my @c = ($cv and ref($cv) eq 'B::CV' and ref($cv->PADLIST) ne 'B::NULL') |
2142
|
|
|
|
|
|
|
? $cv->PADLIST->ARRAY : comppadlist->ARRAY; |
2143
|
0
|
|
|
|
|
0
|
my @types = $c[0]->ARRAY; |
2144
|
0
|
|
|
|
|
0
|
my @pad = $c[1]->ARRAY; |
2145
|
0
|
0
|
|
|
|
0
|
my $ix = $op->can('padix') ? $op->padix : $op->targ; |
2146
|
0
|
|
|
|
|
0
|
my $sv = $pad[$ix]; |
2147
|
0
|
|
|
|
|
0
|
my $t = $types[$ix]; |
2148
|
0
|
0
|
0
|
|
|
0
|
if (defined($t) and ref($t) ne 'B::SPECIAL') { |
|
|
0
|
|
|
|
|
|
2149
|
0
|
0
|
|
|
|
0
|
my $pv = $sv->can("PV") ? $sv->PV : ($t->can('PVX') ? $t->PVX : ''); |
|
|
0
|
|
|
|
|
|
2150
|
|
|
|
|
|
|
# need to fix B for SVpad_TYPEDI without formal STASH |
2151
|
0
|
0
|
0
|
|
|
0
|
my $stash = (ref($t) eq 'B::PVMG' and ref($t->SvSTASH) ne 'B::SPECIAL') ? $t->SvSTASH->NAME : ''; |
2152
|
0
|
0
|
|
|
|
0
|
return wantarray ? ($stash,$pv,$sv) : $pv; |
2153
|
|
|
|
|
|
|
} elsif ($sv) { |
2154
|
0
|
0
|
|
|
|
0
|
my $pv = $sv->PV if $sv->can("PV"); |
2155
|
0
|
0
|
|
|
|
0
|
my $stash = $sv->STASH->NAME if $sv->can("STASH"); |
2156
|
0
|
0
|
|
|
|
0
|
return wantarray ? ($stash,$pv,$sv) : $pv; |
2157
|
|
|
|
|
|
|
} |
2158
|
|
|
|
|
|
|
} |
2159
|
|
|
|
|
|
|
} |
2160
|
|
|
|
|
|
|
|
2161
|
|
|
|
|
|
|
sub svop_name { |
2162
|
0
|
|
|
0
|
0
|
0
|
my $op = shift; |
2163
|
0
|
|
|
|
|
0
|
my $cv = shift; |
2164
|
0
|
|
|
|
|
0
|
my $sv; |
2165
|
0
|
0
|
0
|
|
|
0
|
if ($op->can('name') and $op->name eq 'padsv') { |
2166
|
0
|
|
|
|
|
0
|
my @r = padop_name($op, $cv); |
2167
|
0
|
0
|
|
|
|
0
|
return wantarray ? @r : ($r[1] ? $r[1] : $r[0]); |
|
|
0
|
|
|
|
|
|
2168
|
|
|
|
|
|
|
} else { |
2169
|
0
|
0
|
|
|
|
0
|
if (!$op->can("sv")) { |
2170
|
0
|
0
|
0
|
|
|
0
|
if (ref($op) eq 'B::PMOP' and $op->pmreplroot->can("sv")) { |
2171
|
0
|
|
|
|
|
0
|
$sv = $op->pmreplroot->sv; |
2172
|
|
|
|
|
|
|
} else { |
2173
|
0
|
0
|
0
|
|
|
0
|
$sv = $op->first->sv unless $op->flags & 4 |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2174
|
|
|
|
|
|
|
or ($op->name eq 'const' and $op->flags & 34) or $op->first->can("sv"); |
2175
|
|
|
|
|
|
|
} |
2176
|
|
|
|
|
|
|
} else { |
2177
|
0
|
|
|
|
|
0
|
$sv = $op->sv; |
2178
|
|
|
|
|
|
|
} |
2179
|
0
|
0
|
0
|
|
|
0
|
if ($sv and $$sv) { |
2180
|
0
|
0
|
|
|
|
0
|
if ($sv->FLAGS & SVf_ROK) { |
2181
|
0
|
0
|
|
|
|
0
|
return '' if $sv->isa("B::NULL"); |
2182
|
0
|
|
|
|
|
0
|
my $rv = $sv->RV; |
2183
|
0
|
0
|
|
|
|
0
|
if ($rv->isa("B::PVGV")) { |
2184
|
0
|
|
|
|
|
0
|
my $o = $rv->IO; |
2185
|
0
|
0
|
|
|
|
0
|
return $o->STASH->NAME if $$o; |
2186
|
|
|
|
|
|
|
} |
2187
|
0
|
0
|
|
|
|
0
|
return '' if $rv->isa("B::PVMG"); |
2188
|
0
|
|
|
|
|
0
|
return $rv->STASH->NAME; |
2189
|
|
|
|
|
|
|
} else { |
2190
|
0
|
0
|
|
|
|
0
|
if ($op->name eq 'gvsv') { |
|
|
0
|
|
|
|
|
|
2191
|
0
|
0
|
|
|
|
0
|
return wantarray ? ($sv->STASH->NAME, $sv->NAME) : $sv->STASH->NAME.'::'.$sv->NAME; |
2192
|
|
|
|
|
|
|
} elsif ($op->name eq 'gv') { |
2193
|
0
|
0
|
|
|
|
0
|
return wantarray ? ($sv->STASH->NAME, $sv->NAME) : $sv->STASH->NAME.'::'.$sv->NAME; |
2194
|
|
|
|
|
|
|
} else { |
2195
|
0
|
0
|
|
|
|
0
|
return $sv->can('STASH') ? $sv->STASH->NAME |
|
|
0
|
|
|
|
|
|
2196
|
|
|
|
|
|
|
: $sv->can('NAME') ? $sv->NAME : $sv->PV; |
2197
|
|
|
|
|
|
|
} |
2198
|
|
|
|
|
|
|
} |
2199
|
|
|
|
|
|
|
} |
2200
|
|
|
|
|
|
|
} |
2201
|
|
|
|
|
|
|
} |
2202
|
|
|
|
|
|
|
|
2203
|
|
|
|
|
|
|
# return the next COP for file and line info |
2204
|
|
|
|
|
|
|
sub nextcop { |
2205
|
0
|
|
|
0
|
0
|
0
|
my $op = shift; |
2206
|
0
|
|
0
|
|
|
0
|
while ($op and ref($op) ne 'B::COP' and ref($op) ne 'B::NULL') { $op = $op->next; } |
|
0
|
|
0
|
|
|
0
|
|
2207
|
0
|
0
|
0
|
|
|
0
|
return ($op and ref($op) eq 'B::COP') ? $op : undef; |
2208
|
|
|
|
|
|
|
} |
2209
|
|
|
|
|
|
|
|
2210
|
|
|
|
|
|
|
sub svimmortal { |
2211
|
0
|
|
|
0
|
0
|
0
|
my $sym = shift; |
2212
|
0
|
0
|
|
|
|
0
|
if ($sym =~ /\(SV\*\)?\&PL_sv_(yes|no|undef|placeholder)/) { |
2213
|
0
|
|
|
|
|
0
|
return 1; |
2214
|
|
|
|
|
|
|
} |
2215
|
0
|
|
|
|
|
0
|
return undef; |
2216
|
|
|
|
|
|
|
} |
2217
|
|
|
|
|
|
|
|
2218
|
|
|
|
|
|
|
sub B::SVOP::save { |
2219
|
0
|
|
|
0
|
|
0
|
my ( $op, $level, $fullname ) = @_; |
2220
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
2221
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
2222
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
2223
|
0
|
|
|
|
|
0
|
my $svsym = 'Nullsv'; |
2224
|
|
|
|
|
|
|
# XXX moose1 crash with 5.8.5-nt, Cwd::_perl_abs_path also |
2225
|
0
|
0
|
0
|
|
|
0
|
if ($op->name eq 'aelemfast' and $op->flags & 128) { #OPf_SPECIAL |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2226
|
0
|
|
|
|
|
0
|
$svsym = '&PL_sv_undef'; # pad does not need to be saved |
2227
|
0
|
0
|
|
|
|
0
|
warn sprintf("SVOP->sv aelemfast pad %d\n", $op->flags) if $debug{sv}; |
2228
|
|
|
|
|
|
|
} elsif ($op->name eq 'gv' and $op->next and $op->next->name eq 'rv2cv' |
2229
|
|
|
|
|
|
|
and $op->next->next and $op->next->next->name eq 'defined' ) { |
2230
|
|
|
|
|
|
|
# 96 do not save a gvsv->cv if just checked for defined'ness |
2231
|
0
|
|
|
|
|
0
|
my $gv = $op->sv; |
2232
|
0
|
|
|
|
|
0
|
my $gvsv = svop_name($op); |
2233
|
0
|
0
|
|
|
|
0
|
if ($gvsv !~ /^DynaLoader::/) { |
2234
|
0
|
0
|
|
|
|
0
|
warn "skip saving defined(&$gvsv)\n" if $debug{gv}; # defer to run-time |
2235
|
0
|
|
|
|
|
0
|
$svsym = '(SV*)' . $gv->save( 8 ); # ~Save_CV in B::GV::save |
2236
|
|
|
|
|
|
|
} else { |
2237
|
0
|
|
|
|
|
0
|
$svsym = '(SV*)' . $gv->save(); |
2238
|
|
|
|
|
|
|
} |
2239
|
|
|
|
|
|
|
} else { |
2240
|
0
|
|
|
|
|
0
|
my $sv = $op->sv; |
2241
|
0
|
|
|
|
|
0
|
$svsym = $sv->save("svop ".$op->name); |
2242
|
0
|
0
|
|
|
|
0
|
if ($svsym =~ /^(gv_|PL_.*gv)/) { |
|
|
0
|
|
|
|
|
|
2243
|
0
|
|
|
|
|
0
|
$svsym = '(SV*)' . $svsym; |
2244
|
|
|
|
|
|
|
} elsif ($svsym =~ /^\([SAHC]V\*\)\&sv_list/) { |
2245
|
0
|
|
|
|
|
0
|
$svsym =~ s/^\([SAHC]V\*\)//; |
2246
|
|
|
|
|
|
|
} else { |
2247
|
0
|
|
|
|
|
0
|
$svsym =~ s/^\([GAPH]V\*\)/(SV*)/; |
2248
|
|
|
|
|
|
|
} |
2249
|
0
|
0
|
|
|
|
0
|
warn "Error: SVOP: ".$op->name." $sv $svsym" if $svsym =~ /^\(SV\*\)lexwarn/; #322 |
2250
|
|
|
|
|
|
|
} |
2251
|
0
|
0
|
|
|
|
0
|
if ($op->name eq 'method_named') { |
2252
|
0
|
|
|
|
|
0
|
my $cv = method_named(svop_or_padop_pv($op), nextcop($op)); |
2253
|
0
|
0
|
|
|
|
0
|
$cv->save if $cv; |
2254
|
|
|
|
|
|
|
} |
2255
|
0
|
|
|
|
|
0
|
my $is_const_addr = $svsym =~ m/Null|\&/; |
2256
|
0
|
0
|
0
|
|
|
0
|
if ($MULTI and svimmortal($svsym)) { # t/testm.sh Test::Pod |
2257
|
0
|
|
|
|
|
0
|
$is_const_addr = 0; |
2258
|
|
|
|
|
|
|
} |
2259
|
0
|
|
|
|
|
0
|
$svopsect->comment("$opsect_common, sv"); |
2260
|
0
|
0
|
|
|
|
0
|
$svopsect->add(sprintf( "%s, %s", |
2261
|
|
|
|
|
|
|
$op->_save_common, ( $is_const_addr ? $svsym : "Nullsv /* $svsym */" ) ) |
2262
|
|
|
|
|
|
|
); |
2263
|
0
|
0
|
|
|
|
0
|
$svopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
2264
|
0
|
|
|
|
|
0
|
my $ix = $svopsect->index; |
2265
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "svop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
2266
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
2267
|
0
|
0
|
|
|
|
0
|
$init->add("svop_list[$ix].op_sv = $svsym;") |
2268
|
|
|
|
|
|
|
unless $is_const_addr; |
2269
|
0
|
|
|
|
|
0
|
savesym( $op, "(OP*)&svop_list[$ix]" ); |
2270
|
|
|
|
|
|
|
} |
2271
|
|
|
|
|
|
|
|
2272
|
|
|
|
|
|
|
sub B::PADOP::save { |
2273
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
2274
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
2275
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
2276
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
2277
|
0
|
|
|
|
|
0
|
my $skip_defined; |
2278
|
0
|
0
|
0
|
|
|
0
|
if ($op->name eq 'method_named') { |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2279
|
0
|
|
|
|
|
0
|
my $cv = method_named(svop_or_padop_pv($op), nextcop($op)); |
2280
|
0
|
0
|
|
|
|
0
|
$cv->save if $cv; |
2281
|
|
|
|
|
|
|
} elsif ($op->name eq 'gv' and $op->next and $op->next->name eq 'rv2cv' |
2282
|
|
|
|
|
|
|
and $op->next->next and $op->next->next->name eq 'defined' ) { |
2283
|
|
|
|
|
|
|
# 96 do not save a gvsv->cv if just checked for defined'ness |
2284
|
0
|
|
|
|
|
0
|
$skip_defined++; |
2285
|
|
|
|
|
|
|
} |
2286
|
|
|
|
|
|
|
# This is saved by curpad syms at the end. But with __DATA__ handles it is better to save earlier |
2287
|
0
|
0
|
0
|
|
|
0
|
if ($op->name eq 'padsv' or $op->name eq 'gvsv' or $op->name eq 'gv') { |
|
|
|
0
|
|
|
|
|
2288
|
0
|
|
|
|
|
0
|
my @c = comppadlist->ARRAY; |
2289
|
0
|
|
|
|
|
0
|
my @pad = $c[1]->ARRAY; |
2290
|
0
|
0
|
|
|
|
0
|
my $ix = $op->can('padix') ? $op->padix : $op->targ; |
2291
|
0
|
|
|
|
|
0
|
my $sv = $pad[$ix]; |
2292
|
0
|
0
|
0
|
|
|
0
|
if ($sv and $$sv) { |
2293
|
0
|
|
|
|
|
0
|
my $name = padop_name($op, curcv); |
2294
|
0
|
0
|
0
|
|
|
0
|
if ($skip_defined and $name !~ /^DynaLoader::/) { |
2295
|
0
|
0
|
|
|
|
0
|
warn "skip saving defined(&$name)\n" if $debug{gv}; # defer to run-time |
2296
|
|
|
|
|
|
|
} else { |
2297
|
0
|
0
|
|
|
|
0
|
$sv->save("padop ". ($name ? $name : '')); |
2298
|
|
|
|
|
|
|
} |
2299
|
|
|
|
|
|
|
} |
2300
|
|
|
|
|
|
|
} |
2301
|
0
|
|
|
|
|
0
|
$padopsect->comment("$opsect_common, padix"); |
2302
|
0
|
|
|
|
|
0
|
$padopsect->add( sprintf( "%s, %d", $op->_save_common, $op->padix ) ); |
2303
|
0
|
0
|
|
|
|
0
|
$padopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
2304
|
0
|
|
|
|
|
0
|
my $ix = $padopsect->index; |
2305
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "padop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
2306
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
2307
|
0
|
|
|
|
|
0
|
savesym( $op, "(OP*)&padop_list[$ix]" ); |
2308
|
|
|
|
|
|
|
} |
2309
|
|
|
|
|
|
|
|
2310
|
|
|
|
|
|
|
sub B::COP::save { |
2311
|
0
|
|
|
0
|
|
0
|
my ( $op, $level ) = @_; |
2312
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
2313
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
2314
|
|
|
|
|
|
|
|
2315
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
2316
|
|
|
|
|
|
|
# we need to keep CvSTART cops, so check $level == 0 |
2317
|
|
|
|
|
|
|
# what a COP needs to do is to reset the stack, and restore locals |
2318
|
0
|
0
|
0
|
|
|
0
|
if ($optimize_cop and $level and !$op->label |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2319
|
|
|
|
|
|
|
and ref($prev_op) ne 'B::LISTOP') { # XXX very unsafe! |
2320
|
0
|
|
|
|
|
0
|
my $sym = savesym( $op, $op->next->save ); |
2321
|
|
|
|
|
|
|
warn sprintf( "Skip COP (0x%x) => %s (0x%x), line %d file %s\n", |
2322
|
0
|
0
|
|
|
|
0
|
$$op, $sym, $op->next, $op->line, $op->file ) if $debug{cops}; |
2323
|
0
|
|
|
|
|
0
|
return $sym; |
2324
|
|
|
|
|
|
|
} |
2325
|
|
|
|
|
|
|
|
2326
|
|
|
|
|
|
|
# TODO: if it is a nullified COP we must save it with all cop fields! |
2327
|
|
|
|
|
|
|
warn sprintf( "COP: line %d file %s\n", $op->line, $op->file ) |
2328
|
0
|
0
|
|
|
|
0
|
if $debug{cops}; |
2329
|
|
|
|
|
|
|
|
2330
|
|
|
|
|
|
|
# shameless cut'n'paste from B::Deparse |
2331
|
0
|
|
|
|
|
0
|
my ($warn_sv, $isint); |
2332
|
0
|
|
|
|
|
0
|
my $warnings = $op->warnings; |
2333
|
0
|
|
|
|
|
0
|
my $is_special = ref($warnings) eq 'B::SPECIAL'; |
2334
|
0
|
0
|
|
|
|
0
|
my $warnsvcast = $PERL510 ? "(STRLEN*)" : "(SV*)"; |
2335
|
0
|
0
|
0
|
|
|
0
|
if ( $is_special && $$warnings == 4 ) { # use warnings 'all'; |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2336
|
0
|
|
|
|
|
0
|
$warn_sv = 'pWARN_ALL'; |
2337
|
|
|
|
|
|
|
} |
2338
|
|
|
|
|
|
|
elsif ( $is_special && $$warnings == 5 ) { # no warnings 'all'; |
2339
|
0
|
|
|
|
|
0
|
$warn_sv = 'pWARN_NONE'; |
2340
|
|
|
|
|
|
|
} |
2341
|
|
|
|
|
|
|
elsif ($is_special) { # use warnings; |
2342
|
0
|
|
|
|
|
0
|
$warn_sv = 'pWARN_STD'; |
2343
|
|
|
|
|
|
|
} |
2344
|
|
|
|
|
|
|
else { |
2345
|
|
|
|
|
|
|
# LEXWARN_on: Original $warnings->save from 5.8.9 was wrong, |
2346
|
|
|
|
|
|
|
# DUP_WARNINGS copied length PVX bytes. |
2347
|
0
|
|
|
|
|
0
|
my $warn = bless $warnings, "B::LEXWARN"; |
2348
|
|
|
|
|
|
|
# TODO: isint here misses already seen lexwarn symbols |
2349
|
0
|
|
|
|
|
0
|
($warn_sv, $isint) = $warn->save; |
2350
|
0
|
|
|
|
|
0
|
my $ix = $copsect->index + 1; |
2351
|
|
|
|
|
|
|
# XXX No idea how a &sv_list[] came up here, a re-used object. Anyway. |
2352
|
0
|
0
|
|
|
|
0
|
$warn_sv = substr($warn_sv,1) if substr($warn_sv,0,3) eq '&sv'; |
2353
|
0
|
|
|
|
|
0
|
$warn_sv = $warnsvcast.'&'.$warn_sv; |
2354
|
0
|
0
|
0
|
|
|
0
|
$free->add( sprintf( " cop_list[%d].cop_warnings = NULL;", $ix ) ) |
2355
|
|
|
|
|
|
|
if !$B::C::optimize_warn_sv or !$PERL510; |
2356
|
|
|
|
|
|
|
#push @B::C::static_free, sprintf("cop_list[%d]", $ix); |
2357
|
|
|
|
|
|
|
} |
2358
|
|
|
|
|
|
|
|
2359
|
0
|
0
|
0
|
|
|
0
|
my $dynamic_copwarn = ($PERL510 and !$is_special) ? 1 : !$B::C::optimize_warn_sv; |
2360
|
|
|
|
|
|
|
# branch feature/gh70-static-lexwarn with PERL_SUPPORT_STATIC_COP |
2361
|
0
|
0
|
0
|
|
|
0
|
$dynamic_copwarn = 0 if $Config{usecperl} and $] >= 5.022002; |
2362
|
|
|
|
|
|
|
|
2363
|
|
|
|
|
|
|
# Trim the .pl extension, to print the executable name only. |
2364
|
0
|
|
|
|
|
0
|
my $file = $op->file; |
2365
|
|
|
|
|
|
|
# $file =~ s/\.pl$/.c/; |
2366
|
0
|
|
|
|
|
0
|
my $add_label = 0; |
2367
|
0
|
0
|
|
|
|
0
|
if ($PERL512) { |
|
|
0
|
|
|
|
|
|
2368
|
0
|
0
|
0
|
|
|
0
|
if ($ITHREADS and $] >= 5.017) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2369
|
0
|
|
|
|
|
0
|
$copsect->comment( |
2370
|
|
|
|
|
|
|
"$opsect_common, line, stashoff, file, hints, seq, warnings, hints_hash"); |
2371
|
0
|
0
|
|
|
|
0
|
$copsect->add( |
2372
|
|
|
|
|
|
|
sprintf( "%s, %u, " . "%d, %s, %u, " . "%s, %s, NULL", |
2373
|
|
|
|
|
|
|
$op->_save_common, $op->line, |
2374
|
|
|
|
|
|
|
$op->stashoff, "NULL", #hints=0 |
2375
|
|
|
|
|
|
|
$op->hints, |
2376
|
|
|
|
|
|
|
ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL' |
2377
|
|
|
|
|
|
|
)); |
2378
|
|
|
|
|
|
|
} elsif ($ITHREADS and $] >= 5.016) { |
2379
|
|
|
|
|
|
|
# [perl #113034] [PATCH] 2d8d7b1 replace B::COP::stashflags by B::COP::stashlen (5.16.0 only) |
2380
|
0
|
|
|
|
|
0
|
$copsect->comment( |
2381
|
|
|
|
|
|
|
"$opsect_common, line, stashpv, file, stashlen, hints, seq, warnings, hints_hash"); |
2382
|
0
|
0
|
|
|
|
0
|
$copsect->add( |
|
|
0
|
|
|
|
|
|
2383
|
|
|
|
|
|
|
sprintf( "%s, %u, " . "%s, %s, %d, %u, " . "%s, %s, NULL", |
2384
|
|
|
|
|
|
|
$op->_save_common, $op->line, |
2385
|
|
|
|
|
|
|
"NULL", "NULL", |
2386
|
|
|
|
|
|
|
# XXX at broken 5.16.0 with B-1.34 we do non-utf8, non-null only (=> negative len), |
2387
|
|
|
|
|
|
|
# 5.16.0 B-1.35 has stashlen, 5.16.1 we will see. |
2388
|
|
|
|
|
|
|
$op->can('stashlen') ? $op->stashlen : length($op->stashpv), |
2389
|
|
|
|
|
|
|
$op->hints, |
2390
|
|
|
|
|
|
|
ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL' |
2391
|
|
|
|
|
|
|
)); |
2392
|
|
|
|
|
|
|
} elsif ($ITHREADS and $] >= 5.015004 and $] < 5.016) { |
2393
|
0
|
|
|
|
|
0
|
$copsect->comment( |
2394
|
|
|
|
|
|
|
"$opsect_common, line, stashpv, file, stashflags, hints, seq, warnings, hints_hash"); |
2395
|
0
|
0
|
|
|
|
0
|
$copsect->add( |
2396
|
|
|
|
|
|
|
sprintf( "%s, %u, " . "%s, %s, %d, %u, " . "%s, %s, NULL", |
2397
|
|
|
|
|
|
|
$op->_save_common, $op->line, |
2398
|
|
|
|
|
|
|
"NULL", "NULL", |
2399
|
|
|
|
|
|
|
$op->stashflags, $op->hints, |
2400
|
|
|
|
|
|
|
ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL' |
2401
|
|
|
|
|
|
|
)); |
2402
|
|
|
|
|
|
|
} else { |
2403
|
|
|
|
|
|
|
# cop_label now in hints_hash (Change #33656) |
2404
|
0
|
|
|
|
|
0
|
$copsect->comment( |
2405
|
|
|
|
|
|
|
"$opsect_common, line, stash, file, hints, seq, warn_sv, hints_hash"); |
2406
|
0
|
0
|
|
|
|
0
|
$copsect->add( |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2407
|
|
|
|
|
|
|
sprintf( "%s, %u, " . "%s, %s, %u, " . "%s, %s, NULL", |
2408
|
|
|
|
|
|
|
$op->_save_common, $op->line, |
2409
|
|
|
|
|
|
|
$ITHREADS ? "NULL" : "Nullhv",# we cannot store this static (attribute exit) |
2410
|
|
|
|
|
|
|
$ITHREADS ? "NULL" : "Nullgv", |
2411
|
|
|
|
|
|
|
$op->hints, ivx($op->cop_seq), !$dynamic_copwarn ? $warn_sv : 'NULL' |
2412
|
|
|
|
|
|
|
)); |
2413
|
|
|
|
|
|
|
} |
2414
|
0
|
0
|
|
|
|
0
|
if ( $op->label ) { |
2415
|
0
|
|
|
|
|
0
|
$add_label = 1; |
2416
|
|
|
|
|
|
|
} |
2417
|
|
|
|
|
|
|
} |
2418
|
|
|
|
|
|
|
elsif ($PERL510) { |
2419
|
0
|
|
|
|
|
0
|
$copsect->comment("$opsect_common, line, label, stash, file, hints, seq, warnings, hints_hash"); |
2420
|
0
|
0
|
|
|
|
0
|
$copsect->add(sprintf("%s, %u, %s, " . "%s, %s, %u, " . "%u, %s, NULL", |
2421
|
|
|
|
|
|
|
$op->_save_common, $op->line, 'NULL', |
2422
|
|
|
|
|
|
|
"NULL", "NULL", |
2423
|
|
|
|
|
|
|
$op->hints, $op->cop_seq, !$dynamic_copwarn ? $warn_sv : 'NULL' |
2424
|
|
|
|
|
|
|
)); |
2425
|
0
|
0
|
|
|
|
0
|
if ($op->label) { |
2426
|
0
|
|
|
|
|
0
|
$init->add(sprintf( "CopLABEL_set(&cop_list[%d], CopLABEL_alloc(%s));", |
2427
|
|
|
|
|
|
|
$copsect->index, cstring( $op->label ) )); |
2428
|
|
|
|
|
|
|
} |
2429
|
|
|
|
|
|
|
} |
2430
|
|
|
|
|
|
|
else { |
2431
|
|
|
|
|
|
|
# 5.8 misses cop_io |
2432
|
0
|
|
|
|
|
0
|
$copsect->comment("$opsect_common, label, stash, file, seq, arybase, line, warn_sv, io"); |
2433
|
0
|
0
|
|
|
|
0
|
$copsect->add( |
|
|
0
|
|
|
|
|
|
2434
|
|
|
|
|
|
|
sprintf( "%s, %s, %s, %s, %s, %d, %u, %s %s", |
2435
|
|
|
|
|
|
|
$op->_save_common, cstring( $op->label ), |
2436
|
|
|
|
|
|
|
"NULL", "NULL", |
2437
|
|
|
|
|
|
|
ivx($op->cop_seq), $op->arybase, |
2438
|
|
|
|
|
|
|
$op->line, !$dynamic_copwarn ? $warn_sv : 'NULL', |
2439
|
|
|
|
|
|
|
( $PERL56 ? "" : ", 0" ) |
2440
|
|
|
|
|
|
|
)); |
2441
|
|
|
|
|
|
|
} |
2442
|
0
|
0
|
|
|
|
0
|
$copsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
2443
|
0
|
|
|
|
|
0
|
my $ix = $copsect->index; |
2444
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "cop_list[%d].op_ppaddr = %s;", $ix, $op->ppaddr ) ) |
2445
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
2446
|
|
|
|
|
|
|
|
2447
|
0
|
|
|
|
|
0
|
my $i = 0; |
2448
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and $op->hints_hash) { |
2449
|
0
|
|
|
|
|
0
|
my $hints = $op->hints_hash; |
2450
|
0
|
0
|
|
|
|
0
|
if ($$hints) { |
2451
|
0
|
0
|
|
|
|
0
|
if (exists $cophhtable{$$hints}) { |
2452
|
0
|
|
|
|
|
0
|
my $cophh = $cophhtable{$$hints}; |
2453
|
0
|
|
|
|
|
0
|
$init->add(sprintf("CopHINTHASH_set(&cop_list[%d], %s);", $ix, $cophh)); |
2454
|
|
|
|
|
|
|
} else { |
2455
|
0
|
0
|
|
|
|
0
|
my $hint_hv = $hints->HASH if ref $hints eq 'B::RHE'; |
2456
|
0
|
|
|
|
|
0
|
my $cophh = sprintf( "cophh%d", scalar keys %cophhtable ); |
2457
|
0
|
|
|
|
|
0
|
$cophhtable{$$hints} = $cophh; |
2458
|
0
|
|
|
|
|
0
|
$decl->add(sprintf("Static COPHH *%s;", $cophh)); |
2459
|
0
|
|
|
|
|
0
|
for my $k (keys %$hint_hv) { |
2460
|
0
|
|
|
|
|
0
|
my ($ck, $kl, $utf8) = strlen_flags($k); |
2461
|
0
|
|
|
|
|
0
|
my $v = $hint_hv->{$k}; |
2462
|
0
|
0
|
|
|
|
0
|
next if $k eq ':'; #skip label, see below |
2463
|
0
|
|
|
|
|
0
|
my $val = B::svref_2object( \$v )->save("\$^H{$k}"); |
2464
|
0
|
0
|
|
|
|
0
|
if ($utf8) { |
2465
|
0
|
0
|
|
|
|
0
|
$init->add(sprintf("%s = cophh_store_pvn(%s, %s, %d, 0, %s, COPHH_KEY_UTF8);", |
2466
|
|
|
|
|
|
|
$cophh, $i ? $cophh : 'NULL', $ck, $kl, $val)); |
2467
|
|
|
|
|
|
|
} else { |
2468
|
0
|
0
|
|
|
|
0
|
$init->add(sprintf("%s = cophh_store_pvs(%s, %s, %s, 0);", |
2469
|
|
|
|
|
|
|
$cophh, $i ? $cophh : 'NULL', $ck, $val)); |
2470
|
|
|
|
|
|
|
} |
2471
|
|
|
|
|
|
|
#$init->add(sprintf("%s->refcounted_he_refcnt--;", $cophh)); |
2472
|
|
|
|
|
|
|
#if (!$ITHREADS) { |
2473
|
|
|
|
|
|
|
# $init->add(sprintf("HEK_FLAGS(%s->refcounted_he_hek) |= HVhek_STATIC;", $cophh)); |
2474
|
|
|
|
|
|
|
#} |
2475
|
|
|
|
|
|
|
#if ($PERL522 and !$ITHREADS) { # breaks issue220 |
2476
|
|
|
|
|
|
|
# $init->add(sprintf("unshare_hek_hek(%s->refcounted_he_hek);", $cophh)); |
2477
|
|
|
|
|
|
|
#} |
2478
|
0
|
|
|
|
|
0
|
$i++; |
2479
|
|
|
|
|
|
|
} |
2480
|
0
|
|
|
|
|
0
|
$init->add(sprintf("CopHINTHASH_set(&cop_list[%d], %s);", $ix, $cophh)); |
2481
|
|
|
|
|
|
|
} |
2482
|
|
|
|
|
|
|
} |
2483
|
|
|
|
|
|
|
} |
2484
|
0
|
0
|
|
|
|
0
|
if ($add_label) { |
2485
|
|
|
|
|
|
|
# test 29 and 15,16,21. 44,45 |
2486
|
0
|
|
|
|
|
0
|
my ($cstring, $cur, $utf8) = strlen_flags($op->label); |
2487
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.015001) { # officially added with 5.15.1 aebc0cbee |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2488
|
0
|
0
|
0
|
|
|
0
|
warn "utf8 label $cstring" if $utf8 and $verbose; |
2489
|
0
|
|
|
|
|
0
|
$init->add(sprintf("Perl_cop_store_label(aTHX_ &cop_list[%d], %s, %u, %s);", |
2490
|
|
|
|
|
|
|
$copsect->index, $cstring, $cur, $utf8)); |
2491
|
|
|
|
|
|
|
} elsif ($] > 5.013004) { |
2492
|
0
|
|
|
|
|
0
|
$init->add(sprintf("Perl_store_cop_label(aTHX_ &cop_list[%d], %s, %u, %s);", |
2493
|
|
|
|
|
|
|
$copsect->index, $cstring, $cur, $utf8)); |
2494
|
|
|
|
|
|
|
} elsif (!($^O =~ /^(MSWin32|AIX)$/ or $ENV{PERL_DL_NONLAZY})) { |
2495
|
0
|
0
|
|
|
|
0
|
warn "Warning: Overwrote hints_hash with label\n" if $i; |
2496
|
0
|
|
|
|
|
0
|
my $ix = $copsect->index; |
2497
|
0
|
|
|
|
|
0
|
$init->add( |
2498
|
|
|
|
|
|
|
sprintf("cop_list[%d].cop_hints_hash = Perl_store_cop_label(aTHX_ cop_list[%d].cop_hints_hash, %s);", |
2499
|
|
|
|
|
|
|
$ix, $ix, $cstring)); |
2500
|
|
|
|
|
|
|
} |
2501
|
|
|
|
|
|
|
} |
2502
|
|
|
|
|
|
|
|
2503
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and !$is_special and !$isint) { |
|
|
|
0
|
|
|
|
|
2504
|
0
|
|
|
|
|
0
|
my $copw = $warn_sv; |
2505
|
0
|
|
|
|
|
0
|
$copw =~ s/^\(STRLEN\*\)&//; |
2506
|
|
|
|
|
|
|
# on cv_undef (scope exit, die, Attribute::Handlers, ...) CvROOT and kids are freed. |
2507
|
|
|
|
|
|
|
# so lexical cop_warnings need to be dynamic. |
2508
|
0
|
0
|
|
|
|
0
|
if ($copw) { |
2509
|
0
|
|
|
|
|
0
|
my $dest = "cop_list[$ix].cop_warnings"; |
2510
|
|
|
|
|
|
|
# with DEBUGGING savepvn returns ptr + PERL_MEMORY_DEBUG_HEADER_SIZE |
2511
|
|
|
|
|
|
|
# which is not the address which will be freed in S_cop_free. |
2512
|
|
|
|
|
|
|
# Need to use old-style PerlMemShared_, see S_cop_free in op.c (#362) |
2513
|
|
|
|
|
|
|
# lexwarn might be also be STRLEN* 0 |
2514
|
0
|
|
|
|
|
0
|
$init->no_split; |
2515
|
0
|
|
|
|
|
0
|
$init->add("#ifdef PERL_SUPPORT_STATIC_COP /* so far cperl only */", |
2516
|
|
|
|
|
|
|
"$dest = $warn_sv;", |
2517
|
|
|
|
|
|
|
"#else", |
2518
|
|
|
|
|
|
|
sprintf("%s = (STRLEN*)savesharedpvn((const char*)%s, sizeof(%s));", |
2519
|
|
|
|
|
|
|
$dest, $copw, $copw), |
2520
|
|
|
|
|
|
|
"#endif"); |
2521
|
0
|
|
|
|
|
0
|
$init->split; |
2522
|
|
|
|
|
|
|
} |
2523
|
|
|
|
|
|
|
} else { |
2524
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "cop_list[%d].cop_warnings = %s;", $ix, $warn_sv ) ) |
2525
|
|
|
|
|
|
|
unless $B::C::optimize_warn_sv; |
2526
|
|
|
|
|
|
|
} |
2527
|
|
|
|
|
|
|
#push @B::C::static_free, "cop_list[$ix]" if $ITHREADS; |
2528
|
0
|
0
|
|
|
|
0
|
if (!$B::C::optimize_cop) { |
2529
|
0
|
|
|
|
|
0
|
my $stash = savestashpv($op->stashpv); |
2530
|
0
|
|
|
|
|
0
|
$init->add(sprintf( "CopSTASH_set(&cop_list[%d], %s);", $ix, $stash )); |
2531
|
0
|
0
|
|
|
|
0
|
if (!$ITHREADS) { |
2532
|
0
|
0
|
|
|
|
0
|
if ($B::C::const_strings) { |
2533
|
0
|
|
|
|
|
0
|
my $constpv = constpv($file); |
2534
|
|
|
|
|
|
|
# define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv)) |
2535
|
|
|
|
|
|
|
# cache gv_fetchfile |
2536
|
0
|
0
|
|
|
|
0
|
if ( !$copgvtable{$constpv} ) { |
2537
|
0
|
|
|
|
|
0
|
$copgvtable{$constpv} = $gv_index++; |
2538
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "gv_list[%d] = gv_fetchfile(%s);", $copgvtable{$constpv}, $constpv ) ); |
2539
|
|
|
|
|
|
|
} |
2540
|
|
|
|
|
|
|
$init->add( sprintf( "CopFILEGV_set(&cop_list[%d], gv_list[%d]); /* %s */", |
2541
|
0
|
|
|
|
|
0
|
$ix, $copgvtable{$constpv}, cstring($file) ) ); |
2542
|
|
|
|
|
|
|
#$init->add(sprintf( "CopFILE_set(&cop_list[%d], %s);", $ix, constpv($file) )); |
2543
|
|
|
|
|
|
|
} else { |
2544
|
0
|
|
|
|
|
0
|
$init->add(sprintf( "CopFILE_set(&cop_list[%d], %s);", $ix, cstring($file) )); |
2545
|
|
|
|
|
|
|
} |
2546
|
|
|
|
|
|
|
} else { # cv_undef e.g. in bproto.t and many more core tests with threads |
2547
|
0
|
|
|
|
|
0
|
$init->add(sprintf( "CopFILE_set(&cop_list[%d], %s);", $ix, cstring($file) )); |
2548
|
|
|
|
|
|
|
} |
2549
|
|
|
|
|
|
|
} |
2550
|
|
|
|
|
|
|
|
2551
|
|
|
|
|
|
|
# our root: store all packages from this file |
2552
|
0
|
0
|
|
|
|
0
|
if (!$mainfile) { |
2553
|
0
|
0
|
|
|
|
0
|
$mainfile = $op->file if $op->stashpv eq 'main'; |
2554
|
|
|
|
|
|
|
} else { |
2555
|
0
|
0
|
0
|
|
|
0
|
mark_package($op->stashpv) if $mainfile eq $op->file and $op->stashpv ne 'main'; |
2556
|
|
|
|
|
|
|
} |
2557
|
0
|
|
|
|
|
0
|
savesym( $op, "(OP*)&cop_list[$ix]" ); |
2558
|
|
|
|
|
|
|
} |
2559
|
|
|
|
|
|
|
|
2560
|
|
|
|
|
|
|
# if REGCOMP can be called in init or deferred in init1 |
2561
|
|
|
|
|
|
|
sub re_does_swash { |
2562
|
0
|
|
|
0
|
0
|
0
|
my ($qstr, $pmflags) = @_; |
2563
|
|
|
|
|
|
|
# SWASHNEW, now needing a multideref GV. 0x5000000 is just a hack. can be more |
2564
|
0
|
0
|
0
|
|
|
0
|
if (($] >= 5.021006 and ($pmflags & 0x5000000 == 0x5000000)) |
|
|
|
0
|
|
|
|
|
2565
|
|
|
|
|
|
|
# or any unicode property (#253). Note: \p{} breaks #242 |
2566
|
|
|
|
|
|
|
or ($qstr =~ /\\P\{/) |
2567
|
|
|
|
|
|
|
) |
2568
|
|
|
|
|
|
|
{ |
2569
|
0
|
|
|
|
|
0
|
return 1; |
2570
|
|
|
|
|
|
|
} else { |
2571
|
0
|
|
|
|
|
0
|
return 0; |
2572
|
|
|
|
|
|
|
} |
2573
|
|
|
|
|
|
|
} |
2574
|
|
|
|
|
|
|
|
2575
|
|
|
|
|
|
|
sub B::PMOP::save { |
2576
|
0
|
|
|
0
|
|
0
|
my ( $op, $level, $fullname ) = @_; |
2577
|
0
|
|
|
|
|
0
|
my ($replrootfield, $replstartfield, $gvsym) = ('NULL', 'NULL'); |
2578
|
0
|
|
|
|
|
0
|
my $sym = objsym($op); |
2579
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
2580
|
|
|
|
|
|
|
# 5.8.5-thr crashes here (7) at pushre |
2581
|
0
|
0
|
0
|
|
|
0
|
if ($] < 5.008008 and $ITHREADS and $$op < 256) { # B bug. split->first->pmreplroot = 0x1 |
|
|
|
0
|
|
|
|
|
2582
|
0
|
|
|
|
|
0
|
die "Internal B::walkoptree error: invalid PMOP for pushre\n"; |
2583
|
0
|
|
|
|
|
0
|
return; |
2584
|
|
|
|
|
|
|
} |
2585
|
0
|
0
|
|
|
|
0
|
$level = 0 unless $level; |
2586
|
0
|
|
|
|
|
0
|
my $replroot = $op->pmreplroot; |
2587
|
0
|
|
|
|
|
0
|
my $replstart = $op->pmreplstart; |
2588
|
0
|
|
|
|
|
0
|
my $ppaddr = $op->ppaddr; |
2589
|
|
|
|
|
|
|
|
2590
|
|
|
|
|
|
|
# under ithreads, OP_PUSHRE.op_replroot is an integer. multi not. |
2591
|
0
|
0
|
|
|
|
0
|
$replrootfield = sprintf( "s\\_%x", $$replroot ) if ref $replroot; |
2592
|
0
|
0
|
0
|
|
|
0
|
if ( $ITHREADS && $op->name eq "pushre" ) { |
|
|
0
|
|
|
|
|
|
2593
|
0
|
0
|
|
|
|
0
|
warn "PMOP::save saving a pp_pushre as int ${replroot}\n" if $debug{gv}; |
2594
|
0
|
|
|
|
|
0
|
$replrootfield = "INT2PTR(OP*,${replroot})"; |
2595
|
|
|
|
|
|
|
} |
2596
|
|
|
|
|
|
|
elsif ($$replroot) { |
2597
|
|
|
|
|
|
|
# OP_PUSHRE (a mutated version of OP_MATCH for the regexp |
2598
|
|
|
|
|
|
|
# argument to a split) stores a GV in op_pmreplroot instead |
2599
|
|
|
|
|
|
|
# of a substitution syntax tree. We don't want to walk that... |
2600
|
0
|
0
|
|
|
|
0
|
if ( $op->name eq "pushre" ) { |
2601
|
0
|
0
|
|
|
|
0
|
warn "PMOP::save saving a pp_pushre with GV $gvsym\n" if $debug{gv}; |
2602
|
0
|
|
|
|
|
0
|
$gvsym = $replroot->save; |
2603
|
0
|
|
|
|
|
0
|
$replrootfield = "NULL"; |
2604
|
0
|
0
|
|
|
|
0
|
$replstartfield = $replstart->save if $replstart; |
2605
|
|
|
|
|
|
|
} |
2606
|
|
|
|
|
|
|
else { |
2607
|
0
|
0
|
|
|
|
0
|
$replstart->save if $replstart; |
2608
|
0
|
|
|
|
|
0
|
$replstartfield = saveoptree( "*ignore*", $replroot, $replstart ); |
2609
|
0
|
|
|
|
|
0
|
$replstartfield =~ s/^hv/(OP*)hv/; |
2610
|
|
|
|
|
|
|
} |
2611
|
|
|
|
|
|
|
} |
2612
|
|
|
|
|
|
|
|
2613
|
|
|
|
|
|
|
# pmnext handling is broken in perl itself, we think. Bad op_pmnext |
2614
|
|
|
|
|
|
|
# fields aren't noticed in perl's runtime (unless you try reset) but we |
2615
|
|
|
|
|
|
|
# segfault when trying to dereference it to find op->op_pmnext->op_type |
2616
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
|
|
0
|
|
|
|
|
|
2617
|
0
|
|
|
|
|
0
|
$pmopsect->comment( |
2618
|
|
|
|
|
|
|
"$opsect_common, first, last, pmoffset, pmflags, pmreplroot, pmreplstart" |
2619
|
|
|
|
|
|
|
); |
2620
|
|
|
|
|
|
|
$pmopsect->add( |
2621
|
|
|
|
|
|
|
sprintf( "%s, s\\_%x, s\\_%x, %u, 0x%x, {%s}, {%s}", |
2622
|
0
|
|
|
|
|
0
|
$op->_save_common, ${ $op->first }, |
2623
|
0
|
0
|
|
|
|
0
|
${ $op->last }, ( $ITHREADS ? $op->pmoffset : 0 ), |
|
0
|
|
|
|
|
0
|
|
2624
|
|
|
|
|
|
|
$op->pmflags, $replrootfield, $replstartfield |
2625
|
|
|
|
|
|
|
)); |
2626
|
0
|
0
|
|
|
|
0
|
if ($] >= 5.017) { |
2627
|
0
|
|
|
|
|
0
|
my $code_list = $op->code_list; |
2628
|
0
|
0
|
0
|
|
|
0
|
if ($code_list and $$code_list) { |
2629
|
|
|
|
|
|
|
warn sprintf("saving pmop_list[%d] code_list $code_list (?{})\n", $pmopsect->index) |
2630
|
0
|
0
|
|
|
|
0
|
if $debug{gv}; |
2631
|
0
|
|
|
|
|
0
|
my $code_op = $code_list->save; |
2632
|
0
|
0
|
|
|
|
0
|
$init->add(sprintf("pmop_list[%d].op_code_list = %s;", # (?{}) code blocks |
2633
|
|
|
|
|
|
|
$pmopsect->index, $code_op)) if $code_op; |
2634
|
|
|
|
|
|
|
warn sprintf("done saving pmop_list[%d] code_list $code_list (?{})\n", $pmopsect->index) |
2635
|
0
|
0
|
|
|
|
0
|
if $debug{gv}; |
2636
|
|
|
|
|
|
|
} |
2637
|
|
|
|
|
|
|
} |
2638
|
|
|
|
|
|
|
} |
2639
|
|
|
|
|
|
|
elsif ($PERL56) { |
2640
|
|
|
|
|
|
|
# pmdynflags does not exist as B method. It is only used for PMdf_UTF8 dynamically, |
2641
|
|
|
|
|
|
|
# if static we set this already in pmflags. |
2642
|
0
|
|
|
|
|
0
|
$pmopsect->comment( |
2643
|
|
|
|
|
|
|
"$opsect_common, first, last, pmreplroot, pmreplstart, pmnext, pmregexp, pmflags, pmpermflags, pmdynflags" |
2644
|
|
|
|
|
|
|
); |
2645
|
|
|
|
|
|
|
$pmopsect->add( |
2646
|
|
|
|
|
|
|
sprintf( "%s, s\\_%x, s\\_%x, %s, %s, 0, 0, 0x%x, 0x%x", |
2647
|
|
|
|
|
|
|
$op->_save_common, |
2648
|
0
|
|
|
|
|
0
|
${ $op->first }, ${ $op->last }, |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
2649
|
|
|
|
|
|
|
$replrootfield, $replstartfield, |
2650
|
|
|
|
|
|
|
$op->pmflags, $op->pmpermflags, 0 # XXX original 5.6 B::C misses pmdynflags |
2651
|
|
|
|
|
|
|
)); |
2652
|
|
|
|
|
|
|
} else { # perl5.8.x |
2653
|
0
|
|
|
|
|
0
|
$pmopsect->comment( |
2654
|
|
|
|
|
|
|
"$opsect_common, first, last, pmreplroot, pmreplstart, pmoffset, pmflags, pmpermflags, pmdynflags, pmstash" |
2655
|
|
|
|
|
|
|
); |
2656
|
|
|
|
|
|
|
$pmopsect->add( |
2657
|
|
|
|
|
|
|
sprintf( "%s, s\\_%x, s\\_%x, %s, %s, 0, %u, 0x%x, 0x%x, 0x%x, %s", |
2658
|
0
|
|
|
|
|
0
|
$op->_save_common, ${ $op->first }, |
2659
|
0
|
0
|
|
|
|
0
|
${ $op->last }, $replrootfield, |
|
0
|
0
|
|
|
|
0
|
|
2660
|
|
|
|
|
|
|
$replstartfield, $ITHREADS ? $op->pmoffset : 0, |
2661
|
|
|
|
|
|
|
$op->pmflags, $op->pmpermflags, |
2662
|
|
|
|
|
|
|
$op->pmdynflags, $MULTI ? cstring($op->pmstashpv) : "0" |
2663
|
|
|
|
|
|
|
)); |
2664
|
0
|
0
|
0
|
|
|
0
|
if (!$MULTI and $op->pmstash) { |
2665
|
0
|
|
|
|
|
0
|
my $stash = $op->pmstash->save; |
2666
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "pmop_list[%d].op_pmstash = %s;", $pmopsect->index, $stash ) ); |
2667
|
|
|
|
|
|
|
} |
2668
|
|
|
|
|
|
|
} |
2669
|
0
|
0
|
|
|
|
0
|
$pmopsect->debug( $op->name, $op->flagspv ) if $debug{flags}; |
2670
|
0
|
|
|
|
|
0
|
my $pm = sprintf( "pmop_list[%d]", $pmopsect->index ); |
2671
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "%s.op_ppaddr = %s;", $pm, $ppaddr ) ) |
2672
|
|
|
|
|
|
|
unless $B::C::optimize_ppaddr; |
2673
|
0
|
|
|
|
|
0
|
my $re = $op->precomp; |
2674
|
0
|
0
|
|
|
|
0
|
if ( defined($re) ) { |
2675
|
0
|
|
|
|
|
0
|
my $initpm = $init; |
2676
|
0
|
|
|
|
|
0
|
$Regexp{$$op} = $op; |
2677
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
|
|
0
|
|
|
|
|
|
2678
|
|
|
|
|
|
|
# TODO minor optim: fix savere( $re ) to avoid newSVpvn; |
2679
|
|
|
|
|
|
|
# precomp did not set the utf8 flag (#333, #338), fixed with 1.52_01 |
2680
|
0
|
|
|
|
|
0
|
my ($qre, $relen, $utf8) = strlen_flags($re); |
2681
|
0
|
|
|
|
|
0
|
my $pmflags = $op->pmflags; |
2682
|
|
|
|
|
|
|
warn "pregcomp $pm $qre:$relen:$utf8".sprintf(" 0x%x\n",$pmflags) |
2683
|
0
|
0
|
0
|
|
|
0
|
if $debug{pv} or $debug{gv}; |
2684
|
|
|
|
|
|
|
# Since 5.13.10 with PMf_FOLD (i) we need to swash_init("utf8::Cased"). |
2685
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.013009 and $pmflags & 4) { |
2686
|
|
|
|
|
|
|
# Note: in CORE utf8::SWASHNEW is demand-loaded from utf8 with Perl_load_module() |
2687
|
0
|
|
|
|
|
0
|
load_utf8_heavy(); |
2688
|
0
|
0
|
0
|
|
|
0
|
if ($PERL518 and !$swash_init and $swash_ToCf) { |
|
|
|
0
|
|
|
|
|
2689
|
0
|
|
|
|
|
0
|
$init->add("PL_utf8_tofold = $swash_ToCf;"); |
2690
|
0
|
|
|
|
|
0
|
$swash_init++; |
2691
|
|
|
|
|
|
|
} |
2692
|
|
|
|
|
|
|
} |
2693
|
|
|
|
|
|
|
# some pm need early init (242), SWASHNEW needs some late GVs (GH#273) |
2694
|
|
|
|
|
|
|
# esp with 5.22 multideref init. i.e. all \p{} \N{}, \U, /i, ... |
2695
|
|
|
|
|
|
|
# But XSLoader and utf8::SWASHNEW itself needs to be early. |
2696
|
0
|
0
|
0
|
|
|
0
|
if (($utf8 and $] >= 5.013009 and ($pmflags & 4 == 4)) # needs SWASHNEW (case fold) |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2697
|
|
|
|
|
|
|
or re_does_swash($qre, $pmflags)) |
2698
|
|
|
|
|
|
|
{ |
2699
|
0
|
|
|
|
|
0
|
$initpm = $init1; |
2700
|
0
|
0
|
|
|
|
0
|
warn sprintf("deferred PMOP %s %s 0x%x\n", $qre, $fullname, $pmflags) if $debug{sv}; |
2701
|
|
|
|
|
|
|
} else { |
2702
|
0
|
0
|
|
|
|
0
|
warn sprintf("normal PMOP %s %s 0x%x\n", $qre, $fullname, $pmflags) if $debug{sv}; |
2703
|
|
|
|
|
|
|
} |
2704
|
0
|
0
|
0
|
|
|
0
|
if ($PERL518 and $op->reflags & RXf_EVAL_SEEN) { # set HINT_RE_EVAL on |
2705
|
0
|
|
|
|
|
0
|
$pmflags |= PMf_EVAL; |
2706
|
0
|
|
|
|
|
0
|
$initpm->no_split; |
2707
|
0
|
|
|
|
|
0
|
$initpm->add("{", |
2708
|
|
|
|
|
|
|
" U32 hints_sav = PL_hints;", |
2709
|
|
|
|
|
|
|
" PL_hints |= HINT_RE_EVAL;"); |
2710
|
|
|
|
|
|
|
} |
2711
|
0
|
0
|
|
|
|
0
|
if ($] > 5.008008) { # can do utf8 qr |
2712
|
0
|
|
|
|
|
0
|
$initpm->add( # XXX Modification of a read-only value attempted. use DateTime - threaded |
2713
|
|
|
|
|
|
|
sprintf("PM_SETRE(&%s, CALLREGCOMP(newSVpvn_flags(%s, %s, SVs_TEMP|$utf8), 0x%x));", |
2714
|
|
|
|
|
|
|
$pm, $qre, $relen, $pmflags), |
2715
|
|
|
|
|
|
|
sprintf("RX_EXTFLAGS(PM_GETRE(&%s)) = 0x%x;", $pm, $op->reflags )); |
2716
|
|
|
|
|
|
|
} else { |
2717
|
0
|
|
|
|
|
0
|
$initpm->add |
2718
|
|
|
|
|
|
|
("PM_SETRE(&$pm,", |
2719
|
|
|
|
|
|
|
" CALLREGCOMP(newSVpvn($qre, $relen), ".sprintf("0x%x));", $pmflags), |
2720
|
|
|
|
|
|
|
sprintf("RX_EXTFLAGS(PM_GETRE(&%s)) = 0x%x;", $pm, $op->reflags )); |
2721
|
0
|
0
|
|
|
|
0
|
$initpm->add("SvUTF8_on(PM_GETRE(&$pm));") if $utf8; |
2722
|
|
|
|
|
|
|
} |
2723
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.018 and $op->reflags & RXf_EVAL_SEEN) { # set HINT_RE_EVAL off |
2724
|
0
|
|
|
|
|
0
|
$initpm->add(" PL_hints = hints_sav;", |
2725
|
|
|
|
|
|
|
"}"); |
2726
|
0
|
|
|
|
|
0
|
$initpm->split(); |
2727
|
|
|
|
|
|
|
} |
2728
|
|
|
|
|
|
|
# See toke.c:8964 |
2729
|
|
|
|
|
|
|
# set in the stash the PERL_MAGIC_symtab PTR to the PMOP: ((PMOP**)mg->mg_ptr) [elements++] = pm; |
2730
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and $op->pmflags & PMf_ONCE()) { |
2731
|
0
|
0
|
|
|
|
0
|
my $stash = $MULTI ? $op->pmstashpv |
|
|
0
|
|
|
|
|
|
2732
|
|
|
|
|
|
|
: ref $op->pmstash eq 'B::HV' ? $op->pmstash->NAME : '__ANON__'; |
2733
|
0
|
|
|
|
|
0
|
$Regexp{$$op} = $op; #188: restore PMf_ONCE, set PERL_MAGIC_symtab in $stash |
2734
|
|
|
|
|
|
|
} |
2735
|
|
|
|
|
|
|
} |
2736
|
|
|
|
|
|
|
elsif ($PERL56) { |
2737
|
0
|
|
|
|
|
0
|
my ( $resym, $relen ) = savere( $re, 0 ); |
2738
|
0
|
|
|
|
|
0
|
$init->add( |
2739
|
|
|
|
|
|
|
"$pm.op_pmregexp = pregcomp((char*)$resym, (char*)$resym + $relen, &$pm);" |
2740
|
|
|
|
|
|
|
); |
2741
|
|
|
|
|
|
|
} |
2742
|
|
|
|
|
|
|
else { # 5.8 |
2743
|
0
|
|
|
|
|
0
|
my ( $resym, $relen ) = savere( $re, 0 ); |
2744
|
0
|
|
|
|
|
0
|
$init->add( |
2745
|
|
|
|
|
|
|
"PM_SETRE(&$pm, CALLREGCOMP(aTHX_ (char*)$resym, (char*)$resym + $relen, &$pm));" |
2746
|
|
|
|
|
|
|
); |
2747
|
|
|
|
|
|
|
} |
2748
|
|
|
|
|
|
|
} |
2749
|
0
|
0
|
|
|
|
0
|
if ( $gvsym ) { |
2750
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
2751
|
|
|
|
|
|
|
# XXX need that for subst |
2752
|
0
|
|
|
|
|
0
|
$init->add("$pm.op_pmreplrootu.op_pmreplroot = (OP*)$gvsym;"); |
2753
|
|
|
|
|
|
|
} else { |
2754
|
0
|
|
|
|
|
0
|
$init->add("$pm.op_pmreplroot = (OP*)$gvsym;"); |
2755
|
|
|
|
|
|
|
} |
2756
|
|
|
|
|
|
|
} |
2757
|
0
|
|
|
|
|
0
|
savesym( $op, "(OP*)&$pm" ); |
2758
|
|
|
|
|
|
|
} |
2759
|
|
|
|
|
|
|
|
2760
|
|
|
|
|
|
|
sub B::SPECIAL::save { |
2761
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
2762
|
|
|
|
|
|
|
# special case: $$sv is not the address but an index into specialsv_list |
2763
|
|
|
|
|
|
|
# warn "SPECIAL::save specialsv $$sv\n"; # debug |
2764
|
0
|
0
|
|
|
|
0
|
@specialsv_name = qw(Nullsv &PL_sv_undef &PL_sv_yes &PL_sv_no pWARN_ALL pWARN_NONE) |
2765
|
|
|
|
|
|
|
unless @specialsv_name; # 5.6.2 Exporter quirks. pWARN_STD was added to B with 5.8.9 |
2766
|
0
|
|
|
|
|
0
|
my $sym = $specialsv_name[$$sv]; |
2767
|
0
|
0
|
|
|
|
0
|
if ( !defined($sym) ) { |
2768
|
0
|
|
|
|
|
0
|
warn "unknown specialsv index $$sv passed to B::SPECIAL::save"; |
2769
|
|
|
|
|
|
|
} |
2770
|
0
|
|
|
|
|
0
|
return $sym; |
2771
|
|
|
|
|
|
|
} |
2772
|
|
|
|
|
|
|
|
2773
|
|
|
|
0
|
|
|
sub B::OBJECT::save { } |
2774
|
|
|
|
|
|
|
|
2775
|
|
|
|
|
|
|
sub B::NULL::save { |
2776
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
2777
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
2778
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
2779
|
|
|
|
|
|
|
|
2780
|
|
|
|
|
|
|
# debug |
2781
|
0
|
0
|
|
|
|
0
|
if ( $$sv == 0 ) { |
2782
|
0
|
0
|
|
|
|
0
|
warn "NULL::save for sv = 0 called from @{[(caller(1))[3]]}\n" if $verbose; |
|
0
|
|
|
|
|
0
|
|
2783
|
0
|
|
|
|
|
0
|
return savesym( $sv, "(void*)Nullsv" ); |
2784
|
|
|
|
|
|
|
} |
2785
|
|
|
|
|
|
|
|
2786
|
0
|
|
|
|
|
0
|
my $i = $svsect->index + 1; |
2787
|
0
|
0
|
|
|
|
0
|
warn "Saving SVt_NULL sv_list[$i]\n" if $debug{sv}; |
2788
|
0
|
0
|
|
|
|
0
|
$svsect->add( sprintf( "NULL, $u32fmt, 0x%x".($PERL510?", {0}":''), |
2789
|
|
|
|
|
|
|
$sv->REFCNT, $sv->FLAGS ) ); |
2790
|
|
|
|
|
|
|
#$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; # XXX where is this possible? |
2791
|
0
|
0
|
0
|
|
|
0
|
if ($debug{flags} and (!$ITHREADS or $PERL514) and $DEBUG_LEAKING_SCALARS) { # add index to sv_debug_file to easily find the Nullsv |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2792
|
|
|
|
|
|
|
# $svsect->debug( "ix added to sv_debug_file" ); |
2793
|
0
|
|
|
|
|
0
|
$init->add(sprintf(qq(sv_list[%d].sv_debug_file = savesharedpv("NULL sv_list[%d] 0x%x");), |
2794
|
|
|
|
|
|
|
$svsect->index, $svsect->index, $sv->FLAGS)); |
2795
|
|
|
|
|
|
|
} |
2796
|
0
|
|
|
|
|
0
|
savesym( $sv, sprintf( "&sv_list[%d]", $svsect->index ) ); |
2797
|
|
|
|
|
|
|
} |
2798
|
|
|
|
|
|
|
|
2799
|
|
|
|
|
|
|
sub B::UV::save { |
2800
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
2801
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
2802
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
2803
|
0
|
|
|
|
|
0
|
my $uvuformat = $Config{uvuformat}; |
2804
|
0
|
|
|
|
|
0
|
$uvuformat =~ s/["\0]//g; #" poor editor |
2805
|
0
|
|
|
|
|
0
|
$uvuformat =~ s/".$/"/; # cperl bug 5.22.2 #61 |
2806
|
0
|
|
|
|
|
0
|
my $uvx = $sv->UVX; |
2807
|
0
|
|
|
|
|
0
|
my $suff = 'U'; |
2808
|
0
|
0
|
|
|
|
0
|
$suff .= 'L' if $uvx > 2147483647; |
2809
|
0
|
|
|
|
|
0
|
my $i = $svsect->index + 1; |
2810
|
0
|
0
|
|
|
|
0
|
if ($PERL524) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2811
|
|
|
|
|
|
|
# since 5.24 we need to point the xpvuv to the head |
2812
|
|
|
|
|
|
|
} elsif ($PERL514) { |
2813
|
|
|
|
|
|
|
# issue 145 warn $sv->UVX, " ", sprintf($u32fmt, $sv->UVX); |
2814
|
0
|
|
|
|
|
0
|
$xpvuvsect->comment( "stash, magic, cur, len, xuv_u" ); |
2815
|
0
|
|
|
|
|
0
|
$xpvuvsect->add( sprintf( "Nullhv, {0}, 0, 0, {%".$uvuformat."$suff}", $uvx ) ); |
2816
|
|
|
|
|
|
|
} elsif ($PERL510) { |
2817
|
0
|
|
|
|
|
0
|
$xpvuvsect->comment( "stash, magic, cur, len, xuv_u" ); |
2818
|
0
|
|
|
|
|
0
|
$xpvuvsect->add( sprintf( "{0}, 0, 0, {%".$uvuformat."$suff}", $uvx ) ); |
2819
|
|
|
|
|
|
|
} else { |
2820
|
0
|
|
|
|
|
0
|
$xpvuvsect->comment( "pv, cur, len, uv" ); |
2821
|
0
|
|
|
|
|
0
|
$xpvuvsect->add( sprintf( "0, 0, 0, %".$uvuformat.$suff, $uvx ) ); |
2822
|
|
|
|
|
|
|
} |
2823
|
0
|
0
|
|
|
|
0
|
if ($PERL524) { |
2824
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf( "NULL, $u32fmt, 0x%x". |
|
|
0
|
|
|
|
|
|
2825
|
|
|
|
|
|
|
($PERL510?', {'.($C99?".svu_uv=":"").$uvx."$suff}":''), |
2826
|
|
|
|
|
|
|
$sv->REFCNT, $sv->FLAGS)); |
2827
|
|
|
|
|
|
|
#32bit - sizeof(void*), 64bit: - 2*ptrsize |
2828
|
0
|
0
|
0
|
|
|
0
|
if ($Config{ptrsize} == 4 and !IS_MSVC) { |
2829
|
0
|
|
|
|
|
0
|
$init->add(sprintf( "sv_list[%d].sv_any = (void*)&sv_list[%d] - sizeof(void*);", $i, $i)); |
2830
|
|
|
|
|
|
|
} else { |
2831
|
|
|
|
|
|
|
$init->add(sprintf( "sv_list[%d].sv_any = (char*)&sv_list[%d] - %d;", $i, $i, |
2832
|
0
|
|
|
|
|
0
|
2*$Config{ptrsize})); |
2833
|
|
|
|
|
|
|
} |
2834
|
|
|
|
|
|
|
} else { |
2835
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf( "&xpvuv_list[%d], $u32fmt, 0x%x". |
|
|
0
|
|
|
|
|
|
2836
|
|
|
|
|
|
|
($PERL510?', {'.($C99?".svu_uv=":"").$uvx."$suff}":''), |
2837
|
|
|
|
|
|
|
$xpvuvsect->index, $sv->REFCNT, $sv->FLAGS)); |
2838
|
|
|
|
|
|
|
} |
2839
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
2840
|
|
|
|
|
|
|
warn sprintf( "Saving IV(UV) 0x%x to xpvuv_list[%d], sv_list[%d], called from %s:%s\n", |
2841
|
0
|
|
|
|
|
0
|
$sv->UVX, $xpvuvsect->index, $i, @{[(caller(1))[3]]}, @{[(caller(0))[2]]} ) |
|
0
|
|
|
|
|
0
|
|
2842
|
0
|
0
|
|
|
|
0
|
if $debug{sv}; |
2843
|
0
|
|
|
|
|
0
|
savesym( $sv, sprintf( "&sv_list[%d]", $i ) ); |
2844
|
|
|
|
|
|
|
} |
2845
|
|
|
|
|
|
|
|
2846
|
|
|
|
|
|
|
sub B::IV::save { |
2847
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
2848
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
2849
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
2850
|
|
|
|
|
|
|
# Since 5.11 the RV is no special SV object anymore, just a IV (test 16) |
2851
|
0
|
|
|
|
|
0
|
my $svflags = $sv->FLAGS; |
2852
|
0
|
0
|
0
|
|
|
0
|
if ($PERL512 and $svflags & SVf_ROK) { |
2853
|
0
|
|
|
|
|
0
|
return $sv->B::RV::save($fullname); |
2854
|
|
|
|
|
|
|
} |
2855
|
0
|
0
|
|
|
|
0
|
if ($svflags & SVf_IVisUV) { |
2856
|
0
|
|
|
|
|
0
|
return $sv->B::UV::save; |
2857
|
|
|
|
|
|
|
} |
2858
|
0
|
|
|
|
|
0
|
my $ivx = ivx($sv->IVX); |
2859
|
0
|
|
|
|
|
0
|
my $i = $svsect->index + 1; |
2860
|
0
|
0
|
0
|
|
|
0
|
if ($svflags & 0xff and !($svflags & (SVf_IOK|SVp_IOK))) { # Not nullified |
2861
|
0
|
0
|
0
|
|
|
0
|
unless (($PERL510 and $svflags & 0x00010000) # PADSTALE - out of scope lexical is !IOK |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2862
|
|
|
|
|
|
|
or (!$PERL510 and $svflags & 0x00000100) # PADBUSY |
2863
|
|
|
|
|
|
|
or ($] > 5.015002 and $svflags & 0x60002)) { # 5.15.3 changed PAD bits |
2864
|
0
|
|
|
|
|
0
|
warn sprintf("Internal warning: IV !IOK $fullname sv_list[$i] 0x%x\n",$svflags); |
2865
|
|
|
|
|
|
|
} |
2866
|
|
|
|
|
|
|
} |
2867
|
0
|
0
|
|
|
|
0
|
if ($PERL524) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2868
|
|
|
|
|
|
|
# since 5.24 we need to point the xpviv to the head |
2869
|
|
|
|
|
|
|
} elsif ($PERL514) { |
2870
|
0
|
|
|
|
|
0
|
$xpvivsect->comment( "stash, magic, cur, len, xiv_u" ); |
2871
|
0
|
|
|
|
|
0
|
$xpvivsect->add( sprintf( "Nullhv, {0}, 0, 0, {%s}", $ivx ) ); |
2872
|
|
|
|
|
|
|
} elsif ($PERL510) { |
2873
|
0
|
|
|
|
|
0
|
$xpvivsect->comment( "stash, magic, cur, len, xiv_u" ); |
2874
|
0
|
|
|
|
|
0
|
$xpvivsect->add( sprintf( "{0}, 0, 0, {%s}", $ivx ) ); |
2875
|
|
|
|
|
|
|
} else { |
2876
|
0
|
|
|
|
|
0
|
$xpvivsect->comment( "pv, cur, len, iv" ); |
2877
|
0
|
|
|
|
|
0
|
$xpvivsect->add( sprintf( "0, 0, 0, %s", $ivx ) ); |
2878
|
|
|
|
|
|
|
} |
2879
|
0
|
0
|
|
|
|
0
|
if ($PERL524) { |
2880
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf( "NULL, $u32fmt, 0x%x, {".($C99?".svu_iv=":"").$ivx.'}', |
2881
|
|
|
|
|
|
|
$sv->REFCNT, $svflags )); |
2882
|
|
|
|
|
|
|
#32bit - sizeof(void*), 64bit: - 2*ptrsize |
2883
|
0
|
0
|
0
|
|
|
0
|
if ($Config{ptrsize} == 4 and !IS_MSVC) { |
2884
|
0
|
|
|
|
|
0
|
$init->add(sprintf( "sv_list[%d].sv_any = (void*)&sv_list[%d] - sizeof(void*);", $i, $i)); |
2885
|
|
|
|
|
|
|
} else { |
2886
|
|
|
|
|
|
|
$init->add(sprintf( "sv_list[%d].sv_any = (char*)&sv_list[%d] - %d;", $i, $i, |
2887
|
0
|
|
|
|
|
0
|
2*$Config{ptrsize})); |
2888
|
|
|
|
|
|
|
} |
2889
|
|
|
|
|
|
|
} else { |
2890
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf( "&xpviv_list[%d], $u32fmt, 0x%x".($PERL510?', {'.($C99?".svu_iv=":"").$ivx.'}':''), |
|
|
0
|
|
|
|
|
|
2891
|
|
|
|
|
|
|
$xpvivsect->index, $sv->REFCNT, $svflags )); |
2892
|
|
|
|
|
|
|
} |
2893
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
2894
|
|
|
|
|
|
|
warn sprintf( "Saving IV 0x%x to xpviv_list[%d], sv_list[%d], called from %s:%s\n", |
2895
|
0
|
|
|
|
|
0
|
$sv->IVX, $xpvivsect->index, $i, @{[(caller(1))[3]]}, @{[(caller(0))[2]]} ) |
|
0
|
|
|
|
|
0
|
|
2896
|
0
|
0
|
|
|
|
0
|
if $debug{sv}; |
2897
|
0
|
|
|
|
|
0
|
savesym( $sv, sprintf( "&sv_list[%d]", $i ) ); |
2898
|
|
|
|
|
|
|
} |
2899
|
|
|
|
|
|
|
|
2900
|
|
|
|
|
|
|
sub B::NV::save { |
2901
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
2902
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
2903
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
2904
|
0
|
|
|
|
|
0
|
my $nv = nvx($sv->NV); |
2905
|
0
|
0
|
|
|
|
0
|
$nv .= '.00' if $nv =~ /^-?\d+$/; |
2906
|
|
|
|
|
|
|
# IVX is invalid in B.xs and unused |
2907
|
0
|
0
|
|
|
|
0
|
my $iv = $sv->FLAGS & SVf_IOK ? $sv->IVX : 0; |
2908
|
0
|
0
|
0
|
|
|
0
|
$nv = '0.00' if IS_MSVC and !$nv; |
2909
|
0
|
0
|
|
|
|
0
|
if ($PERL514) { |
|
|
0
|
|
|
|
|
|
2910
|
0
|
|
|
|
|
0
|
$xpvnvsect->comment('STASH, MAGIC, cur, len, IVX, NVX'); |
2911
|
0
|
|
|
|
|
0
|
$xpvnvsect->add( sprintf( "Nullhv, {0}, 0, 0, {%ld}, {%s}", $iv, $nv ) ); |
2912
|
|
|
|
|
|
|
} elsif ($PERL510) { # not fixed by NV isa IV >= 5.8 |
2913
|
0
|
|
|
|
|
0
|
$xpvnvsect->comment('NVX, cur, len, IVX'); |
2914
|
0
|
|
|
|
|
0
|
$xpvnvsect->add( sprintf( "{%s}, 0, 0, {%ld}", $nv, $iv ) ); |
2915
|
|
|
|
|
|
|
} |
2916
|
|
|
|
|
|
|
else { |
2917
|
0
|
|
|
|
|
0
|
$xpvnvsect->comment('PVX, cur, len, IVX, NVX'); |
2918
|
0
|
|
|
|
|
0
|
$xpvnvsect->add( sprintf( "0, 0, 0, %ld, %s", $iv, $nv ) ); |
2919
|
|
|
|
|
|
|
} |
2920
|
0
|
0
|
|
|
|
0
|
$svsect->add( |
2921
|
|
|
|
|
|
|
sprintf( "&xpvnv_list[%d], $u32fmt, 0x%x %s", |
2922
|
|
|
|
|
|
|
$xpvnvsect->index, $sv->REFCNT, $sv->FLAGS, $PERL510 ? ', {0}' : '' )); |
2923
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
2924
|
|
|
|
|
|
|
warn sprintf( "Saving NV %s to xpvnv_list[%d], sv_list[%d]\n", |
2925
|
|
|
|
|
|
|
$nv, $xpvnvsect->index, $svsect->index ) |
2926
|
0
|
0
|
|
|
|
0
|
if $debug{sv}; |
2927
|
0
|
|
|
|
|
0
|
savesym( $sv, sprintf( "&sv_list[%d]", $svsect->index ) ); |
2928
|
|
|
|
|
|
|
} |
2929
|
|
|
|
|
|
|
|
2930
|
|
|
|
|
|
|
sub savepvn { |
2931
|
0
|
|
|
0
|
0
|
0
|
my ( $dest, $pv, $sv, $cur ) = @_; |
2932
|
0
|
|
|
|
|
0
|
my @init; |
2933
|
|
|
|
|
|
|
|
2934
|
|
|
|
|
|
|
# work with byte offsets/lengths |
2935
|
0
|
0
|
|
|
|
0
|
$pv = pack "a*", $pv if defined $pv; |
2936
|
0
|
0
|
0
|
|
|
0
|
if ( defined $max_string_len && length($pv) > $max_string_len ) { |
2937
|
0
|
|
|
|
|
0
|
push @init, sprintf( "Newx(%s, %u, char);", $dest, length($pv) + 2 ); |
2938
|
0
|
|
|
|
|
0
|
my $offset = 0; |
2939
|
0
|
|
|
|
|
0
|
while ( length $pv ) { |
2940
|
0
|
|
|
|
|
0
|
my $str = substr $pv, 0, $max_string_len, ''; |
2941
|
0
|
|
|
|
|
0
|
push @init, |
2942
|
|
|
|
|
|
|
sprintf( "Copy(%s, %s+%d, %u, char);", |
2943
|
|
|
|
|
|
|
cstring($str), $dest, $offset, length($str) ); |
2944
|
0
|
|
|
|
|
0
|
$offset += length $str; |
2945
|
|
|
|
|
|
|
} |
2946
|
0
|
|
|
|
|
0
|
push @init, sprintf( "%s[%u] = '\\0';", $dest, $offset ); |
2947
|
|
|
|
|
|
|
warn sprintf( "Copying overlong PV %s to %s\n", cstring($pv), $dest ) |
2948
|
0
|
0
|
0
|
|
|
0
|
if $debug{sv} or $debug{pv}; |
2949
|
|
|
|
|
|
|
} |
2950
|
|
|
|
|
|
|
else { |
2951
|
|
|
|
|
|
|
# If READONLY and FAKE use newSVpvn_share instead. (test 75) |
2952
|
|
|
|
|
|
|
# XXX IsCOW forgotten here. rather use a helper is_shared_hek() |
2953
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and $sv and (($sv->FLAGS & 0x09000000) == 0x09000000)) { |
|
|
|
0
|
|
|
|
|
2954
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Saving shared HEK %s to %s\n", cstring($pv), $dest ) if $debug{sv}; |
2955
|
0
|
|
|
|
|
0
|
my $hek = save_hek($pv,'',1); |
2956
|
0
|
0
|
|
|
|
0
|
push @init, sprintf( "%s = HEK_KEY(%s);", $dest, $hek ) unless $hek eq 'NULL'; |
2957
|
0
|
0
|
|
|
|
0
|
if ($DEBUGGING) { # we have to bypass a wrong HE->HEK assert in hv.c |
2958
|
0
|
|
|
|
|
0
|
push @B::C::static_free, $dest; |
2959
|
|
|
|
|
|
|
} |
2960
|
|
|
|
|
|
|
} else { |
2961
|
0
|
|
|
|
|
0
|
my $cstr = cstring($pv); |
2962
|
0
|
0
|
0
|
|
|
0
|
if (!$cstr and $cstr == 0) { |
2963
|
0
|
|
|
|
|
0
|
$cstr = '""'; |
2964
|
|
|
|
|
|
|
} |
2965
|
0
|
0
|
0
|
|
|
0
|
if ($sv and IsCOW($sv)) { # and ($B::C::cow or IsCOW_hek($sv))) |
2966
|
|
|
|
|
|
|
# This cannot be savepvn allocated. TODO: READONLY COW => static hek? |
2967
|
0
|
0
|
|
|
|
0
|
if ($cstr !~ /\\000\\00\d"$/) { |
2968
|
0
|
|
|
|
|
0
|
$cstr = substr($cstr,0,-1) . '\0\001"'; |
2969
|
0
|
|
|
|
|
0
|
$cur += 2; |
2970
|
|
|
|
|
|
|
} |
2971
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Saving COW PV %s to %s\n", $cstr, $dest ) if $debug{sv}; |
2972
|
0
|
|
|
|
|
0
|
return (sprintf( "Newx(%s, sizeof(%s)-1, char);", $dest, $cstr ), |
2973
|
|
|
|
|
|
|
sprintf( "Copy(%s, %s, sizeof(%s)-1, char);", $cstr, $dest, $cstr )); |
2974
|
|
|
|
|
|
|
} |
2975
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Saving PV %s to %s\n", $cstr, $dest ) if $debug{sv}; |
2976
|
0
|
|
|
|
|
0
|
push @init, sprintf( "%s = Perl_savepvn(aTHX_ STR_WITH_LEN(%s));", $dest, $cstr ); |
2977
|
|
|
|
|
|
|
} |
2978
|
|
|
|
|
|
|
} |
2979
|
0
|
|
|
|
|
0
|
return @init; |
2980
|
|
|
|
|
|
|
} |
2981
|
|
|
|
|
|
|
|
2982
|
|
|
|
|
|
|
sub B::PVLV::save { |
2983
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
2984
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
2985
|
0
|
0
|
|
|
|
0
|
if (defined $sym) { |
2986
|
0
|
0
|
|
|
|
0
|
if ($in_endav) { |
2987
|
0
|
0
|
|
|
|
0
|
warn "in_endav: static_free without $sym\n" if $debug{av}; |
2988
|
0
|
|
|
|
|
0
|
@B::C::static_free = grep {$_ ne $sym} @B::C::static_free; |
|
0
|
|
|
|
|
0
|
|
2989
|
|
|
|
|
|
|
} |
2990
|
0
|
|
|
|
|
0
|
return $sym; |
2991
|
|
|
|
|
|
|
} |
2992
|
0
|
|
|
|
|
0
|
my ($pvsym, $cur, $len, $pv, $static, $flags) = save_pv_or_rv ($sv, $fullname); |
2993
|
0
|
|
|
|
|
0
|
my ( $lvtarg, $lvtarg_sym ); # XXX missing |
2994
|
0
|
|
|
|
|
0
|
my $tmp_pvsym = $pvsym; |
2995
|
0
|
0
|
|
|
|
0
|
if ($PERL514) { |
|
|
0
|
|
|
|
|
|
2996
|
0
|
|
|
|
|
0
|
$xpvlvsect->comment('STASH, MAGIC, CUR, LEN, GvNAME, xnv_u, TARGOFF, TARGLEN, TARG, TYPE'); |
2997
|
0
|
|
|
|
|
0
|
$xpvlvsect->add( |
2998
|
|
|
|
|
|
|
sprintf("Nullhv, {0}, %u, %d, 0/*GvNAME later*/, %s, %u, %u, Nullsv, %s", |
2999
|
|
|
|
|
|
|
$cur, $len, nvx($sv->NVX), |
3000
|
|
|
|
|
|
|
$sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) )); |
3001
|
0
|
0
|
0
|
|
|
0
|
$tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static |
3002
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x, {(char*)%s}", |
3003
|
|
|
|
|
|
|
$xpvlvsect->index, $sv->REFCNT, $sv->FLAGS, $tmp_pvsym)); |
3004
|
|
|
|
|
|
|
} elsif ($PERL510) { |
3005
|
0
|
|
|
|
|
0
|
$xpvlvsect->comment('xnv_u, CUR, LEN, GvNAME, MAGIC, STASH, TARGOFF, TARGLEN, TARG, TYPE'); |
3006
|
0
|
|
|
|
|
0
|
$xpvlvsect->add( |
3007
|
|
|
|
|
|
|
sprintf("%s, %u, %d, 0/*GvNAME later*/, 0, Nullhv, %u, %u, Nullsv, %s", |
3008
|
|
|
|
|
|
|
nvx($sv->NVX), $cur, $len, |
3009
|
|
|
|
|
|
|
$sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) )); |
3010
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x, {%s}", |
3011
|
|
|
|
|
|
|
$xpvlvsect->index, $sv->REFCNT, $flags, |
3012
|
|
|
|
|
|
|
($C99?".svu_pv = (char*)":"(char*)").$tmp_pvsym)); |
3013
|
|
|
|
|
|
|
} else { |
3014
|
0
|
|
|
|
|
0
|
$xpvlvsect->comment('PVX, CUR, LEN, IVX, NVX, TARGOFF, TARGLEN, TARG, TYPE'); |
3015
|
0
|
|
|
|
|
0
|
$xpvlvsect->add( |
3016
|
|
|
|
|
|
|
sprintf("(char*)%s, %u, %u, %s, %s, 0, 0, %u, %u, Nullsv, %s", |
3017
|
|
|
|
|
|
|
$pvsym, $cur, $len, ivx($sv->IVX), nvx($sv->NVX), |
3018
|
|
|
|
|
|
|
$sv->TARGOFF, $sv->TARGLEN, cchar( $sv->TYPE ) )); |
3019
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvlv_list[%d], $u32fmt, 0x%x", |
3020
|
|
|
|
|
|
|
$xpvlvsect->index, $sv->REFCNT, $flags)); |
3021
|
|
|
|
|
|
|
} |
3022
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
3023
|
0
|
|
|
|
|
0
|
my $s = "sv_list[".$svsect->index."]"; |
3024
|
0
|
0
|
0
|
|
|
0
|
if ( !$static ) { |
|
|
0
|
|
|
|
|
|
3025
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3026
|
0
|
|
|
|
|
0
|
$init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) ); |
3027
|
|
|
|
|
|
|
} |
3028
|
|
|
|
|
|
|
else { |
3029
|
0
|
|
|
|
|
0
|
$init->add( savepvn( sprintf( "xpvlv_list[%d].xpv_pv", $xpvlvsect->index ), $pv, $cur ) ); |
3030
|
|
|
|
|
|
|
} |
3031
|
|
|
|
|
|
|
} elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) { |
3032
|
0
|
|
|
|
|
0
|
$init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym )); |
3033
|
|
|
|
|
|
|
} |
3034
|
0
|
|
|
|
|
0
|
$sv->save_magic($fullname); |
3035
|
0
|
|
|
|
|
0
|
savesym( $sv, "&".$s ); |
3036
|
|
|
|
|
|
|
} |
3037
|
|
|
|
|
|
|
|
3038
|
|
|
|
|
|
|
sub B::PVIV::save { |
3039
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
3040
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
3041
|
0
|
0
|
|
|
|
0
|
if (defined $sym) { |
3042
|
0
|
0
|
|
|
|
0
|
if ($in_endav) { |
3043
|
0
|
0
|
|
|
|
0
|
warn "in_endav: static_free without $sym\n" if $debug{av}; |
3044
|
0
|
|
|
|
|
0
|
@B::C::static_free = grep {$_ ne $sym} @B::C::static_free; |
|
0
|
|
|
|
|
0
|
|
3045
|
|
|
|
|
|
|
} |
3046
|
0
|
|
|
|
|
0
|
return $sym; |
3047
|
|
|
|
|
|
|
} |
3048
|
0
|
|
|
|
|
0
|
my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname); |
3049
|
0
|
|
|
|
|
0
|
my $tmp_pvsym = $pvsym; |
3050
|
0
|
0
|
|
|
|
0
|
if ($PERL514) { |
|
|
0
|
|
|
|
|
|
3051
|
0
|
|
|
|
|
0
|
$xpvivsect->comment('STASH, MAGIC, cur, len, IVX'); |
3052
|
0
|
|
|
|
|
0
|
$xpvivsect->add( sprintf( "Nullhv, {0}, %u, %u, {%s}", $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long |
3053
|
0
|
0
|
0
|
|
|
0
|
$tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static |
3054
|
|
|
|
|
|
|
} elsif ($PERL510) { |
3055
|
0
|
|
|
|
|
0
|
$xpvivsect->comment('xnv_u, cur, len, IVX'); |
3056
|
0
|
|
|
|
|
0
|
$xpvivsect->add( sprintf( "{0}, %u, %u, {%s}", $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long |
3057
|
|
|
|
|
|
|
} else { |
3058
|
|
|
|
|
|
|
#$iv = 0 if $sv->FLAGS & (SVf_IOK|SVp_IOK); |
3059
|
0
|
|
|
|
|
0
|
$xpvivsect->comment('PVX, cur, len, IVX'); |
3060
|
0
|
|
|
|
|
0
|
$xpvivsect->add( sprintf( "(char*)%s, %u, %u, %s", |
3061
|
|
|
|
|
|
|
$pvsym, $cur, $len, ivx($sv->IVX) ) ); # IVTYPE long |
3062
|
|
|
|
|
|
|
} |
3063
|
0
|
0
|
|
|
|
0
|
$svsect->add( |
|
|
0
|
|
|
|
|
|
3064
|
|
|
|
|
|
|
sprintf("&xpviv_list[%d], $u32fmt, 0x%x %s", |
3065
|
|
|
|
|
|
|
$xpvivsect->index, $sv->REFCNT, $flags, |
3066
|
|
|
|
|
|
|
$PERL510 ? ", {".($C99?".svu_pv=":"")."(char*)$tmp_pvsym}" : '' ) ); |
3067
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
3068
|
0
|
|
|
|
|
0
|
my $s = "sv_list[".$svsect->index."]"; |
3069
|
0
|
0
|
|
|
|
0
|
if ( defined($pv) ) { |
3070
|
0
|
0
|
0
|
|
|
0
|
if ( !$static ) { |
|
|
0
|
|
|
|
|
|
3071
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3072
|
0
|
|
|
|
|
0
|
$init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) ); |
3073
|
|
|
|
|
|
|
} else { |
3074
|
0
|
|
|
|
|
0
|
$init->add( savepvn( sprintf( "xpviv_list[%d].xpv_pv", $xpvivsect->index ), $pv, $cur ) ); |
3075
|
|
|
|
|
|
|
} |
3076
|
|
|
|
|
|
|
} elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) { |
3077
|
0
|
|
|
|
|
0
|
$init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym )); |
3078
|
|
|
|
|
|
|
} |
3079
|
|
|
|
|
|
|
} |
3080
|
0
|
|
|
|
|
0
|
savesym( $sv, "&".$s ); |
3081
|
|
|
|
|
|
|
} |
3082
|
|
|
|
|
|
|
|
3083
|
|
|
|
|
|
|
sub B::PVNV::save { |
3084
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
3085
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
3086
|
0
|
0
|
|
|
|
0
|
if (defined $sym) { |
3087
|
0
|
0
|
|
|
|
0
|
if ($in_endav) { |
3088
|
0
|
0
|
|
|
|
0
|
warn "in_endav: static_free without $sym\n" if $debug{av}; |
3089
|
0
|
|
|
|
|
0
|
@B::C::static_free = grep {$_ ne $sym} @B::C::static_free; |
|
0
|
|
|
|
|
0
|
|
3090
|
|
|
|
|
|
|
} |
3091
|
0
|
|
|
|
|
0
|
return $sym; |
3092
|
|
|
|
|
|
|
} |
3093
|
0
|
|
|
|
|
0
|
my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname); |
3094
|
0
|
|
|
|
|
0
|
my $tmp_pvsym = $pvsym; |
3095
|
0
|
|
|
|
|
0
|
my $nvx = '0.0'; |
3096
|
0
|
|
|
|
|
0
|
my $ivx = ivx($sv->IVX); # here must be IVX! |
3097
|
0
|
0
|
|
|
|
0
|
if ($flags & (SVf_NOK|SVp_NOK)) { |
3098
|
|
|
|
|
|
|
# it could be a double, or it could be 2 ints - union xpad_cop_seq |
3099
|
0
|
|
|
|
|
0
|
$nvx = nvx($sv->NV); |
3100
|
|
|
|
|
|
|
} else { |
3101
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and $C99 and !$PERL522) { |
|
|
0
|
0
|
|
|
|
|
3102
|
0
|
|
|
|
|
0
|
$nvx = sprintf(".xpad_cop_seq.xlow = %s, .xpad_cop_seq.xhigh = %s", |
3103
|
|
|
|
|
|
|
ivx($sv->COP_SEQ_RANGE_LOW), ivx($sv->COP_SEQ_RANGE_HIGH), |
3104
|
|
|
|
|
|
|
); |
3105
|
|
|
|
|
|
|
} elsif (!$PERL522) { |
3106
|
0
|
|
|
|
|
0
|
$nvx = nvx($sv->NVX); |
3107
|
|
|
|
|
|
|
} |
3108
|
|
|
|
|
|
|
} |
3109
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3110
|
|
|
|
|
|
|
# For some time the stringification works of NVX double to two ints worked ok. |
3111
|
0
|
0
|
|
|
|
0
|
if ($PERL514) { |
3112
|
0
|
0
|
0
|
|
|
0
|
$tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static |
3113
|
0
|
|
|
|
|
0
|
$xpvnvsect->comment('STASH, MAGIC, cur, len, IVX, NVX'); |
3114
|
0
|
|
|
|
|
0
|
$xpvnvsect->add(sprintf( "Nullhv, {0}, %u, %u, {%s}, {%s}", $cur, $len, $ivx, $nvx) ); |
3115
|
|
|
|
|
|
|
} else { |
3116
|
0
|
|
|
|
|
0
|
$xpvnvsect->comment('NVX, cur, len, IVX'); |
3117
|
0
|
|
|
|
|
0
|
$xpvnvsect->add(sprintf( "{%s}, %u, %u, {%s}", $nvx, $cur, $len, $ivx ) ); |
3118
|
|
|
|
|
|
|
} |
3119
|
0
|
0
|
0
|
|
|
0
|
if (!($sv->FLAGS & (SVf_NOK|SVp_NOK)) and !$PERL522) { |
3120
|
0
|
0
|
|
|
|
0
|
warn "NV => run-time union xpad_cop_seq init\n" if $debug{sv}; |
3121
|
0
|
|
|
|
|
0
|
$init->add(sprintf("xpvnv_list[%d].xnv_u.xpad_cop_seq.xlow = %s;", |
3122
|
|
|
|
|
|
|
$xpvnvsect->index, ivx($sv->COP_SEQ_RANGE_LOW)), |
3123
|
|
|
|
|
|
|
# pad.c: PAD_MAX = I32_MAX (4294967295) |
3124
|
|
|
|
|
|
|
# U suffix <= "warning: this decimal constant is unsigned only in ISO C90" |
3125
|
|
|
|
|
|
|
sprintf("xpvnv_list[%d].xnv_u.xpad_cop_seq.xhigh = %s;", |
3126
|
|
|
|
|
|
|
$xpvnvsect->index, ivx($sv->COP_SEQ_RANGE_HIGH))); |
3127
|
|
|
|
|
|
|
} |
3128
|
|
|
|
|
|
|
} |
3129
|
|
|
|
|
|
|
else { |
3130
|
0
|
|
|
|
|
0
|
$xpvnvsect->comment('PVX, cur, len, IVX, NVX'); |
3131
|
0
|
|
|
|
|
0
|
$xpvnvsect->add(sprintf( "(char*)%s, %u, %u, %s, %s", $pvsym, $cur, $len, $ivx, $nvx ) ); |
3132
|
|
|
|
|
|
|
} |
3133
|
0
|
0
|
|
|
|
0
|
$svsect->add( |
|
|
0
|
|
|
|
|
|
3134
|
|
|
|
|
|
|
sprintf("&xpvnv_list[%d], $u32fmt, 0x%x %s", |
3135
|
|
|
|
|
|
|
$xpvnvsect->index, $sv->REFCNT, $flags, |
3136
|
|
|
|
|
|
|
$PERL510 ? ", {".($C99?".svu_pv=":"")."(char*)$tmp_pvsym}" : '' ) ); |
3137
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
3138
|
0
|
|
|
|
|
0
|
my $s = "sv_list[".$svsect->index."]"; |
3139
|
0
|
0
|
|
|
|
0
|
if ( defined($pv) ) { |
3140
|
0
|
0
|
0
|
|
|
0
|
if ( !$static ) { |
|
|
0
|
|
|
|
|
|
3141
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3142
|
0
|
|
|
|
|
0
|
$init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) ); |
3143
|
|
|
|
|
|
|
} |
3144
|
|
|
|
|
|
|
else { |
3145
|
0
|
|
|
|
|
0
|
$init->add( savepvn( sprintf( "xpvnv_list[%d].xpv_pv", $xpvnvsect->index ), $pv, $cur ) ); |
3146
|
|
|
|
|
|
|
} |
3147
|
|
|
|
|
|
|
} elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) { |
3148
|
0
|
|
|
|
|
0
|
$init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym )); |
3149
|
|
|
|
|
|
|
} |
3150
|
|
|
|
|
|
|
} |
3151
|
0
|
0
|
0
|
|
|
0
|
push @B::C::static_free, "&".$s if $PERL518 and $sv->FLAGS & SVs_OBJECT; |
3152
|
0
|
|
|
|
|
0
|
savesym( $sv, "&".$s ); |
3153
|
|
|
|
|
|
|
} |
3154
|
|
|
|
|
|
|
|
3155
|
|
|
|
|
|
|
sub B::BM::save { |
3156
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
3157
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
3158
|
0
|
0
|
0
|
|
|
0
|
return $sym if !$PERL510 and defined $sym; |
3159
|
0
|
0
|
|
|
|
0
|
$sv = bless $sv, "B::BM" if $PERL510; |
3160
|
0
|
|
|
|
|
0
|
my $pv = pack "a*", ( $sv->PV . "\0" . $sv->TABLE ); |
3161
|
0
|
|
|
|
|
0
|
my $cur = $sv->CUR; |
3162
|
0
|
|
|
|
|
0
|
my $len = $cur + length($sv->TABLE) + 1; |
3163
|
0
|
|
|
|
|
0
|
my $s; |
3164
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3165
|
0
|
0
|
|
|
|
0
|
warn "Saving FBM for GV $sym\n" if $debug{gv}; |
3166
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "%s = (GV*)newSV_type(SVt_PVGV);", $sym ), |
3167
|
|
|
|
|
|
|
sprintf( "SvFLAGS(%s) = 0x%x;", $sym, $sv->FLAGS), |
3168
|
|
|
|
|
|
|
sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $sv->REFCNT + 1 ), |
3169
|
|
|
|
|
|
|
sprintf( "SvPVX(%s) = %s;", $sym, cstring($pv) ), |
3170
|
|
|
|
|
|
|
sprintf( "SvCUR_set(%s, %d);", $sym, $cur ), |
3171
|
|
|
|
|
|
|
sprintf( "SvLEN_set(%s, %d);", $sym, $len ), |
3172
|
|
|
|
|
|
|
sprintf( "BmRARE(%s) = %d;", $sym, $sv->RARE ), |
3173
|
|
|
|
|
|
|
sprintf( "BmPREVIOUS(%s) = %d;", $sym, $sv->PREVIOUS ), |
3174
|
|
|
|
|
|
|
sprintf( "BmUSEFUL(%s) = %d;", $sym, $sv->USEFUL ) |
3175
|
|
|
|
|
|
|
); |
3176
|
|
|
|
|
|
|
} else { |
3177
|
0
|
|
|
|
|
0
|
my $static; |
3178
|
0
|
|
|
|
|
0
|
$xpvbmsect->comment('pvx,cur,len(+258),IVX,NVX,MAGIC,STASH,USEFUL,PREVIOUS,RARE'); |
3179
|
0
|
0
|
0
|
|
|
0
|
$xpvbmsect->add( |
3180
|
|
|
|
|
|
|
sprintf("%s, %u, %u, %s, %s, 0, 0, %d, %u, 0x%x", |
3181
|
|
|
|
|
|
|
defined($pv) && $static ? cstring($pv) : "NULL", |
3182
|
|
|
|
|
|
|
$cur, $len, ivx($sv->IVX), nvx($sv->NVX), |
3183
|
|
|
|
|
|
|
$sv->USEFUL, $sv->PREVIOUS, $sv->RARE |
3184
|
|
|
|
|
|
|
)); |
3185
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvbm_list[%d], $u32fmt, 0x%x", |
3186
|
|
|
|
|
|
|
$xpvbmsect->index, $sv->REFCNT, $sv->FLAGS)); |
3187
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
3188
|
0
|
|
|
|
|
0
|
$s = "sv_list[".$svsect->index."]"; |
3189
|
0
|
0
|
|
|
|
0
|
if (!$static) { |
3190
|
0
|
|
|
|
|
0
|
$init->add(savepvn( sprintf( "xpvbm_list[%d].xpv_pv", $xpvbmsect->index ), $pv, 0, $len ) ); |
3191
|
|
|
|
|
|
|
} else { |
3192
|
0
|
0
|
0
|
|
|
0
|
push @B::C::static_free, $s if defined($pv) and !$in_endav; |
3193
|
|
|
|
|
|
|
} |
3194
|
|
|
|
|
|
|
} |
3195
|
|
|
|
|
|
|
# Restore possible additional magic. fbm_compile adds just 'B'. |
3196
|
0
|
|
|
|
|
0
|
$sv->save_magic($fullname); |
3197
|
|
|
|
|
|
|
|
3198
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3199
|
0
|
|
|
|
|
0
|
return $sym; |
3200
|
|
|
|
|
|
|
} else { |
3201
|
0
|
0
|
|
|
|
0
|
if ($] == 5.008009) { # XXX 5.8.9 needs more. TODO test 5.8.0 - 5.8.7 |
3202
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "fbm_compile(&sv_list[%d], 0);", $svsect->index ) ); |
3203
|
|
|
|
|
|
|
} |
3204
|
|
|
|
|
|
|
# cur+len was broken on all B::C versions |
3205
|
|
|
|
|
|
|
#$init->add(sprintf( "xpvbm_list[%d].xpv_cur = %u;", $xpvbmsect->index, $len ) ); |
3206
|
0
|
|
|
|
|
0
|
return savesym( $sv, "&".$s ); |
3207
|
|
|
|
|
|
|
} |
3208
|
|
|
|
|
|
|
} |
3209
|
|
|
|
|
|
|
|
3210
|
|
|
|
|
|
|
sub B::PV::save { |
3211
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
3212
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
3213
|
0
|
0
|
|
|
|
0
|
if (defined $sym) { |
3214
|
0
|
0
|
|
|
|
0
|
if ($in_endav) { |
3215
|
0
|
0
|
|
|
|
0
|
warn "in_endav: static_free without $sym\n" if $debug{av}; |
3216
|
0
|
|
|
|
|
0
|
@B::C::static_free = grep {$_ ne $sym} @B::C::static_free; |
|
0
|
|
|
|
|
0
|
|
3217
|
|
|
|
|
|
|
} |
3218
|
0
|
|
|
|
|
0
|
return $sym; |
3219
|
|
|
|
|
|
|
} |
3220
|
|
|
|
|
|
|
#my $flags = $sv->FLAGS; |
3221
|
0
|
|
|
|
|
0
|
my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname); |
3222
|
0
|
0
|
|
|
|
0
|
my $shared_hek = $PERL510 ? (($flags & 0x09000000) == 0x09000000) : undef; |
3223
|
0
|
0
|
0
|
|
|
0
|
if (!$shared_hek and (IsCOW_hek($sv) or ($len==0 and $flags & SVf_IsCOW))) { |
|
|
|
0
|
|
|
|
|
3224
|
0
|
|
|
|
|
0
|
$shared_hek = 1; |
3225
|
|
|
|
|
|
|
} |
3226
|
0
|
|
|
|
|
0
|
my $tmp_pvsym = $pvsym; |
3227
|
|
|
|
|
|
|
# $static = 0 if !($flags & SVf_ROK) and $sv->PV and $sv->PV =~ /::bootstrap$/; |
3228
|
0
|
|
|
|
|
0
|
my $refcnt = $sv->REFCNT; |
3229
|
0
|
|
|
|
|
0
|
my $svix; |
3230
|
|
|
|
|
|
|
# sv_free2 problem with !SvIMMORTAL and del_SV |
3231
|
|
|
|
|
|
|
# repro with -O0 .. -O2 for all testcases |
3232
|
0
|
0
|
0
|
|
|
0
|
if ($PERL518 and $fullname && $fullname eq 'svop const') { |
|
|
|
0
|
|
|
|
|
3233
|
0
|
0
|
|
|
|
0
|
$refcnt = $DEBUGGING ? 1000 : 0x7fffffff; |
3234
|
|
|
|
|
|
|
} |
3235
|
|
|
|
|
|
|
#if (!$shared_hek and !$B::C::cow and IsCOW($sv)) { |
3236
|
|
|
|
|
|
|
# $flags &= ~SVf_IsCOW; |
3237
|
|
|
|
|
|
|
# warn sprintf("turn off SVf_IsCOW %s %s %s\n", $sym, cstring($pv), $fullname) |
3238
|
|
|
|
|
|
|
# if $debug{pv}; |
3239
|
|
|
|
|
|
|
#} |
3240
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3241
|
|
|
|
|
|
|
# static pv, do not destruct. test 13 with pv0 "3". |
3242
|
0
|
0
|
0
|
|
|
0
|
if ($B::C::const_strings and !$shared_hek and $flags & SVf_READONLY and !$len) { |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
3243
|
0
|
|
|
|
|
0
|
$flags &= ~0x01000000; |
3244
|
|
|
|
|
|
|
warn sprintf("constpv turn off SVf_FAKE %s %s %s\n", $sym, cstring($pv), $fullname) |
3245
|
0
|
0
|
|
|
|
0
|
if $debug{pv}; |
3246
|
|
|
|
|
|
|
} |
3247
|
0
|
0
|
0
|
|
|
0
|
$tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static |
3248
|
0
|
0
|
|
|
|
0
|
$xpvsect->comment( $PERL514 ? "stash, magic, cur, len" : "xnv_u, cur, len"); |
3249
|
0
|
0
|
|
|
|
0
|
$xpvsect->add( sprintf( "%s{0}, %u, %u", $PERL514 ? "Nullhv, " : "", $cur, $len ) ); |
3250
|
0
|
|
|
|
|
0
|
$svsect->comment( "any, refcnt, flags, sv_u" ); |
3251
|
0
|
0
|
|
|
|
0
|
$svsect->add( sprintf( "&xpv_list[%d], $u32fmt, 0x%x, {%s}", |
|
|
0
|
|
|
|
|
|
3252
|
|
|
|
|
|
|
$xpvsect->index, $refcnt, $flags, |
3253
|
|
|
|
|
|
|
$tmp_pvsym eq 'NULL' ? '0' : |
3254
|
|
|
|
|
|
|
($C99?".svu_pv=(char*)":"(char*)").$pvsym )); |
3255
|
0
|
|
|
|
|
0
|
$svix = $svsect->index; |
3256
|
0
|
0
|
0
|
|
|
0
|
if ( defined($pv) and !$static ) { |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
3257
|
0
|
0
|
|
|
|
0
|
if ($shared_hek) { |
3258
|
0
|
|
|
|
|
0
|
my $hek = save_hek($pv, $fullname, 1); |
3259
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "sv_list[%d].sv_u.svu_pv = HEK_KEY(%s);", $svix, $hek )) |
3260
|
|
|
|
|
|
|
unless $hek eq 'NULL'; |
3261
|
|
|
|
|
|
|
} else { |
3262
|
0
|
|
|
|
|
0
|
$init->add( savepvn( sprintf( "sv_list[%d].sv_u.svu_pv", $svix ), $pv, $sv, $cur ) ); |
3263
|
|
|
|
|
|
|
} |
3264
|
|
|
|
|
|
|
} elsif ($shared_hek and $static and $pvsym =~ /^hek/) { |
3265
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "sv_list[%d].sv_u.svu_pv = %s.hek_key;", $svix, $pvsym )); |
3266
|
|
|
|
|
|
|
} |
3267
|
0
|
0
|
0
|
|
|
0
|
if ($debug{flags} and (!$ITHREADS or $PERL514) and $DEBUG_LEAKING_SCALARS) { # add sv_debug_file |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
3268
|
0
|
0
|
|
|
|
0
|
$init->add(sprintf(qq(sv_list[%d].sv_debug_file = %s" sv_list[%d] 0x%x";), |
3269
|
|
|
|
|
|
|
$svix, cstring($pv) eq '0' ? '"NULL"' : cstring($pv), |
3270
|
|
|
|
|
|
|
$svix, $flags)); |
3271
|
|
|
|
|
|
|
} |
3272
|
|
|
|
|
|
|
} |
3273
|
|
|
|
|
|
|
else { |
3274
|
0
|
|
|
|
|
0
|
$xpvsect->comment( "pv, cur, len"); |
3275
|
0
|
|
|
|
|
0
|
$xpvsect->add(sprintf( "(char*)%s, %u, %u", $pvsym, $cur, $len ) ); |
3276
|
0
|
|
|
|
|
0
|
$svsect->comment( "any, refcnt, flags" ); |
3277
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf( "&xpv_list[%d], $u32fmt, 0x%x", |
3278
|
|
|
|
|
|
|
$xpvsect->index, $refcnt, $flags)); |
3279
|
0
|
|
|
|
|
0
|
$svix = $svsect->index; |
3280
|
0
|
0
|
0
|
|
|
0
|
if ( defined($pv) and !$static ) { |
3281
|
0
|
|
|
|
|
0
|
$init->add( savepvn( sprintf( "xpv_list[%d].xpv_pv", $xpvsect->index ), $pv, 0, $cur ) ); |
3282
|
|
|
|
|
|
|
} |
3283
|
|
|
|
|
|
|
} |
3284
|
0
|
|
|
|
|
0
|
my $s = "sv_list[$svix]"; |
3285
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
3286
|
0
|
0
|
0
|
|
|
0
|
push @B::C::static_free, "&".$s if $PERL518 and $flags & SVs_OBJECT; |
3287
|
0
|
|
|
|
|
0
|
savesym( $sv, "&".$s ); |
3288
|
|
|
|
|
|
|
} |
3289
|
|
|
|
|
|
|
|
3290
|
|
|
|
|
|
|
# 5.18-5.20 => PV::save, since 5.22 native using this method |
3291
|
|
|
|
|
|
|
sub B::PADNAME::save { |
3292
|
0
|
|
|
0
|
|
0
|
my ($pn, $fullname) = @_; |
3293
|
0
|
|
|
|
|
0
|
my $sym = objsym($pn); |
3294
|
0
|
0
|
|
|
|
0
|
if (defined $sym) { |
3295
|
0
|
0
|
|
|
|
0
|
if ($in_endav) { |
3296
|
0
|
0
|
|
|
|
0
|
warn "in_endav: static_free without $sym\n" if $debug{av}; |
3297
|
0
|
|
|
|
|
0
|
@B::C::static_free = grep {$_ ne $sym} @B::C::static_free; |
|
0
|
|
|
|
|
0
|
|
3298
|
|
|
|
|
|
|
} |
3299
|
0
|
|
|
|
|
0
|
return $sym; |
3300
|
|
|
|
|
|
|
} |
3301
|
0
|
|
|
|
|
0
|
my $flags = $pn->FLAGS; # U8 + FAKE if OUTER. OUTER,STATE,LVALUE,TYPED,OUR |
3302
|
0
|
|
|
|
|
0
|
$flags = $flags & 0xff; |
3303
|
0
|
|
|
|
|
0
|
my $gen = $pn->GEN; |
3304
|
0
|
|
|
|
|
0
|
my $stash = $pn->OURSTASH; |
3305
|
0
|
|
|
|
|
0
|
my $type = $pn->TYPE; |
3306
|
0
|
|
|
|
|
0
|
my $sn = $stash->save($fullname); |
3307
|
0
|
|
|
|
|
0
|
my $tn = $type->save($fullname); |
3308
|
0
|
|
|
|
|
0
|
my $refcnt = $pn->REFCNT; |
3309
|
0
|
0
|
|
|
|
0
|
$refcnt++ if $refcnt < 1000; # XXX protect from free, but allow SvREFCOUNT_IMMORTAL |
3310
|
0
|
|
|
|
|
0
|
my $str = $pn->PVX; |
3311
|
0
|
|
|
|
|
0
|
my $cstr = cstring($str); # a 5.22 padname is always utf8 |
3312
|
0
|
|
|
|
|
0
|
my $len = $pn->LEN; |
3313
|
0
|
|
|
|
|
0
|
my $alignedlen = 8*(int($len / 8)+1); # 5 -> 8, 9 -> 16 |
3314
|
0
|
|
|
|
|
0
|
my $struct_name = "my_padname_with_str_".$alignedlen; |
3315
|
0
|
|
|
|
|
0
|
my $pnsect = $padnamesect{$alignedlen}; |
3316
|
0
|
0
|
|
|
|
0
|
if (!$pnsect) { |
3317
|
0
|
|
|
|
|
0
|
my $name = "padname_$alignedlen"; |
3318
|
0
|
0
|
|
|
|
0
|
warn "dynamically created oversized $name section\n" if $verbose; |
3319
|
0
|
|
|
|
|
0
|
$padnamesect{$alignedlen} = new B::C::Section $name, \%symtable, 0; |
3320
|
|
|
|
|
|
|
} |
3321
|
0
|
|
|
|
|
0
|
my $ix = $pnsect->index + 1; |
3322
|
0
|
|
|
|
|
0
|
my $name = $pnsect->name; |
3323
|
0
|
|
|
|
|
0
|
my $s = "&".$name."_list[$ix]"; |
3324
|
|
|
|
|
|
|
# 5.22 needs the buffer to be at the end, and the pv pointing to it. |
3325
|
|
|
|
|
|
|
# We allocate a static buffer of different sizes. |
3326
|
0
|
|
|
|
|
0
|
$pnsect->comment( "pv, ourstash, type, low, high, refcnt, gen, len, flags, str"); |
3327
|
0
|
|
|
|
|
0
|
my $pnstr = "((char*)$s)+STRUCT_OFFSET(struct $struct_name, xpadn_str[0])"; |
3328
|
0
|
0
|
|
|
|
0
|
if (IS_MSVC) { |
3329
|
0
|
|
|
|
|
0
|
$pnstr = sprintf("((char*)$s)+%d", $Config{ptrsize} * 3 + 5); |
3330
|
|
|
|
|
|
|
} |
3331
|
0
|
0
|
0
|
|
|
0
|
$pnsect->add( sprintf |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
3332
|
|
|
|
|
|
|
( "%s, %s, {%s}, %u, %u, %s, %i, %u, 0x%x, %s", |
3333
|
|
|
|
|
|
|
($ix or $len) ? $pnstr : 'NULL', |
3334
|
|
|
|
|
|
|
is_constant($sn) ? "(HV*)$sn" : 'Nullhv', |
3335
|
|
|
|
|
|
|
is_constant($tn) ? "(HV*)$tn" : 'Nullhv', |
3336
|
|
|
|
|
|
|
$pn->COP_SEQ_RANGE_LOW, |
3337
|
|
|
|
|
|
|
$pn->COP_SEQ_RANGE_HIGH, |
3338
|
|
|
|
|
|
|
$refcnt >= 1000 ? sprintf("0x%x", $refcnt) : "$refcnt /* +1 */", |
3339
|
|
|
|
|
|
|
$gen, $len, $flags, $cstr)); |
3340
|
|
|
|
|
|
|
#if ( $len > 64 ) { |
3341
|
|
|
|
|
|
|
# Houston we have a problem, need to allocate this padname dynamically. Not done yet |
3342
|
|
|
|
|
|
|
# either dynamic or seperate structs per size MyPADNAME(5) |
3343
|
|
|
|
|
|
|
# die "Internal Error: Overlong name of lexical variable $cstr for $fullname [#229]"; |
3344
|
|
|
|
|
|
|
#} |
3345
|
0
|
0
|
|
|
|
0
|
$pnsect->debug( $fullname." ".$str, $pn->flagspv ) if $debug{flags}; |
3346
|
0
|
0
|
|
|
|
0
|
$init->add("SvOURSTASH_set($s, $sn);") unless is_constant($sn); |
3347
|
0
|
0
|
|
|
|
0
|
$init->add("PadnameTYPE($s) = (HV*)$tn;") unless is_constant($tn); |
3348
|
0
|
|
|
|
|
0
|
push @B::C::static_free, $s; |
3349
|
0
|
|
|
|
|
0
|
savesym( $pn, $s ); |
3350
|
|
|
|
|
|
|
} |
3351
|
|
|
|
|
|
|
|
3352
|
|
|
|
|
|
|
sub lexwarnsym { |
3353
|
0
|
|
|
0
|
0
|
0
|
my $pv = shift; |
3354
|
0
|
0
|
|
|
|
0
|
if ($lexwarnsym{$pv}) { |
3355
|
0
|
|
|
|
|
0
|
return @{$lexwarnsym{$pv}}; |
|
0
|
|
|
|
|
0
|
|
3356
|
|
|
|
|
|
|
} else { |
3357
|
0
|
|
|
|
|
0
|
my $sym = sprintf( "lexwarn%d", $pv_index++ ); |
3358
|
0
|
|
|
|
|
0
|
my ($cstring, $cur, $utf8) = strlen_flags($pv); |
3359
|
0
|
|
|
|
|
0
|
my $isint = 0; |
3360
|
0
|
0
|
|
|
|
0
|
if ($] < 5.009) { # need a SV->PV |
3361
|
0
|
|
|
|
|
0
|
$decl->add( sprintf( "Static SV* %s;", $sym )); |
3362
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "%s = newSVpvn(%s, %u);", $sym, $cstring, $cur)); |
3363
|
|
|
|
|
|
|
} else { |
3364
|
|
|
|
|
|
|
# if 8 use UVSIZE, if 4 use LONGSIZE |
3365
|
0
|
0
|
|
|
|
0
|
my $t = ($Config{longsize} == 8) ? "J" : "L"; |
3366
|
0
|
|
|
|
|
0
|
my ($iv) = unpack($t, $pv); # unsigned longsize |
3367
|
0
|
0
|
0
|
|
|
0
|
if ($iv >= 0 and $iv <= 2) { # specialWARN: single STRLEN |
3368
|
0
|
|
|
|
|
0
|
$decl->add( sprintf( "Static const STRLEN* %s = %d;", $sym, $iv )); |
3369
|
0
|
|
|
|
|
0
|
$isint = 1; |
3370
|
|
|
|
|
|
|
} else { # sizeof(STRLEN) + (WARNsize) |
3371
|
0
|
|
|
|
|
0
|
my $packedpv = pack("$t a*",length($pv), $pv); |
3372
|
0
|
|
|
|
|
0
|
$decl->add( sprintf( "Static const char %s[] = %s;", $sym, cstring($packedpv) )); |
3373
|
|
|
|
|
|
|
} |
3374
|
|
|
|
|
|
|
} |
3375
|
0
|
|
|
|
|
0
|
$lexwarnsym{$pv} = [$sym,$isint]; |
3376
|
0
|
|
|
|
|
0
|
return ($sym, $isint); |
3377
|
|
|
|
|
|
|
} |
3378
|
|
|
|
|
|
|
} |
3379
|
|
|
|
|
|
|
|
3380
|
|
|
|
|
|
|
# pre vs. post 5.8.9/5.9.4 logic for lexical warnings |
3381
|
|
|
|
|
|
|
@B::LEXWARN::ISA = qw(B::PV B::IV); |
3382
|
|
|
|
|
|
|
sub B::LEXWARN::save { |
3383
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
3384
|
0
|
0
|
|
|
|
0
|
my $pv = $] >= 5.008009 ? $sv->PV : $sv->IV; |
3385
|
0
|
|
|
|
|
0
|
return lexwarnsym($pv); # look for shared const int's |
3386
|
|
|
|
|
|
|
} |
3387
|
|
|
|
|
|
|
|
3388
|
|
|
|
|
|
|
# post 5.11: When called from save_rv not from PMOP::save precomp |
3389
|
|
|
|
|
|
|
sub B::REGEXP::save { |
3390
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
3391
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
3392
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
3393
|
0
|
|
|
|
|
0
|
my $pv = $sv->PV; |
3394
|
0
|
|
|
|
|
0
|
my $cur = $sv->CUR; |
3395
|
|
|
|
|
|
|
# construct original PV |
3396
|
0
|
|
|
|
|
0
|
$pv =~ s/^(\(\?\^[adluimsx-]*\:)(.*)\)$/$2/; |
3397
|
0
|
|
|
|
|
0
|
$cur -= length($sv->PV) - length($pv); |
3398
|
0
|
|
|
|
|
0
|
my $cstr = cstring($pv); |
3399
|
|
|
|
|
|
|
# Unfortunately this XPV is needed temp. Later replaced by struct regexp. |
3400
|
0
|
0
|
|
|
|
0
|
$xpvsect->add( sprintf( "%s{0}, %u, %u", $PERL514 ? "Nullhv, " : "", $cur, 0 ) ); |
3401
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf("&xpv_list[%d], $u32fmt, 0x%x, {%s}", |
3402
|
|
|
|
|
|
|
$xpvsect->index, $sv->REFCNT, $sv->FLAGS, $] > 5.017006 ? "NULL" : $cstr)); |
3403
|
0
|
|
|
|
|
0
|
my $ix = $svsect->index; |
3404
|
0
|
0
|
0
|
|
|
0
|
warn "Saving RX $cstr to sv_list[$ix]\n" if $debug{rx} or $debug{sv}; |
3405
|
0
|
0
|
|
|
|
0
|
if ($] > 5.011) { |
3406
|
0
|
0
|
|
|
|
0
|
my $pmflags = $PERL522 ? $sv->compflags : $sv->EXTFLAGS; |
3407
|
0
|
0
|
|
|
|
0
|
my $initpm = re_does_swash($cstr, $pmflags) ? $init1 : $init; |
3408
|
0
|
0
|
0
|
|
|
0
|
if ($PERL518 and $sv->EXTFLAGS & RXf_EVAL_SEEN) { |
3409
|
0
|
|
|
|
|
0
|
$initpm->add("PL_hints |= HINT_RE_EVAL;"); |
3410
|
|
|
|
|
|
|
} |
3411
|
|
|
|
|
|
|
$initpm->add(# replace sv_any->XPV with struct regexp. need pv and extflags |
3412
|
0
|
|
|
|
|
0
|
sprintf("SvANY(&sv_list[%d]) = SvANY(CALLREGCOMP(newSVpvn(%s, %d), 0x%x));", |
3413
|
|
|
|
|
|
|
$ix, $cstr, $cur, $pmflags)); |
3414
|
0
|
0
|
0
|
|
|
0
|
if ($PERL518 and $sv->EXTFLAGS & RXf_EVAL_SEEN) { |
3415
|
0
|
|
|
|
|
0
|
$initpm->add("PL_hints &= ~HINT_RE_EVAL;"); |
3416
|
|
|
|
|
|
|
} |
3417
|
|
|
|
|
|
|
} |
3418
|
0
|
0
|
|
|
|
0
|
if ($] < 5.017006) { |
3419
|
|
|
|
|
|
|
# since 5.17.6 the SvLEN stores RX_WRAPPED(rx) |
3420
|
0
|
|
|
|
|
0
|
$init->add(sprintf("SvCUR(&sv_list[%d]) = %d;", $ix, $cur), |
3421
|
|
|
|
|
|
|
"SvLEN(&sv_list[$ix]) = 0;"); |
3422
|
|
|
|
|
|
|
} else { |
3423
|
0
|
|
|
|
|
0
|
$init->add("sv_list[$ix].sv_u.svu_rx = (struct regexp*)sv_list[$ix].sv_any;"); |
3424
|
|
|
|
|
|
|
} |
3425
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
3426
|
0
|
|
|
|
|
0
|
$sym = savesym( $sv, sprintf( "&sv_list[%d]", $ix ) ); |
3427
|
0
|
|
|
|
|
0
|
$sv->save_magic($fullname); |
3428
|
0
|
|
|
|
|
0
|
return $sym; |
3429
|
|
|
|
|
|
|
} |
3430
|
|
|
|
|
|
|
|
3431
|
|
|
|
|
|
|
sub save_remap { |
3432
|
0
|
|
|
0
|
0
|
0
|
my ($key, $pkg, $name, $ivx, $mandatory) = @_; |
3433
|
0
|
|
|
|
|
0
|
my $id = $xpvmgsect->index + 1; |
3434
|
|
|
|
|
|
|
#my $svid = $svsect->index + 1; |
3435
|
0
|
0
|
|
|
|
0
|
warn "init remap for $key\: $name $ivx in xpvmg_list[$id]\n" if $verbose; |
3436
|
0
|
|
|
|
|
0
|
my $props = { NAME => $name, ID => $id, MANDATORY => $mandatory }; |
3437
|
0
|
0
|
|
|
|
0
|
$init2_remap{$key}{MG} = [] unless $init2_remap{$key}{'MG'}; |
3438
|
0
|
|
|
|
|
0
|
push @{$init2_remap{$key}{MG}}, $props; |
|
0
|
|
|
|
|
0
|
|
3439
|
|
|
|
|
|
|
} |
3440
|
|
|
|
|
|
|
|
3441
|
|
|
|
|
|
|
sub patch_dlsym { |
3442
|
0
|
|
|
0
|
0
|
0
|
my ($sv, $fullname, $ivx) = @_; |
3443
|
0
|
|
|
|
|
0
|
my $pkg = ''; |
3444
|
0
|
0
|
|
|
|
0
|
if (ref($sv) eq 'B::PVMG') { |
3445
|
0
|
|
|
|
|
0
|
my $stash = $sv->SvSTASH; |
3446
|
0
|
0
|
|
|
|
0
|
$pkg = $stash->can('NAME') ? $stash->NAME : ''; |
3447
|
|
|
|
|
|
|
} |
3448
|
0
|
0
|
|
|
|
0
|
my $name = $sv->FLAGS & SVp_POK ? $sv->PVX : ""; |
3449
|
0
|
|
|
|
|
0
|
my $ivx_s = $ivx; |
3450
|
0
|
|
|
|
|
0
|
$ivx_s =~ s/U?L?$//g; |
3451
|
0
|
|
|
|
|
0
|
my $ivxhex = sprintf("0x%x", $ivx_s); |
3452
|
|
|
|
|
|
|
# Encode RT #94221 |
3453
|
0
|
0
|
0
|
|
|
0
|
if ($name =~ /encoding$/ and $name =~ /^(ascii|ascii_ctrl|iso8859_1|null)/ and $Encode::VERSION eq '2.58') { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
3454
|
0
|
|
|
|
|
0
|
$name =~ s/-/_/g; |
3455
|
0
|
0
|
|
|
|
0
|
$pkg = 'Encode' if $pkg eq 'Encode::XS'; # TODO foreign classes |
3456
|
0
|
0
|
0
|
|
|
0
|
mark_package($pkg) if $fullname eq '(unknown)' and $ITHREADS; |
3457
|
0
|
0
|
|
|
|
0
|
warn "$pkg $Encode::VERSION with remap support for $name\n" if $verbose; |
3458
|
|
|
|
|
|
|
} |
3459
|
|
|
|
|
|
|
elsif ($pkg eq 'Encode::XS') { |
3460
|
0
|
|
|
|
|
0
|
$pkg = 'Encode'; |
3461
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'Encode::Encoding{iso-8859-1}') { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
3462
|
0
|
|
|
|
|
0
|
$name = "iso8859_1_encoding"; |
3463
|
|
|
|
|
|
|
} |
3464
|
|
|
|
|
|
|
elsif ($fullname eq 'Encode::Encoding{null}') { |
3465
|
0
|
|
|
|
|
0
|
$name = "null_encoding"; |
3466
|
|
|
|
|
|
|
} |
3467
|
|
|
|
|
|
|
elsif ($fullname eq 'Encode::Encoding{ascii-ctrl}') { |
3468
|
0
|
|
|
|
|
0
|
$name = "ascii_ctrl_encoding"; |
3469
|
|
|
|
|
|
|
} |
3470
|
|
|
|
|
|
|
elsif ($fullname eq 'Encode::Encoding{ascii}') { |
3471
|
0
|
|
|
|
|
0
|
$name = "ascii_encoding"; |
3472
|
|
|
|
|
|
|
} |
3473
|
|
|
|
|
|
|
|
3474
|
0
|
0
|
0
|
|
|
0
|
if ($name and $name =~ /^(ascii|ascii_ctrl|iso8859_1|null)/ and $Encode::VERSION gt '2.58') { |
|
|
|
0
|
|
|
|
|
3475
|
0
|
|
|
|
|
0
|
my $enc = Encode::find_encoding($name); |
3476
|
0
|
0
|
|
|
|
0
|
$name .= "_encoding" unless $name =~ /_encoding$/; |
3477
|
0
|
|
|
|
|
0
|
$name =~ s/-/_/g; |
3478
|
0
|
0
|
|
|
|
0
|
warn "$pkg $Encode::VERSION with remap support for $name (find 1)\n" if $verbose; |
3479
|
0
|
|
|
|
|
0
|
mark_package($pkg); |
3480
|
0
|
0
|
|
|
|
0
|
if ($pkg ne 'Encode') { |
3481
|
0
|
|
|
|
|
0
|
svref_2object( \&{"$pkg\::bootstrap"} )->save; |
|
0
|
|
|
|
|
0
|
|
3482
|
0
|
|
|
|
|
0
|
mark_package('Encode'); |
3483
|
|
|
|
|
|
|
} |
3484
|
|
|
|
|
|
|
} |
3485
|
|
|
|
|
|
|
else { |
3486
|
0
|
|
|
|
|
0
|
for my $n (Encode::encodings()) { # >=5.16 constsub without name |
3487
|
0
|
|
|
|
|
0
|
my $enc = Encode::find_encoding($n); |
3488
|
0
|
0
|
0
|
|
|
0
|
if ($enc and ref($enc) ne 'Encode::XS') { # resolve alias such as Encode::JP::JIS7=HASH(0x292a9d0) |
3489
|
0
|
|
|
|
|
0
|
$pkg = ref($enc); |
3490
|
0
|
|
|
|
|
0
|
$pkg =~ s/^(Encode::\w+)(::.*)/$1/; # collapse to the @dl_module name |
3491
|
0
|
|
|
|
|
0
|
$enc = Encode->find_alias($n); |
3492
|
|
|
|
|
|
|
} |
3493
|
0
|
0
|
0
|
|
|
0
|
if ($enc and ref($enc) eq 'Encode::XS' and $sv->IVX == $$enc) { |
|
|
|
0
|
|
|
|
|
3494
|
0
|
|
|
|
|
0
|
$name = $n; |
3495
|
0
|
|
|
|
|
0
|
$name =~ s/-/_/g; |
3496
|
0
|
0
|
|
|
|
0
|
$name .= "_encoding" if $name !~ /_encoding$/; |
3497
|
0
|
|
|
|
|
0
|
mark_package($pkg) ; |
3498
|
0
|
0
|
|
|
|
0
|
if ($pkg ne 'Encode') { |
3499
|
0
|
|
|
|
|
0
|
svref_2object( \&{"$pkg\::bootstrap"} )->save; |
|
0
|
|
|
|
|
0
|
|
3500
|
0
|
|
|
|
|
0
|
mark_package('Encode'); |
3501
|
|
|
|
|
|
|
} |
3502
|
0
|
|
|
|
|
0
|
last; |
3503
|
|
|
|
|
|
|
} |
3504
|
|
|
|
|
|
|
} |
3505
|
0
|
0
|
|
|
|
0
|
if ($name) { |
3506
|
0
|
0
|
|
|
|
0
|
warn "$pkg $Encode::VERSION remap found for constant $name\n" if $verbose; |
3507
|
|
|
|
|
|
|
} else { |
3508
|
0
|
|
|
|
|
0
|
warn "Warning: Possible missing remap for compile-time XS symbol in $pkg $fullname $ivxhex [#305]\n"; |
3509
|
|
|
|
|
|
|
} |
3510
|
|
|
|
|
|
|
} |
3511
|
|
|
|
|
|
|
} |
3512
|
|
|
|
|
|
|
# Encode-2.59 uses a different name without _encoding |
3513
|
|
|
|
|
|
|
elsif ($Encode::VERSION ge '2.58' and Encode::find_encoding($name)) { |
3514
|
0
|
|
|
|
|
0
|
my $enc = Encode::find_encoding($name); |
3515
|
0
|
0
|
|
|
|
0
|
$pkg = ref($enc) if ref($enc) ne 'Encode::XS'; |
3516
|
0
|
|
|
|
|
0
|
$name .= "_encoding"; |
3517
|
0
|
|
|
|
|
0
|
$name =~ s/-/_/g; |
3518
|
0
|
0
|
|
|
|
0
|
$pkg = 'Encode' unless $pkg; |
3519
|
0
|
0
|
|
|
|
0
|
warn "$pkg $Encode::VERSION with remap support for $name (find 2)\n" if $verbose; |
3520
|
|
|
|
|
|
|
} |
3521
|
|
|
|
|
|
|
# now that is a weak heuristic, which misses #305 |
3522
|
|
|
|
|
|
|
elsif (defined ($Net::DNS::VERSION) |
3523
|
|
|
|
|
|
|
and $Net::DNS::VERSION =~ /^0\.(6[789]|7[1234])/) { |
3524
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'svop const') { |
3525
|
0
|
|
|
|
|
0
|
$name = "ascii_encoding"; |
3526
|
0
|
0
|
|
|
|
0
|
$pkg = 'Encode' unless $pkg; |
3527
|
0
|
|
|
|
|
0
|
warn "Warning: Patch Net::DNS external XS symbol $pkg\::$name $ivxhex [RT #94069]\n"; |
3528
|
|
|
|
|
|
|
} |
3529
|
|
|
|
|
|
|
} |
3530
|
|
|
|
|
|
|
elsif ($pkg eq 'Net::LibIDN') { |
3531
|
0
|
|
|
|
|
0
|
$name = "idn_to_ascii"; # ?? |
3532
|
|
|
|
|
|
|
} |
3533
|
|
|
|
|
|
|
|
3534
|
|
|
|
|
|
|
# new API (only Encode so far) |
3535
|
0
|
0
|
0
|
|
|
0
|
if ($pkg and $name and $name =~ /^[a-zA-Z_0-9-]+$/) { # valid symbol name |
|
|
|
0
|
|
|
|
|
3536
|
0
|
0
|
|
|
|
0
|
warn "Remap IOK|POK $pkg with $name\n" if $verbose; |
3537
|
0
|
|
|
|
|
0
|
save_remap($pkg, $pkg, $name, $ivxhex, 0); |
3538
|
0
|
|
|
|
|
0
|
$ivx = "0UL /* $ivxhex => $name */"; |
3539
|
0
|
0
|
|
|
|
0
|
mark_package($pkg, 1) if $fullname =~ /^(svop const|padop)/; |
3540
|
|
|
|
|
|
|
} |
3541
|
|
|
|
|
|
|
else { |
3542
|
0
|
|
|
|
|
0
|
warn "Warning: Possible missing remap for compile-time XS symbol in $pkg $fullname $ivxhex [#305]\n"; |
3543
|
|
|
|
|
|
|
} |
3544
|
0
|
|
|
|
|
0
|
return $ivx; |
3545
|
|
|
|
|
|
|
} |
3546
|
|
|
|
|
|
|
|
3547
|
|
|
|
|
|
|
sub B::PVMG::save { |
3548
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
3549
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
3550
|
0
|
0
|
|
|
|
0
|
if (defined $sym) { |
3551
|
0
|
0
|
|
|
|
0
|
if ($in_endav) { |
3552
|
0
|
0
|
|
|
|
0
|
warn "in_endav: static_free without $sym\n" if $debug{av}; |
3553
|
0
|
|
|
|
|
0
|
@B::C::static_free = grep {$_ ne $sym} @B::C::static_free; |
|
0
|
|
|
|
|
0
|
|
3554
|
|
|
|
|
|
|
} |
3555
|
0
|
|
|
|
|
0
|
return $sym; |
3556
|
|
|
|
|
|
|
} |
3557
|
0
|
|
|
|
|
0
|
my ( $pvsym, $cur, $len, $pv, $static, $flags ) = save_pv_or_rv($sv, $fullname); |
3558
|
|
|
|
|
|
|
#warn sprintf( "PVMG %s (0x%x) $pvsym, $len, $cur, $pv\n", $sym, $$sv ) if $debug{mg}; |
3559
|
|
|
|
|
|
|
|
3560
|
0
|
|
|
|
|
0
|
my ($ivx,$nvx); |
3561
|
|
|
|
|
|
|
# since 5.11 REGEXP isa PVMG, but has no IVX and NVX methods |
3562
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.011 and ref($sv) eq 'B::REGEXP') { |
3563
|
0
|
|
|
|
|
0
|
return B::REGEXP::save($sv, $fullname); |
3564
|
|
|
|
|
|
|
} |
3565
|
|
|
|
|
|
|
else { |
3566
|
0
|
|
|
|
|
0
|
$ivx = ivx($sv->IVX); # XXX How to detect HEK* namehek? |
3567
|
0
|
|
|
|
|
0
|
$nvx = nvx($sv->NVX); # it cannot be xnv_u.xgv_stash ptr (BTW set by GvSTASH later) |
3568
|
|
|
|
|
|
|
|
3569
|
|
|
|
|
|
|
# See #305 Encode::XS: XS objects are often stored as SvIV(SvRV(obj)). The real |
3570
|
|
|
|
|
|
|
# address needs to be patched after the XS object is initialized. |
3571
|
|
|
|
|
|
|
# But how detect them properly? |
3572
|
|
|
|
|
|
|
# Detect ptr to extern symbol in shared library and remap it in init2 |
3573
|
|
|
|
|
|
|
# Safe and mandatory currently only Net-DNS-0.67 - 0.74. |
3574
|
|
|
|
|
|
|
# svop const or pad OBJECT,IOK |
3575
|
0
|
0
|
0
|
|
|
0
|
if (((!$ITHREADS |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
3576
|
|
|
|
|
|
|
and $fullname |
3577
|
|
|
|
|
|
|
and $fullname =~ /^svop const|^padop|^Encode::Encoding| :pad\[1\]/) |
3578
|
|
|
|
|
|
|
or $ITHREADS) |
3579
|
|
|
|
|
|
|
and $sv->IVX > LOWEST_IMAGEBASE # some crazy heuristic for a sharedlibrary ptr in .data (> image_base) |
3580
|
|
|
|
|
|
|
and ref($sv->SvSTASH) ne 'B::SPECIAL') |
3581
|
|
|
|
|
|
|
{ |
3582
|
0
|
|
|
|
|
0
|
$ivx = patch_dlsym($sv, $fullname, $ivx); |
3583
|
|
|
|
|
|
|
} |
3584
|
|
|
|
|
|
|
} |
3585
|
|
|
|
|
|
|
|
3586
|
0
|
|
|
|
|
0
|
my $tmp_pvsym = $pvsym; |
3587
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3588
|
0
|
0
|
|
|
|
0
|
if ($sv->FLAGS & SVf_ROK) { # sv => sv->RV cannot be initialized static. |
3589
|
0
|
0
|
|
|
|
0
|
$init->add(sprintf("SvRV_set(&sv_list[%d], (SV*)%s);", $svsect->index+1, $pvsym)) |
3590
|
|
|
|
|
|
|
if $pvsym ne ''; |
3591
|
0
|
|
|
|
|
0
|
$pvsym = 'NULL'; |
3592
|
0
|
|
|
|
|
0
|
$static = 1; |
3593
|
|
|
|
|
|
|
} |
3594
|
0
|
0
|
|
|
|
0
|
if ($PERL514) { |
3595
|
0
|
0
|
0
|
|
|
0
|
$tmp_pvsym = 'NULL' if $tmp_pvsym =~ /^hek/ and $static; # cannot init static |
3596
|
0
|
|
|
|
|
0
|
$xpvmgsect->comment("STASH, MAGIC, cur, len, xiv_u, xnv_u"); |
3597
|
0
|
|
|
|
|
0
|
$xpvmgsect->add(sprintf("Nullhv, {0}, %u, %u, {%s}, {%s}", |
3598
|
|
|
|
|
|
|
$cur, $len, $ivx, $nvx)); |
3599
|
|
|
|
|
|
|
} else { |
3600
|
0
|
|
|
|
|
0
|
$xpvmgsect->comment("xnv_u, cur, len, xiv_u, xmg_u, xmg_stash"); |
3601
|
0
|
|
|
|
|
0
|
$xpvmgsect->add(sprintf("{%s}, %u, %u, {%s}, {0}, Nullhv", |
3602
|
|
|
|
|
|
|
$nvx, $cur, $len, $ivx)); |
3603
|
|
|
|
|
|
|
} |
3604
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf("&xpvmg_list[%d], $u32fmt, 0x%x, {%s}", |
|
|
0
|
|
|
|
|
|
3605
|
|
|
|
|
|
|
$xpvmgsect->index, $sv->REFCNT, $flags, |
3606
|
|
|
|
|
|
|
$tmp_pvsym eq 'NULL' ? '0' : |
3607
|
|
|
|
|
|
|
($C99?".svu_pv=(char*)":"(char*)").$tmp_pvsym)); |
3608
|
|
|
|
|
|
|
} |
3609
|
|
|
|
|
|
|
else { |
3610
|
0
|
0
|
0
|
|
|
0
|
if ($pvsym =~ /PL_sv_undef/ and $ITHREADS) { |
3611
|
0
|
|
|
|
|
0
|
$pvsym = 'NULL'; # Moose 5.8.9d |
3612
|
|
|
|
|
|
|
} |
3613
|
0
|
|
|
|
|
0
|
$xpvmgsect->add(sprintf("(char*)%s, %u, %u, %s, %s, 0, 0", |
3614
|
|
|
|
|
|
|
$pvsym, $cur, $len, $ivx, $nvx)); |
3615
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvmg_list[%d], $u32fmt, 0x%x", |
3616
|
|
|
|
|
|
|
$xpvmgsect->index, $sv->REFCNT, $flags)); |
3617
|
|
|
|
|
|
|
} |
3618
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
3619
|
0
|
|
|
|
|
0
|
my $s = "sv_list[".$svsect->index."]"; |
3620
|
0
|
0
|
0
|
|
|
0
|
if ( !$static ) { # do not overwrite RV slot (#273) |
|
|
0
|
|
|
|
|
|
3621
|
|
|
|
|
|
|
# XXX comppadnames need &PL_sv_undef instead of 0 (?? which testcase?) |
3622
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3623
|
0
|
|
|
|
|
0
|
$init->add( savepvn( "$s.sv_u.svu_pv", $pv, $sv, $cur ) ); |
3624
|
|
|
|
|
|
|
} else { |
3625
|
0
|
|
|
|
|
0
|
$init->add( savepvn( sprintf( "xpvmg_list[%d].xpv_pv", $xpvmgsect->index ), |
3626
|
|
|
|
|
|
|
$pv, $sv, $cur ) ); |
3627
|
|
|
|
|
|
|
} |
3628
|
|
|
|
|
|
|
} elsif ($tmp_pvsym eq 'NULL' and $pvsym =~ /^hek/) { |
3629
|
0
|
|
|
|
|
0
|
$init->add( sprintf("%s.sv_u.svu_pv = %s.hek_key;", $s, $pvsym )); |
3630
|
|
|
|
|
|
|
} |
3631
|
0
|
|
|
|
|
0
|
$sym = savesym( $sv, "&".$s ); |
3632
|
0
|
|
|
|
|
0
|
$sv->save_magic($fullname); |
3633
|
0
|
|
|
|
|
0
|
return $sym; |
3634
|
|
|
|
|
|
|
} |
3635
|
|
|
|
|
|
|
|
3636
|
|
|
|
|
|
|
# mark threads::shared to be xs-loaded |
3637
|
|
|
|
|
|
|
sub mark_threads { |
3638
|
0
|
0
|
|
0
|
0
|
0
|
if ( $INC{'threads.pm'} ) { |
3639
|
0
|
|
|
|
|
0
|
my $stash = 'threads'; |
3640
|
0
|
|
|
|
|
0
|
mark_package($stash); |
3641
|
0
|
|
|
|
|
0
|
$use_xsloader = 1; |
3642
|
0
|
|
|
|
|
0
|
$xsub{$stash} = 'Dynamic-' . $INC{'threads.pm'}; |
3643
|
0
|
0
|
|
|
|
0
|
warn "mark threads for 'P' magic\n" if $debug{mg}; |
3644
|
|
|
|
|
|
|
} else { |
3645
|
0
|
0
|
|
|
|
0
|
warn "ignore to mark threads for 'P' magic\n" if $debug{mg}; |
3646
|
|
|
|
|
|
|
} |
3647
|
0
|
0
|
|
|
|
0
|
if ( $INC{'threads/shared.pm'} ) { |
3648
|
0
|
|
|
|
|
0
|
my $stash = 'threads::shared'; |
3649
|
0
|
|
|
|
|
0
|
mark_package($stash); |
3650
|
|
|
|
|
|
|
# XXX why is this needed? threads::shared should be initialized automatically |
3651
|
0
|
|
|
|
|
0
|
$use_xsloader = 1; # ensure threads::shared is initialized |
3652
|
0
|
|
|
|
|
0
|
$xsub{$stash} = 'Dynamic-' . $INC{'threads/shared.pm'}; |
3653
|
0
|
0
|
|
|
|
0
|
warn "mark threads::shared for 'P' magic\n" if $debug{mg}; |
3654
|
|
|
|
|
|
|
} else { |
3655
|
0
|
0
|
|
|
|
0
|
warn "ignore to mark threads::shared for 'P' magic\n" if $debug{mg}; |
3656
|
|
|
|
|
|
|
} |
3657
|
|
|
|
|
|
|
} |
3658
|
|
|
|
|
|
|
|
3659
|
|
|
|
|
|
|
sub B::PVMG::save_magic { |
3660
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
3661
|
0
|
|
|
|
|
0
|
my $sv_flags = $sv->FLAGS; |
3662
|
0
|
|
|
|
|
0
|
my $pkg; |
3663
|
0
|
0
|
0
|
|
|
0
|
return if $fullname and $fullname eq '%B::C::'; |
3664
|
0
|
0
|
|
|
|
0
|
if ($debug{mg}) { |
3665
|
0
|
|
|
|
|
0
|
my $flagspv = ""; |
3666
|
0
|
0
|
|
|
|
0
|
$fullname = '' unless $fullname; |
3667
|
0
|
0
|
0
|
|
|
0
|
$flagspv = $sv->flagspv if $debug{flags} and $PERL510 and !$sv->MAGICAL; |
|
|
|
0
|
|
|
|
|
3668
|
|
|
|
|
|
|
warn sprintf( "saving magic for %s %s (0x%x) flags=0x%x%s - called from %s:%s\n", |
3669
|
|
|
|
|
|
|
B::class($sv), $fullname, $$sv, $sv_flags, $debug{flags} ? "(".$flagspv.")" : "", |
3670
|
0
|
0
|
|
|
|
0
|
@{[(caller(1))[3]]}, @{[(caller(1))[2]]}); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
3671
|
|
|
|
|
|
|
} |
3672
|
|
|
|
|
|
|
|
3673
|
|
|
|
|
|
|
# crashes on STASH=0x18 with HV PERL_MAGIC_overload_table stash %version:: flags=0x3280000c |
3674
|
|
|
|
|
|
|
# issue267 GetOpt::Long SVf_AMAGIC|SVs_RMG|SVf_OOK |
3675
|
|
|
|
|
|
|
# crashes with %Class::MOP::Instance:: flags=0x2280000c also |
3676
|
0
|
0
|
0
|
|
|
0
|
if (ref($sv) eq 'B::HV' and $] > 5.018 and $sv->MAGICAL and $fullname =~ /::$/) { |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
3677
|
0
|
0
|
|
|
|
0
|
warn sprintf("skip SvSTASH for overloaded HV %s flags=0x%x\n", $fullname, $sv_flags) |
3678
|
|
|
|
|
|
|
if $verbose; |
3679
|
|
|
|
|
|
|
# [cperl #60] not only overloaded, version also |
3680
|
|
|
|
|
|
|
} elsif (ref($sv) eq 'B::HV' and $] > 5.018 and $fullname =~ /(version|File)::$/) { |
3681
|
0
|
0
|
|
|
|
0
|
warn sprintf("skip SvSTASH for %s flags=0x%x\n", $fullname, $sv_flags) |
3682
|
|
|
|
|
|
|
if $verbose; |
3683
|
|
|
|
|
|
|
} else { |
3684
|
0
|
|
|
|
|
0
|
my $pkgsym; |
3685
|
0
|
|
|
|
|
0
|
$pkg = $sv->SvSTASH; |
3686
|
0
|
0
|
0
|
|
|
0
|
if ($pkg and $$pkg) { |
3687
|
0
|
0
|
|
|
|
0
|
my $pkgname = $pkg->can('NAME') ? $pkg->NAME : $pkg->NAME_HEK."::DESTROY"; |
3688
|
|
|
|
|
|
|
warn sprintf("stash isa class \"%s\" (%s)\n", $pkgname, ref $pkg) |
3689
|
0
|
0
|
0
|
|
|
0
|
if $debug{mg} or $debug{gv}; |
3690
|
|
|
|
|
|
|
# 361 do not force dynaloading IO via IO::Handle upon us |
3691
|
|
|
|
|
|
|
# core already initialized this stash for us |
3692
|
0
|
0
|
0
|
|
|
0
|
unless ($fullname eq 'main::STDOUT' and $] >= 5.018) { |
3693
|
0
|
0
|
|
|
|
0
|
if (ref $pkg eq 'B::HV') { |
3694
|
0
|
0
|
0
|
|
|
0
|
if ($fullname !~ /::$/ or $B::C::stash) { |
3695
|
0
|
|
|
|
|
0
|
$pkgsym = $pkg->save($fullname); |
3696
|
|
|
|
|
|
|
} else { |
3697
|
0
|
|
|
|
|
0
|
$pkgsym = savestashpv($pkgname); |
3698
|
|
|
|
|
|
|
} |
3699
|
|
|
|
|
|
|
} else { |
3700
|
0
|
|
|
|
|
0
|
$pkgsym = 'NULL'; |
3701
|
|
|
|
|
|
|
} |
3702
|
|
|
|
|
|
|
|
3703
|
|
|
|
|
|
|
warn sprintf( "xmg_stash = \"%s\" as %s\n", $pkgname, $pkgsym ) |
3704
|
0
|
0
|
0
|
|
|
0
|
if $debug{mg} or $debug{gv}; |
3705
|
|
|
|
|
|
|
# Q: Who is initializing our stash from XS? ->save is missing that. |
3706
|
|
|
|
|
|
|
# A: We only need to init it when we need a CV |
3707
|
|
|
|
|
|
|
# defer for XS loaded stashes with AMT magic |
3708
|
0
|
0
|
|
|
|
0
|
if (ref $pkg eq 'B::HV') { |
3709
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "SvSTASH_set(s\\_%x, (HV*)s\\_%x);", $$sv, $$pkg ) ); |
3710
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "SvREFCNT((SV*)s\\_%x) += 1;", $$pkg ) ); |
3711
|
0
|
0
|
|
|
|
0
|
$init->add("++PL_sv_objcount;") unless ref($sv) eq "B::IO"; |
3712
|
|
|
|
|
|
|
# XXX |
3713
|
|
|
|
|
|
|
#push_package($pkg->NAME); # correct code, but adds lots of new stashes |
3714
|
|
|
|
|
|
|
} |
3715
|
|
|
|
|
|
|
} |
3716
|
|
|
|
|
|
|
} |
3717
|
|
|
|
|
|
|
} |
3718
|
0
|
0
|
0
|
|
|
0
|
$init->add(sprintf("SvREADONLY_off((SV*)s\\_%x);", $$sv)) |
3719
|
|
|
|
|
|
|
if $sv_flags & SVf_READONLY and ref($sv) ne 'B::HV'; |
3720
|
|
|
|
|
|
|
|
3721
|
|
|
|
|
|
|
# Protect our SVs against non-magic or SvPAD_OUR. Fixes tests 16 and 14 + 23 |
3722
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and !($sv->MAGICAL or $sv_flags & SVf_AMAGIC)) { |
|
|
|
0
|
|
|
|
|
3723
|
|
|
|
|
|
|
warn sprintf("Skipping non-magical PVMG type=%d, flags=0x%x%s\n", |
3724
|
|
|
|
|
|
|
$sv_flags && 0xff, $sv_flags, $debug{flags} ? "(".$sv->flagspv.")" : "") |
3725
|
0
|
0
|
0
|
|
|
0
|
if $debug{mg}; |
|
|
0
|
|
|
|
|
|
3726
|
0
|
|
|
|
|
0
|
return ''; |
3727
|
|
|
|
|
|
|
} |
3728
|
|
|
|
|
|
|
|
3729
|
|
|
|
|
|
|
# disabled. testcase: t/testm.sh Path::Class |
3730
|
0
|
|
|
|
|
0
|
if (0 and $PERL518 and $sv_flags & SVf_AMAGIC) { |
3731
|
|
|
|
|
|
|
my $name = $fullname; |
3732
|
|
|
|
|
|
|
$name =~ s/^%(.*)::$/$1/; |
3733
|
|
|
|
|
|
|
$name = $pkg->NAME if $pkg and $$pkg; |
3734
|
|
|
|
|
|
|
warn sprintf("initialize overload cache for %s\n", $fullname ) |
3735
|
|
|
|
|
|
|
if $debug{mg} or $debug{gv}; |
3736
|
|
|
|
|
|
|
# This is destructive, it removes the magic instead of adding it. |
3737
|
|
|
|
|
|
|
#$init1->add(sprintf("Gv_AMG(%s); /* init overload cache for %s */", savestashpv($name), |
3738
|
|
|
|
|
|
|
# $fullname)); |
3739
|
|
|
|
|
|
|
} |
3740
|
|
|
|
|
|
|
|
3741
|
0
|
|
|
|
|
0
|
my @mgchain = $sv->MAGIC; |
3742
|
0
|
|
|
|
|
0
|
my ( $mg, $type, $obj, $ptr, $len, $ptrsv ); |
3743
|
0
|
|
|
|
|
0
|
my $magic = ''; |
3744
|
0
|
|
|
|
|
0
|
foreach $mg (@mgchain) { |
3745
|
0
|
|
|
|
|
0
|
$type = $mg->TYPE; |
3746
|
0
|
|
|
|
|
0
|
$ptr = $mg->PTR; |
3747
|
0
|
|
|
|
|
0
|
$len = $mg->LENGTH; |
3748
|
0
|
|
|
|
|
0
|
$magic .= $type; |
3749
|
0
|
0
|
|
|
|
0
|
if ( $debug{mg} ) { |
3750
|
0
|
|
|
|
|
0
|
warn sprintf( "%s %s magic 0x%x\n", $fullname, cchar($type), $mg->FLAGS ); |
3751
|
|
|
|
|
|
|
#eval { |
3752
|
|
|
|
|
|
|
# warn sprintf( "magic %s (0x%x), obj %s (0x%x), type %s, ptr %s\n", |
3753
|
|
|
|
|
|
|
# B::class($sv), $$sv, B::class($obj), $$obj, cchar($type), |
3754
|
|
|
|
|
|
|
# cstring($ptr) ); |
3755
|
|
|
|
|
|
|
#}; |
3756
|
|
|
|
|
|
|
} |
3757
|
|
|
|
|
|
|
|
3758
|
0
|
0
|
|
|
|
0
|
unless ( $type =~ /^[rDn]$/ ) { # r - test 23 / D - Getopt::Long |
3759
|
|
|
|
|
|
|
# 5.10: Can't call method "save" on unblessed reference |
3760
|
|
|
|
|
|
|
#warn "Save MG ". $obj . "\n" if $PERL510; |
3761
|
|
|
|
|
|
|
# 5.11 'P' fix in B::IV::save, IV => RV |
3762
|
0
|
|
|
|
|
0
|
$obj = $mg->OBJ; |
3763
|
0
|
0
|
0
|
|
|
0
|
$obj->save($fullname) |
3764
|
|
|
|
|
|
|
unless $PERL510 and ref $obj eq 'SCALAR'; |
3765
|
0
|
0
|
|
|
|
0
|
mark_threads if $type eq 'P'; |
3766
|
|
|
|
|
|
|
} |
3767
|
|
|
|
|
|
|
|
3768
|
0
|
0
|
|
|
|
0
|
if ( $len == HEf_SVKEY ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
3769
|
|
|
|
|
|
|
# The pointer is an SV* ('s' sigelem e.g.) |
3770
|
|
|
|
|
|
|
# XXX On 5.6 ptr might be a SCALAR ref to the PV, which was fixed later |
3771
|
0
|
0
|
0
|
|
|
0
|
if (ref($ptr) eq 'SCALAR') { |
|
|
0
|
|
|
|
|
|
3772
|
0
|
|
|
|
|
0
|
$ptrsv = svref_2object($ptr)->save($fullname); |
3773
|
|
|
|
|
|
|
} elsif ($ptr and ref $ptr) { |
3774
|
0
|
|
|
|
|
0
|
$ptrsv = $ptr->save($fullname); |
3775
|
|
|
|
|
|
|
} else { |
3776
|
0
|
|
|
|
|
0
|
$ptrsv = 'NULL'; |
3777
|
|
|
|
|
|
|
} |
3778
|
0
|
0
|
|
|
|
0
|
warn "MG->PTR is an SV*\n" if $debug{mg}; |
3779
|
0
|
|
|
|
|
0
|
$init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, (char *)%s, %d);", |
3780
|
|
|
|
|
|
|
$$sv, $$obj, cchar($type), $ptrsv, $len)); |
3781
|
0
|
0
|
|
|
|
0
|
if (!($mg->FLAGS & 2)) { |
3782
|
0
|
|
|
|
|
0
|
mg_RC_off($mg, $sv, $type); |
3783
|
|
|
|
|
|
|
} |
3784
|
|
|
|
|
|
|
} |
3785
|
|
|
|
|
|
|
# coverage $Template::Stash::PRIVATE |
3786
|
|
|
|
|
|
|
elsif ( $type eq 'r' ) { # qr magic, for 5.6 done in C.xs. test 20 |
3787
|
0
|
0
|
|
|
|
0
|
my $rx = $PERL56 ? ${$mg->OBJ} : $mg->REGEX; |
|
0
|
|
|
|
|
0
|
|
3788
|
|
|
|
|
|
|
# stored by some PMOP *pm = cLOGOP->op_other (pp_ctl.c) in C.xs |
3789
|
0
|
|
|
|
|
0
|
my $pmop = $Regexp{$rx}; |
3790
|
0
|
0
|
|
|
|
0
|
if (!$pmop) { |
3791
|
0
|
|
|
|
|
0
|
warn "Warning: C.xs PMOP missing for QR\n"; |
3792
|
|
|
|
|
|
|
} else { |
3793
|
0
|
|
|
|
|
0
|
my ($resym, $relen); |
3794
|
0
|
0
|
|
|
|
0
|
if ($PERL56) { |
3795
|
0
|
|
|
|
|
0
|
($resym, $relen) = savere( $pmop->precomp ); # 5.6 has precomp only in PMOP |
3796
|
0
|
0
|
|
|
|
0
|
($resym, $relen) = savere( $mg->precomp ) unless $relen; |
3797
|
|
|
|
|
|
|
} else { |
3798
|
0
|
|
|
|
|
0
|
($resym, $relen) = savere( $mg->precomp ); |
3799
|
|
|
|
|
|
|
} |
3800
|
0
|
|
|
|
|
0
|
my $pmsym = $pmop->save(0, $fullname); |
3801
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3802
|
0
|
|
|
|
|
0
|
push @B::C::static_free, $resym; |
3803
|
0
|
|
|
|
|
0
|
$init->add( split /\n/, |
3804
|
|
|
|
|
|
|
sprintf <pmflags, $$sv, cchar($type), cstring($ptr), $len ); |
3805
|
|
|
|
|
|
|
{ |
3806
|
|
|
|
|
|
|
REGEXP* rx = CALLREGCOMP((SV* const)%s, %d); |
3807
|
|
|
|
|
|
|
sv_magic((SV*)s\\_%x, (SV*)rx, %s, %s, %d); |
3808
|
|
|
|
|
|
|
} |
3809
|
|
|
|
|
|
|
CODE1 |
3810
|
|
|
|
|
|
|
} |
3811
|
|
|
|
|
|
|
else { |
3812
|
0
|
|
|
|
|
0
|
$pmsym =~ s/\(OP\*\)\&pmop_list/&pmop_list/; |
3813
|
0
|
|
|
|
|
0
|
$init->add( split /\n/, |
3814
|
|
|
|
|
|
|
sprintf <
|
3815
|
|
|
|
|
|
|
{ |
3816
|
|
|
|
|
|
|
REGEXP* rx = pregcomp((char*)$resym,(char*)($resym + $relen), (PMOP*)$pmsym); |
3817
|
|
|
|
|
|
|
sv_magic((SV*)s\\_%x, (SV*)rx, %s, %s, %d); |
3818
|
|
|
|
|
|
|
} |
3819
|
|
|
|
|
|
|
CODE2 |
3820
|
|
|
|
|
|
|
} |
3821
|
|
|
|
|
|
|
} |
3822
|
|
|
|
|
|
|
} |
3823
|
|
|
|
|
|
|
elsif ( $type eq 'D' ) { # XXX regdata AV - coverage? i95, 903 |
3824
|
|
|
|
|
|
|
# see Perl_mg_copy() in mg.c |
3825
|
0
|
0
|
|
|
|
0
|
$init->add(sprintf("sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);", |
3826
|
|
|
|
|
|
|
$$sv, $fullname eq 'main::-' ? 0 : $$sv, "'D'", cstring($ptr), $len )); |
3827
|
|
|
|
|
|
|
} |
3828
|
|
|
|
|
|
|
elsif ( $type eq 'n' ) { # shared_scalar is from XS dist/threads-shared |
3829
|
|
|
|
|
|
|
# XXX check if threads is loaded also? otherwise it is only stubbed |
3830
|
0
|
|
|
|
|
0
|
mark_threads; |
3831
|
0
|
|
|
|
|
0
|
$init->add(sprintf("sv_magic((SV*)s\\_%x, Nullsv, %s, %s, %d);", |
3832
|
|
|
|
|
|
|
$$sv, "'n'", cstring($ptr), $len )); |
3833
|
|
|
|
|
|
|
} |
3834
|
|
|
|
|
|
|
elsif ( $type eq 'c' ) { # and !$PERL518 |
3835
|
0
|
|
|
|
|
0
|
$init->add(sprintf( |
3836
|
|
|
|
|
|
|
"/* AMT overload table for the stash %s s\\_%x is generated dynamically */", |
3837
|
|
|
|
|
|
|
$fullname, $$sv )); |
3838
|
|
|
|
|
|
|
} |
3839
|
|
|
|
|
|
|
elsif ( $type eq ':' ) { # symtab magic |
3840
|
|
|
|
|
|
|
# search $ptr in list of pmops and replace it. e.g. (char*)&pmop_list[0] |
3841
|
0
|
|
|
|
|
0
|
my $pmop_ptr = unpack("J", $mg->PTR); |
3842
|
0
|
|
|
|
|
0
|
my $pmop; |
3843
|
0
|
0
|
|
|
|
0
|
$pmop = $B::C::Regexp{$pmop_ptr} if defined $pmop_ptr; |
3844
|
0
|
0
|
|
|
|
0
|
my $pmsym = $pmop ? $pmop->save(0, $fullname) |
3845
|
|
|
|
|
|
|
: ''; #sprintf('&pmop_list[%u]', $pmopsect->index); |
3846
|
0
|
0
|
0
|
|
|
0
|
warn sprintf("pmop 0x%x not found in our B::C Regexp hash\n", $pmop_ptr || 'undef') |
|
|
|
0
|
|
|
|
|
3847
|
|
|
|
|
|
|
if !$pmop and $verbose; |
3848
|
0
|
0
|
|
|
|
0
|
$init->add("{\tU32 elements;", # toke.c: PL_multi_open == '?' |
|
|
0
|
|
|
|
|
|
3849
|
|
|
|
|
|
|
sprintf("\tMAGIC *mg = sv_magicext((SV*)s\\_%x, 0, ':', 0, 0, 0);", $$sv), |
3850
|
|
|
|
|
|
|
"\telements = mg->mg_len / sizeof(PMOP**);", |
3851
|
|
|
|
|
|
|
"\tRenewc(mg->mg_ptr, elements + 1, PMOP*, char);", |
3852
|
|
|
|
|
|
|
($pmop |
3853
|
|
|
|
|
|
|
? (sprintf("\t((OP**)mg->mg_ptr) [elements++] = (OP*)%s;", $pmsym)) |
3854
|
|
|
|
|
|
|
: ( defined $pmop_ptr |
3855
|
|
|
|
|
|
|
? sprintf( "\t((OP**)mg->mg_ptr) [elements++] = (OP*)s\\_%x;", $pmop_ptr ) : '' )), |
3856
|
|
|
|
|
|
|
"\tmg->mg_len = elements * sizeof(PMOP**);", "}"); |
3857
|
|
|
|
|
|
|
} |
3858
|
|
|
|
|
|
|
else { |
3859
|
0
|
|
|
|
|
0
|
$init->add(sprintf( |
3860
|
|
|
|
|
|
|
"sv_magic((SV*)s\\_%x, (SV*)s\\_%x, %s, %s, %d);", |
3861
|
|
|
|
|
|
|
$$sv, $$obj, cchar($type), cstring($ptr), $len)); |
3862
|
0
|
0
|
|
|
|
0
|
if (!($mg->FLAGS & 2)) { |
3863
|
0
|
|
|
|
|
0
|
mg_RC_off($mg, $sv, $type); |
3864
|
|
|
|
|
|
|
} |
3865
|
|
|
|
|
|
|
} |
3866
|
|
|
|
|
|
|
} |
3867
|
0
|
0
|
0
|
|
|
0
|
$init->add(sprintf("SvREADONLY_on((SV*)s\\_%x);", $$sv)) |
3868
|
|
|
|
|
|
|
if $sv_flags & SVf_READONLY and ref($sv) ne 'B::HV'; |
3869
|
0
|
|
|
|
|
0
|
$magic; |
3870
|
|
|
|
|
|
|
} |
3871
|
|
|
|
|
|
|
|
3872
|
|
|
|
|
|
|
# Since 5.11 also called by IV::save (SV -> IV) |
3873
|
|
|
|
|
|
|
sub B::RV::save { |
3874
|
0
|
|
|
0
|
|
0
|
my ($sv, $fullname) = @_; |
3875
|
0
|
|
|
|
|
0
|
my $sym = objsym($sv); |
3876
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
3877
|
|
|
|
|
|
|
warn sprintf( "Saving RV %s (0x%x) - called from %s:%s\n", |
3878
|
0
|
|
|
|
|
0
|
B::class($sv), $$sv, @{[(caller(1))[3]]}, @{[(caller(1))[2]]}) |
|
0
|
|
|
|
|
0
|
|
3879
|
0
|
0
|
|
|
|
0
|
if $debug{sv}; |
3880
|
|
|
|
|
|
|
|
3881
|
0
|
|
|
|
|
0
|
my $rv = save_rv($sv, $fullname); |
3882
|
0
|
0
|
|
|
|
0
|
return '0' unless $rv; |
3883
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3884
|
0
|
|
|
|
|
0
|
$svsect->comment( "any, refcnt, flags, sv_u" ); |
3885
|
|
|
|
|
|
|
# 5.22 has a wrong RV->FLAGS (https://github.com/perl11/cperl/issues/63) |
3886
|
0
|
|
|
|
|
0
|
my $flags = $sv->FLAGS; |
3887
|
0
|
0
|
0
|
|
|
0
|
$flags = 0x801 if $flags & 9 and $PERL522; # not a GV but a ROK IV (21) |
3888
|
|
|
|
|
|
|
# 5.10 has no struct xrv anymore, just sv_u.svu_rv. static or dynamic? |
3889
|
|
|
|
|
|
|
# initializer element is computable at load time |
3890
|
0
|
0
|
0
|
|
|
0
|
$svsect->add( sprintf( "ptr_undef, $u32fmt, 0x%x, {%s}", $sv->REFCNT, $flags, |
3891
|
|
|
|
|
|
|
(($C99 && is_constant($rv)) ? ".svu_rv=$rv" : "0 /*-> $rv */"))); |
3892
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
3893
|
0
|
|
|
|
|
0
|
my $s = "sv_list[".$svsect->index."]"; |
3894
|
|
|
|
|
|
|
# 354 defined needs SvANY |
3895
|
0
|
0
|
0
|
|
|
0
|
$init->add( sprintf("$s.sv_any = (char*)&$s - %d;", $Config{ptrsize})) |
3896
|
|
|
|
|
|
|
if $] > 5.019 or $ITHREADS; |
3897
|
0
|
0
|
0
|
|
|
0
|
unless ($C99 && is_constant($rv)) { |
3898
|
0
|
0
|
|
|
|
0
|
if ( $rv =~ /get_cv/ ) { |
3899
|
0
|
|
|
|
|
0
|
$init2->add( "$s.sv_u.svu_rv = (SV*)$rv;" ) ; |
3900
|
|
|
|
|
|
|
} else { |
3901
|
0
|
|
|
|
|
0
|
$init->add( "$s.sv_u.svu_rv = (SV*)$rv;" ) ; |
3902
|
|
|
|
|
|
|
} |
3903
|
|
|
|
|
|
|
} |
3904
|
0
|
|
|
|
|
0
|
return savesym( $sv, "&".$s ); |
3905
|
|
|
|
|
|
|
} |
3906
|
|
|
|
|
|
|
else { |
3907
|
|
|
|
|
|
|
# GVs need to be handled at runtime |
3908
|
0
|
0
|
0
|
|
|
0
|
if ( ref( $sv->RV ) eq 'B::GV' or $rv =~ /^gv_list/) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
3909
|
0
|
|
|
|
|
0
|
$xrvsect->add("Nullsv /* $rv */"); |
3910
|
0
|
|
|
|
|
0
|
$init->add( |
3911
|
|
|
|
|
|
|
sprintf( "xrv_list[%d].xrv_rv = (SV*)%s;", $xrvsect->index, $rv ) ); |
3912
|
|
|
|
|
|
|
} |
3913
|
|
|
|
|
|
|
# and stashes, too |
3914
|
|
|
|
|
|
|
elsif ( $sv->RV->isa('B::HV') && $sv->RV->NAME ) { |
3915
|
0
|
|
|
|
|
0
|
$xrvsect->add("Nullsv /* $rv */"); |
3916
|
0
|
|
|
|
|
0
|
$init->add( |
3917
|
|
|
|
|
|
|
sprintf( "xrv_list[%d].xrv_rv = (SV*)%s;", $xrvsect->index, $rv ) ); |
3918
|
|
|
|
|
|
|
} |
3919
|
|
|
|
|
|
|
# one more: bootstrapped XS CVs (test Class::MOP, no simple testcase yet) |
3920
|
|
|
|
|
|
|
# dynamic; so we need to inc it |
3921
|
|
|
|
|
|
|
elsif ( $rv =~ /get_cv/ ) { |
3922
|
0
|
|
|
|
|
0
|
$xrvsect->add("Nullsv /* $rv */"); |
3923
|
0
|
|
|
|
|
0
|
$init2->add( |
3924
|
|
|
|
|
|
|
sprintf( "xrv_list[%d].xrv_rv = (SV*)SvREFCNT_inc(%s);", $xrvsect->index, $rv ) ); |
3925
|
|
|
|
|
|
|
} |
3926
|
|
|
|
|
|
|
else { |
3927
|
|
|
|
|
|
|
#$xrvsect->add($rv); # not static initializable (e.g. cv160 for ExtUtils::Install) |
3928
|
0
|
|
|
|
|
0
|
$xrvsect->add("Nullsv /* $rv */"); |
3929
|
0
|
|
|
|
|
0
|
$init->add( |
3930
|
|
|
|
|
|
|
sprintf( "xrv_list[%d].xrv_rv = (SV*)SvREFCNT_inc(%s);", $xrvsect->index, $rv ) ); |
3931
|
|
|
|
|
|
|
} |
3932
|
0
|
|
|
|
|
0
|
$svsect->comment( "any, refcnt, flags" ); |
3933
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xrv_list[%d], $u32fmt, 0x%x", |
3934
|
|
|
|
|
|
|
$xrvsect->index, $sv->REFCNT, $sv->FLAGS)); |
3935
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $sv->flagspv ) if $debug{flags}; |
3936
|
0
|
|
|
|
|
0
|
my $s = "sv_list[".$svsect->index."]"; |
3937
|
0
|
|
|
|
|
0
|
return savesym( $sv, "&".$s ); |
3938
|
|
|
|
|
|
|
} |
3939
|
|
|
|
|
|
|
} |
3940
|
|
|
|
|
|
|
|
3941
|
|
|
|
|
|
|
sub get_isa ($) { |
3942
|
0
|
|
|
0
|
0
|
0
|
my $name = shift; |
3943
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
3944
|
0
|
0
|
|
|
|
0
|
if (is_using_mro()) { # mro.xs loaded. c3 or dfs |
3945
|
0
|
|
|
|
|
0
|
return @{mro::get_linear_isa($name)}; |
|
0
|
|
|
|
|
0
|
|
3946
|
|
|
|
|
|
|
} else { # dfs only, without loading mro |
3947
|
0
|
|
|
|
|
0
|
return @{B::C::get_linear_isa($name)}; |
|
0
|
|
|
|
|
0
|
|
3948
|
|
|
|
|
|
|
} |
3949
|
|
|
|
|
|
|
} else { |
3950
|
55
|
|
|
55
|
|
446
|
no strict 'refs'; |
|
55
|
|
|
|
|
87
|
|
|
55
|
|
|
|
|
7511
|
|
3951
|
0
|
|
|
|
|
0
|
my $s = "$name\::"; |
3952
|
0
|
0
|
|
|
|
0
|
if (exists(${$s}{ISA})) { |
|
0
|
|
|
|
|
0
|
|
3953
|
0
|
0
|
|
|
|
0
|
if (exists(${$s}{ISA}{ARRAY})) { |
|
0
|
|
|
|
|
0
|
|
3954
|
0
|
|
|
|
|
0
|
return @{ "$s\::ISA" }; |
|
0
|
|
|
|
|
0
|
|
3955
|
|
|
|
|
|
|
} |
3956
|
|
|
|
|
|
|
} |
3957
|
|
|
|
|
|
|
} |
3958
|
|
|
|
|
|
|
} |
3959
|
|
|
|
|
|
|
|
3960
|
|
|
|
|
|
|
# try_isa($pkg,$name) returns the found $pkg for the method $pkg::$name |
3961
|
|
|
|
|
|
|
# If a method can be called (via UNIVERSAL::can) search the ISA's. No AUTOLOAD needed. |
3962
|
|
|
|
|
|
|
# XXX issue 64, empty @ISA if a package has no subs. in Bytecode ok |
3963
|
|
|
|
|
|
|
sub try_isa { |
3964
|
0
|
|
|
0
|
0
|
0
|
my ( $cvstashname, $cvname ) = @_; |
3965
|
0
|
0
|
0
|
|
|
0
|
return 0 unless defined $cvstashname && defined $cvname; |
3966
|
0
|
0
|
|
|
|
0
|
if (my $found = $isa_cache{"$cvstashname\::$cvname"}) { |
3967
|
0
|
|
|
|
|
0
|
return $found; |
3968
|
|
|
|
|
|
|
} |
3969
|
55
|
|
|
55
|
|
244
|
no strict 'refs'; |
|
55
|
|
|
|
|
75
|
|
|
55
|
|
|
|
|
23868
|
|
3970
|
|
|
|
|
|
|
# XXX theoretically a valid shortcut. In reality it fails when $cvstashname is not loaded. |
3971
|
|
|
|
|
|
|
# return 0 unless $cvstashname->can($cvname); |
3972
|
0
|
|
|
|
|
0
|
my @isa = get_isa($cvstashname); |
3973
|
|
|
|
|
|
|
warn sprintf( "No definition for sub %s::%s. Try \@%s::ISA=(%s)\n", |
3974
|
|
|
|
|
|
|
$cvstashname, $cvname, $cvstashname, join(",",@isa)) |
3975
|
0
|
0
|
|
|
|
0
|
if $debug{cv}; |
3976
|
0
|
|
|
|
|
0
|
for (@isa) { # global @ISA or in pad |
3977
|
0
|
0
|
|
|
|
0
|
next if $_ eq $cvstashname; |
3978
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Try &%s::%s\n", $_, $cvname ) if $debug{cv}; |
3979
|
0
|
0
|
|
|
|
0
|
if (defined(&{$_ .'::'. $cvname})) { |
|
0
|
|
|
|
|
0
|
|
3980
|
0
|
0
|
|
|
|
0
|
if (exists(${$cvstashname.'::'}{ISA})) { |
|
0
|
|
|
|
|
0
|
|
3981
|
0
|
|
|
|
|
0
|
svref_2object( \@{$cvstashname . '::ISA'} )->save("$cvstashname\::ISA"); |
|
0
|
|
|
|
|
0
|
|
3982
|
|
|
|
|
|
|
} |
3983
|
0
|
|
|
|
|
0
|
$isa_cache{"$cvstashname\::$cvname"} = $_; |
3984
|
0
|
|
|
|
|
0
|
mark_package($_, 1); # force |
3985
|
0
|
|
|
|
|
0
|
return $_; |
3986
|
|
|
|
|
|
|
} else { |
3987
|
0
|
|
|
|
|
0
|
$isa_cache{"$_\::$cvname"} = 0; |
3988
|
0
|
0
|
|
|
|
0
|
if (get_isa($_)) { |
3989
|
0
|
|
|
|
|
0
|
my $parent = try_isa($_, $cvname); |
3990
|
0
|
0
|
|
|
|
0
|
if ($parent) { |
3991
|
0
|
|
|
|
|
0
|
$isa_cache{"$_\::$cvname"} = $parent; |
3992
|
0
|
|
|
|
|
0
|
$isa_cache{"$cvstashname\::$cvname"} = $parent; |
3993
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Found &%s::%s\n", $parent, $cvname ) if $debug{gv}; |
3994
|
0
|
0
|
|
|
|
0
|
if (exists(${$parent.'::'}{ISA})) { |
|
0
|
|
|
|
|
0
|
|
3995
|
0
|
0
|
|
|
|
0
|
warn "save \@$parent\::ISA\n" if $debug{pkg}; |
3996
|
0
|
|
|
|
|
0
|
svref_2object( \@{$parent . '::ISA'} )->save("$parent\::ISA"); |
|
0
|
|
|
|
|
0
|
|
3997
|
|
|
|
|
|
|
} |
3998
|
0
|
0
|
|
|
|
0
|
if (exists(${$_.'::'}{ISA})) { |
|
0
|
|
|
|
|
0
|
|
3999
|
0
|
0
|
|
|
|
0
|
warn "save \@$_\::ISA\n" if $debug{pkg}; |
4000
|
0
|
|
|
|
|
0
|
svref_2object( \@{$_ . '::ISA'} )->save("$_\::ISA"); |
|
0
|
|
|
|
|
0
|
|
4001
|
|
|
|
|
|
|
} |
4002
|
0
|
|
|
|
|
0
|
return $parent; |
4003
|
|
|
|
|
|
|
} |
4004
|
|
|
|
|
|
|
} |
4005
|
|
|
|
|
|
|
} |
4006
|
|
|
|
|
|
|
} |
4007
|
0
|
|
|
|
|
0
|
return 0; # not found |
4008
|
|
|
|
|
|
|
} |
4009
|
|
|
|
|
|
|
|
4010
|
|
|
|
|
|
|
sub load_utf8_heavy { |
4011
|
0
|
0
|
|
0
|
0
|
0
|
return if $savINC{"utf8_heavy.pl"}; |
4012
|
|
|
|
|
|
|
|
4013
|
0
|
|
|
|
|
0
|
require 'utf8_heavy.pl'; |
4014
|
0
|
|
|
|
|
0
|
mark_package('utf8_heavy.pl'); |
4015
|
0
|
|
|
|
|
0
|
$curINC{'utf8_heavy.pl'} = $INC{'utf8_heavy.pl'}; |
4016
|
0
|
|
|
|
|
0
|
$savINC{"utf8_heavy.pl"} = 1; |
4017
|
0
|
|
|
|
|
0
|
add_hashINC("utf8"); |
4018
|
|
|
|
|
|
|
|
4019
|
|
|
|
|
|
|
# FIXME: we want to use add_hashINC for utf8_heavy, inc_packname should return an array |
4020
|
|
|
|
|
|
|
# add_hashINC("utf8_heavy.pl"); |
4021
|
|
|
|
|
|
|
|
4022
|
|
|
|
|
|
|
# In CORE utf8::SWASHNEW is demand-loaded from utf8 with Perl_load_module() |
4023
|
|
|
|
|
|
|
# It adds about 1.6MB exe size 32-bit. |
4024
|
0
|
|
|
|
|
0
|
svref_2object( \&{"utf8\::SWASHNEW"} )->save; |
|
0
|
|
|
|
|
0
|
|
4025
|
|
|
|
|
|
|
|
4026
|
0
|
|
|
|
|
0
|
return 1; |
4027
|
|
|
|
|
|
|
} |
4028
|
|
|
|
|
|
|
|
4029
|
|
|
|
|
|
|
# If the sub or method is not found: |
4030
|
|
|
|
|
|
|
# 1. try @ISA, mark_package and return. |
4031
|
|
|
|
|
|
|
# 2. try UNIVERSAL::method |
4032
|
|
|
|
|
|
|
# 3. try compile-time expansion of AUTOLOAD to get the goto &sub addresses |
4033
|
|
|
|
|
|
|
sub try_autoload { |
4034
|
0
|
|
|
0
|
0
|
0
|
my ( $cvstashname, $cvname ) = @_; |
4035
|
55
|
|
|
55
|
|
244
|
no strict 'refs'; |
|
55
|
|
|
|
|
89
|
|
|
55
|
|
|
|
|
2342
|
|
4036
|
0
|
0
|
0
|
|
|
0
|
return unless defined $cvstashname && defined $cvname; |
4037
|
0
|
0
|
|
|
|
0
|
return 1 if try_isa($cvstashname, $cvname); |
4038
|
|
|
|
|
|
|
|
4039
|
55
|
|
|
55
|
|
193
|
no strict 'refs'; |
|
55
|
|
|
|
|
78
|
|
|
55
|
|
|
|
|
57212
|
|
4040
|
0
|
0
|
|
|
|
0
|
if (defined(*{'UNIVERSAL::'. $cvname}{CODE})) { |
|
0
|
|
|
|
|
0
|
|
4041
|
0
|
0
|
|
|
|
0
|
warn "Found UNIVERSAL::$cvname\n" if $debug{cv}; |
4042
|
0
|
|
|
|
|
0
|
return svref_2object( \&{'UNIVERSAL::'.$cvname} ); |
|
0
|
|
|
|
|
0
|
|
4043
|
|
|
|
|
|
|
} |
4044
|
0
|
|
|
|
|
0
|
my $fullname = $cvstashname . '::' . $cvname; |
4045
|
|
|
|
|
|
|
warn sprintf( "No definition for sub %s. Try %s::AUTOLOAD\n", |
4046
|
0
|
0
|
|
|
|
0
|
$fullname, $cvstashname ) if $debug{cv}; |
4047
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'utf8::SWASHNEW') { |
4048
|
|
|
|
|
|
|
# utf8_heavy was loaded so far, so defer to a demand-loading stub |
4049
|
|
|
|
|
|
|
# always require utf8_heavy, do not care if it s already in |
4050
|
0
|
|
|
0
|
|
0
|
my $stub = sub { require 'utf8_heavy.pl'; goto &utf8::SWASHNEW }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
4051
|
0
|
|
|
|
|
0
|
return svref_2object( $stub ); |
4052
|
|
|
|
|
|
|
} |
4053
|
|
|
|
|
|
|
|
4054
|
|
|
|
|
|
|
# Handle AutoLoader classes. Any more general AUTOLOAD |
4055
|
|
|
|
|
|
|
# use should be handled by the class itself. |
4056
|
0
|
|
|
|
|
0
|
my @isa = get_isa($cvstashname); |
4057
|
0
|
0
|
0
|
|
|
0
|
if ( $cvstashname =~ /^POSIX|Storable|DynaLoader|Net::SSLeay|Class::MethodMaker$/ |
|
|
|
0
|
|
|
|
|
4058
|
0
|
|
|
|
|
0
|
or (exists ${$cvstashname.'::'}{AUTOLOAD} and grep( $_ eq "AutoLoader", @isa ) ) ) |
4059
|
|
|
|
|
|
|
{ |
4060
|
|
|
|
|
|
|
# Tweaked version of AutoLoader::AUTOLOAD |
4061
|
0
|
|
|
|
|
0
|
my $dir = $cvstashname; |
4062
|
0
|
|
|
|
|
0
|
$dir =~ s(::)(/)g; |
4063
|
0
|
0
|
|
|
|
0
|
warn "require \"auto/$dir/$cvname.al\"\n" if $debug{cv}; |
4064
|
0
|
0
|
|
|
|
0
|
eval { local $SIG{__DIE__}; require "auto/$dir/$cvname.al" unless $INC{"auto/$dir/$cvname.al"} }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
4065
|
0
|
0
|
|
|
|
0
|
unless ($@) { |
4066
|
0
|
0
|
|
|
|
0
|
warn "Forced load of \"auto/$dir/$cvname.al\"\n" if $verbose; |
4067
|
0
|
0
|
|
|
|
0
|
return svref_2object( \&$fullname ) |
4068
|
|
|
|
|
|
|
if defined &$fullname; |
4069
|
|
|
|
|
|
|
} |
4070
|
|
|
|
|
|
|
} |
4071
|
|
|
|
|
|
|
|
4072
|
|
|
|
|
|
|
# XXX Still not found, now it's getting dangerous (until 5.10 only) |
4073
|
|
|
|
|
|
|
# Search and call ::AUTOLOAD (=> ROOT and XSUB) (test 27, 5.8) |
4074
|
|
|
|
|
|
|
# Since 5.10 AUTOLOAD xsubs are already resolved |
4075
|
0
|
0
|
0
|
|
|
0
|
if (exists ${$cvstashname.'::'}{AUTOLOAD} and !$PERL510) { |
|
0
|
|
|
|
|
0
|
|
4076
|
0
|
|
|
|
|
0
|
my $auto = \&{$cvstashname.'::AUTOLOAD'}; |
|
0
|
|
|
|
|
0
|
|
4077
|
|
|
|
|
|
|
# Tweaked version of __PACKAGE__::AUTOLOAD |
4078
|
0
|
|
|
|
|
0
|
$AutoLoader::AUTOLOAD = ${$cvstashname.'::AUTOLOAD'} = "$cvstashname\::$cvname"; |
|
0
|
|
|
|
|
0
|
|
4079
|
|
|
|
|
|
|
|
4080
|
|
|
|
|
|
|
# Prevent eval from polluting STDOUT,STDERR and our c code. |
4081
|
|
|
|
|
|
|
# With a debugging perl STDERR is written |
4082
|
0
|
|
|
|
|
0
|
local *REALSTDOUT; |
4083
|
0
|
0
|
|
|
|
0
|
local *REALSTDERR unless $DEBUGGING; |
4084
|
0
|
|
|
|
|
0
|
open(REALSTDOUT,">&STDOUT"); |
4085
|
0
|
0
|
|
|
|
0
|
open(REALSTDERR,">&STDERR") unless $DEBUGGING; |
4086
|
0
|
|
|
|
|
0
|
open(STDOUT,">","/dev/null"); |
4087
|
0
|
0
|
|
|
|
0
|
open(STDERR,">","/dev/null") unless $DEBUGGING; |
4088
|
0
|
0
|
|
|
|
0
|
warn "eval \&$cvstashname\::AUTOLOAD\n" if $debug{cv}; |
4089
|
0
|
|
|
|
|
0
|
eval { &$auto }; |
|
0
|
|
|
|
|
0
|
|
4090
|
0
|
|
|
|
|
0
|
open(STDOUT,">&REALSTDOUT"); |
4091
|
0
|
0
|
|
|
|
0
|
open(STDERR,">&REALSTDERR") unless $DEBUGGING; |
4092
|
|
|
|
|
|
|
|
4093
|
0
|
0
|
|
|
|
0
|
unless ($@) { |
4094
|
|
|
|
|
|
|
# we need just the empty auto GV, $cvname->ROOT and $cvname->XSUB, |
4095
|
|
|
|
|
|
|
# but not the whole CV optree. XXX This still fails with 5.8 |
4096
|
0
|
|
|
|
|
0
|
my $cv = svref_2object( \&{$fullname} ); |
|
0
|
|
|
|
|
0
|
|
4097
|
0
|
|
|
|
|
0
|
return $cv; |
4098
|
|
|
|
|
|
|
} |
4099
|
|
|
|
|
|
|
} |
4100
|
|
|
|
|
|
|
|
4101
|
|
|
|
|
|
|
# XXX TODO Check Selfloader (test 31?) |
4102
|
0
|
|
|
|
|
0
|
svref_2object( \*{$cvstashname.'::AUTOLOAD'} )->save |
4103
|
0
|
0
|
0
|
|
|
0
|
if $cvstashname and exists ${$cvstashname.'::'}{AUTOLOAD}; |
|
0
|
|
|
|
|
0
|
|
4104
|
0
|
|
|
|
|
0
|
svref_2object( \*{$cvstashname.'::CLONE'} )->save |
4105
|
0
|
0
|
0
|
|
|
0
|
if $cvstashname and exists ${$cvstashname.'::'}{CLONE}; |
|
0
|
|
|
|
|
0
|
|
4106
|
|
|
|
|
|
|
} |
4107
|
|
|
|
0
|
0
|
|
sub Dummy_initxs { } |
4108
|
|
|
|
|
|
|
|
4109
|
|
|
|
|
|
|
sub B::CV::is_lexsub { |
4110
|
0
|
|
|
0
|
|
0
|
my ($cv, $gv) = @_; |
4111
|
|
|
|
|
|
|
# logical shortcut perl5 bug since ~ 5.19: testcc.sh 42 |
4112
|
|
|
|
|
|
|
# return ($PERL518 and (!$gv or ref($gv) eq 'B::SPECIAL') and $cv->can('NAME_HEK')); |
4113
|
0
|
0
|
0
|
|
|
0
|
return ($PERL518 and (!$gv or ref($gv) eq 'B::SPECIAL') and $cv->can('NAME_HEK')) ? 1 : 0; |
4114
|
|
|
|
|
|
|
} |
4115
|
|
|
|
|
|
|
|
4116
|
|
|
|
|
|
|
sub is_phase_name { |
4117
|
0
|
0
|
|
0
|
0
|
0
|
$_[0] =~ /^(BEGIN|INIT|UNITCHECK|CHECK|END)$/ ? 1 : 0; |
4118
|
|
|
|
|
|
|
} |
4119
|
|
|
|
|
|
|
|
4120
|
|
|
|
|
|
|
sub B::CV::save { |
4121
|
0
|
|
|
0
|
|
0
|
my ($cv, $origname) = @_; |
4122
|
0
|
|
|
|
|
0
|
my $sym = objsym($cv); |
4123
|
0
|
0
|
|
|
|
0
|
if ( defined($sym) ) { |
4124
|
0
|
0
|
0
|
|
|
0
|
warn sprintf( "CV 0x%x already saved as $sym\n", $$cv ) if $$cv and $debug{cv}; |
4125
|
0
|
|
|
|
|
0
|
return $sym; |
4126
|
|
|
|
|
|
|
} |
4127
|
0
|
|
|
|
|
0
|
my $gv = $cv->GV; |
4128
|
0
|
|
|
|
|
0
|
my ( $cvname, $cvstashname, $fullname, $isutf8 ); |
4129
|
0
|
|
|
|
|
0
|
$fullname = ''; |
4130
|
0
|
|
|
|
|
0
|
my $CvFLAGS = $cv->CvFLAGS; |
4131
|
0
|
0
|
0
|
|
|
0
|
if ($gv and $$gv) { |
|
|
0
|
|
|
|
|
|
4132
|
0
|
|
|
|
|
0
|
$cvstashname = $gv->STASH->NAME; |
4133
|
0
|
|
|
|
|
0
|
$cvname = $gv->NAME; |
4134
|
0
|
|
0
|
|
|
0
|
$isutf8 = ($gv->FLAGS & SVf_UTF8) || ($gv->STASH->FLAGS & SVf_UTF8); |
4135
|
0
|
|
|
|
|
0
|
$fullname = $cvstashname.'::'.$cvname; |
4136
|
|
|
|
|
|
|
# XXX gv->EGV does not really help here |
4137
|
0
|
0
|
0
|
|
|
0
|
if ($PERL522 and $cvname eq '__ANON__') { |
4138
|
0
|
0
|
|
|
|
0
|
if ($origname) { |
4139
|
|
|
|
|
|
|
warn sprintf( "CV with empty PVGV %s -> %s\n", |
4140
|
0
|
0
|
|
|
|
0
|
$fullname, $origname) if $debug{cv}; |
4141
|
0
|
|
|
|
|
0
|
$cvname = $fullname = $origname; |
4142
|
0
|
0
|
|
|
|
0
|
$cvname =~ s/^\Q$cvstashname\E::(.*)( :pad\[.*)?$/$1/ if $cvstashname; |
4143
|
0
|
|
|
|
|
0
|
$cvname =~ s/^.*:://; |
4144
|
0
|
0
|
|
|
|
0
|
if ($cvname =~ m/ :pad\[.*$/) { |
4145
|
0
|
|
|
|
|
0
|
$cvname =~ s/ :pad\[.*$//; |
4146
|
0
|
0
|
|
|
|
0
|
$cvname = '__ANON__' if is_phase_name($cvname); |
4147
|
0
|
|
|
|
|
0
|
$fullname = $cvstashname.'::'.$cvname; |
4148
|
|
|
|
|
|
|
} |
4149
|
0
|
0
|
|
|
|
0
|
warn sprintf( "empty -> %s\n", $cvname) if $debug{cv}; |
4150
|
|
|
|
|
|
|
} else { |
4151
|
0
|
|
|
|
|
0
|
$cvname = $gv->EGV->NAME; |
4152
|
|
|
|
|
|
|
warn sprintf( "CV with empty PVGV %s -> %s::%s\n", |
4153
|
0
|
0
|
|
|
|
0
|
$fullname, $cvstashname, $cvname) if $debug{cv}; |
4154
|
0
|
|
|
|
|
0
|
$fullname = $cvstashname.'::'.$cvname; |
4155
|
|
|
|
|
|
|
} |
4156
|
|
|
|
|
|
|
} |
4157
|
|
|
|
|
|
|
warn sprintf( "CV 0x%x as PVGV 0x%x %s CvFLAGS=0x%x\n", |
4158
|
0
|
0
|
|
|
|
0
|
$$cv, $$gv, $fullname, $CvFLAGS ) if $debug{cv}; |
4159
|
|
|
|
|
|
|
# XXX not needed, we already loaded utf8_heavy |
4160
|
|
|
|
|
|
|
#return if $fullname eq 'utf8::AUTOLOAD'; |
4161
|
0
|
0
|
0
|
|
|
0
|
return '0' if $all_bc_subs{$fullname} or skip_pkg($cvstashname); |
4162
|
0
|
0
|
|
|
|
0
|
$CvFLAGS &= ~0x400 if $PERL514; # no CVf_CVGV_RC otherwise we cannot set the GV |
4163
|
0
|
0
|
|
|
|
0
|
mark_package($cvstashname, 1) unless $include_package{$cvstashname}; |
4164
|
|
|
|
|
|
|
} |
4165
|
|
|
|
|
|
|
elsif ($cv->is_lexsub($gv)) { |
4166
|
0
|
|
|
|
|
0
|
$fullname = $cv->NAME_HEK; |
4167
|
0
|
0
|
|
|
|
0
|
$fullname = '' unless defined $fullname; |
4168
|
0
|
|
|
|
|
0
|
$isutf8 = $cv->FLAGS & SVf_UTF8; |
4169
|
0
|
0
|
|
|
|
0
|
warn sprintf( "CV lexsub NAME_HEK $fullname\n") if $debug{cv}; |
4170
|
0
|
0
|
|
|
|
0
|
if ($fullname =~ /^(.*)::(.*?)$/) { |
4171
|
0
|
|
|
|
|
0
|
$cvstashname = $1; |
4172
|
0
|
|
|
|
|
0
|
$cvname = $2; |
4173
|
|
|
|
|
|
|
} |
4174
|
|
|
|
|
|
|
} |
4175
|
0
|
0
|
|
|
|
0
|
$cvstashname = '' unless defined $cvstashname; |
4176
|
|
|
|
|
|
|
|
4177
|
|
|
|
|
|
|
# XXX TODO need to save the gv stash::AUTOLOAD if exists |
4178
|
0
|
|
|
|
|
0
|
my $root = $cv->ROOT; |
4179
|
0
|
|
|
|
|
0
|
my $cvxsub = $cv->XSUB; |
4180
|
0
|
|
|
|
|
0
|
my $isconst; |
4181
|
55
|
|
|
55
|
|
294
|
{ no strict 'subs'; |
|
55
|
|
|
|
|
72
|
|
|
55
|
|
|
|
|
21231
|
|
|
0
|
|
|
|
|
0
|
|
4182
|
0
|
0
|
|
|
|
0
|
$isconst = $PERL56 ? 0 : $CvFLAGS & CVf_CONST; |
4183
|
|
|
|
|
|
|
} |
4184
|
|
|
|
|
|
|
|
4185
|
0
|
0
|
0
|
|
|
0
|
if ( !$isconst && $cvxsub && ( $cvname ne "INIT" ) ) { |
|
|
|
0
|
|
|
|
|
4186
|
0
|
|
|
|
|
0
|
my $egv = $gv->EGV; |
4187
|
0
|
|
|
|
|
0
|
my $stashname = $egv->STASH->NAME; |
4188
|
0
|
|
|
|
|
0
|
$fullname = $stashname.'::'.$cvname; |
4189
|
0
|
0
|
0
|
|
|
0
|
if ( $cvname eq "bootstrap" and !$xsub{$stashname} ) { |
4190
|
0
|
|
|
|
|
0
|
my $file = $gv->FILE; |
4191
|
0
|
|
|
|
|
0
|
$decl->add("/* bootstrap $file */"); |
4192
|
0
|
0
|
|
|
|
0
|
warn "Bootstrap $stashname $file\n" if $verbose; |
4193
|
0
|
|
|
|
|
0
|
mark_package($stashname); |
4194
|
|
|
|
|
|
|
|
4195
|
|
|
|
|
|
|
# Without DynaLoader we must boot and link static |
4196
|
0
|
0
|
0
|
|
|
0
|
if ( !$Config{usedl} ) { |
|
|
0
|
0
|
|
|
|
|
4197
|
0
|
|
|
|
|
0
|
$xsub{$stashname} = 'Static'; |
4198
|
|
|
|
|
|
|
} |
4199
|
|
|
|
|
|
|
# if it not isa('DynaLoader'), it should hopefully be XSLoaded |
4200
|
|
|
|
|
|
|
# ( attributes being an exception, of course ) |
4201
|
|
|
|
|
|
|
elsif ( !UNIVERSAL::isa( $stashname, 'DynaLoader' ) |
4202
|
|
|
|
|
|
|
and ($stashname ne 'attributes' || $] >= 5.011)) |
4203
|
|
|
|
|
|
|
{ |
4204
|
0
|
|
|
|
|
0
|
my $stashfile = $stashname; |
4205
|
0
|
|
|
|
|
0
|
$stashfile =~ s/::/\//g; |
4206
|
0
|
0
|
|
|
|
0
|
if ($file =~ /XSLoader\.pm$/) { # almost always the case |
4207
|
0
|
|
|
|
|
0
|
$file = $INC{$stashfile . ".pm"}; |
4208
|
|
|
|
|
|
|
} |
4209
|
0
|
0
|
|
|
|
0
|
unless ($file) { # do the reverse as DynaLoader: soname => pm |
4210
|
0
|
|
|
|
|
0
|
my ($laststash) = $stashname =~ /::([^:]+)$/; |
4211
|
0
|
0
|
|
|
|
0
|
$laststash = $stashname unless $laststash; |
4212
|
0
|
|
|
|
|
0
|
my $sofile = "auto/" . $stashfile . '/' . $laststash . '\.' . $Config{dlext}; |
4213
|
0
|
|
|
|
|
0
|
for (@DynaLoader::dl_shared_objects) { |
4214
|
0
|
0
|
|
|
|
0
|
if (m{^(.+/)$sofile$}) { |
4215
|
0
|
|
|
|
|
0
|
$file = $1. $stashfile.".pm"; last; |
|
0
|
|
|
|
|
0
|
|
4216
|
|
|
|
|
|
|
} |
4217
|
|
|
|
|
|
|
} |
4218
|
|
|
|
|
|
|
} |
4219
|
0
|
|
|
|
|
0
|
$xsub{$stashname} = 'Dynamic-'.$file; |
4220
|
0
|
|
|
|
|
0
|
force_saving_xsloader(); |
4221
|
|
|
|
|
|
|
} |
4222
|
|
|
|
|
|
|
else { |
4223
|
0
|
|
|
|
|
0
|
$xsub{$stashname} = 'Dynamic'; |
4224
|
|
|
|
|
|
|
# DynaLoader was for sure loaded, before so we execute the branch which |
4225
|
|
|
|
|
|
|
# does walk_syms and add_hashINC |
4226
|
0
|
|
|
|
|
0
|
mark_package('DynaLoader', 1); |
4227
|
|
|
|
|
|
|
} |
4228
|
|
|
|
|
|
|
|
4229
|
|
|
|
|
|
|
# INIT is removed from the symbol table, so this call must come |
4230
|
|
|
|
|
|
|
# from PL_initav->save. Re-bootstrapping will push INIT back in, |
4231
|
|
|
|
|
|
|
# so nullop should be sent. |
4232
|
0
|
0
|
|
|
|
0
|
warn $fullname."\n" if $debug{sub}; |
4233
|
0
|
|
|
|
|
0
|
return qq/NULL/; |
4234
|
|
|
|
|
|
|
} |
4235
|
|
|
|
|
|
|
else { |
4236
|
|
|
|
|
|
|
# XSUBs for IO::File, IO::Handle, IO::Socket, IO::Seekable and IO::Poll |
4237
|
|
|
|
|
|
|
# are defined in IO.xs, so let's bootstrap it |
4238
|
0
|
|
|
|
|
0
|
my @IO = qw(IO::File IO::Handle IO::Socket IO::Seekable IO::Poll); |
4239
|
0
|
0
|
|
|
|
0
|
if (grep { $stashname eq $_ } @IO) { |
|
0
|
|
|
|
|
0
|
|
4240
|
|
|
|
|
|
|
# mark_package('IO', 1); |
4241
|
|
|
|
|
|
|
# $xsub{IO} = 'Dynamic-'. $INC{'IO.pm'}; # XSLoader (issue59) |
4242
|
0
|
|
|
|
|
0
|
svref_2object( \&IO::bootstrap )->save; |
4243
|
0
|
|
|
|
|
0
|
mark_package('IO::Handle', 1); |
4244
|
0
|
|
|
|
|
0
|
mark_package('SelectSaver', 1); |
4245
|
|
|
|
|
|
|
#for (@IO) { # mark all IO packages |
4246
|
|
|
|
|
|
|
# mark_package($_, 1); |
4247
|
|
|
|
|
|
|
#} |
4248
|
|
|
|
|
|
|
} |
4249
|
|
|
|
|
|
|
} |
4250
|
0
|
0
|
|
|
|
0
|
warn $fullname."\n" if $debug{sub}; |
4251
|
0
|
0
|
|
|
|
0
|
unless ( in_static_core($stashname, $cvname) ) { |
4252
|
55
|
|
|
55
|
|
259
|
no strict 'refs'; |
|
55
|
|
|
|
|
74
|
|
|
55
|
|
|
|
|
5690
|
|
4253
|
|
|
|
|
|
|
warn sprintf( "XSUB $fullname CV 0x%x\n", $$cv ) |
4254
|
0
|
0
|
|
|
|
0
|
if $debug{cv}; |
4255
|
0
|
0
|
|
|
|
0
|
svref_2object( \*{"$stashname\::bootstrap"} )->save |
|
0
|
|
|
|
|
0
|
|
4256
|
|
|
|
|
|
|
if $stashname;# and defined ${"$stashname\::bootstrap"}; |
4257
|
|
|
|
|
|
|
# delsym($cv); |
4258
|
0
|
|
|
|
|
0
|
return get_cv($fullname, 0); |
4259
|
|
|
|
|
|
|
} else { # Those cvs are already booted. Reuse their GP. |
4260
|
|
|
|
|
|
|
# Esp. on windows it is impossible to get at the XS function ptr |
4261
|
0
|
0
|
|
|
|
0
|
warn sprintf( "core XSUB $fullname CV 0x%x\n", $$cv ) if $debug{cv}; |
4262
|
0
|
|
|
|
|
0
|
return get_cv($fullname, 0); |
4263
|
|
|
|
|
|
|
} |
4264
|
|
|
|
|
|
|
} |
4265
|
0
|
0
|
0
|
|
|
0
|
if ( !$isconst && $cvxsub && $cvname eq "INIT" ) { |
|
|
|
0
|
|
|
|
|
4266
|
55
|
|
|
55
|
|
214
|
no strict 'refs'; |
|
55
|
|
|
|
|
75
|
|
|
55
|
|
|
|
|
48695
|
|
4267
|
0
|
0
|
|
|
|
0
|
warn $fullname."\n" if $debug{sub}; |
4268
|
0
|
|
|
|
|
0
|
return svref_2object( \&Dummy_initxs )->save; |
4269
|
|
|
|
|
|
|
} |
4270
|
|
|
|
|
|
|
|
4271
|
|
|
|
|
|
|
# XXX how is ANON with CONST handled? CONST uses XSUBANY [GH #246] |
4272
|
0
|
0
|
0
|
|
|
0
|
if ($isconst and $cvxsub and !is_phase_name($cvname) and |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
4273
|
|
|
|
|
|
|
( |
4274
|
|
|
|
|
|
|
( |
4275
|
|
|
|
|
|
|
$PERL522 |
4276
|
|
|
|
|
|
|
and !( $CvFLAGS & SVs_PADSTALE ) |
4277
|
|
|
|
|
|
|
and !( $CvFLAGS & CVf_WEAKOUTSIDE ) |
4278
|
|
|
|
|
|
|
and !( $fullname && $fullname =~ qr{^File::Glob::GLOB} |
4279
|
|
|
|
|
|
|
and ( $CvFLAGS & (CVf_ANONCONST|CVf_CONST) ) ) |
4280
|
|
|
|
|
|
|
) |
4281
|
|
|
|
|
|
|
or (!$PERL522 and !($CvFLAGS & CVf_ANON)) ) |
4282
|
|
|
|
|
|
|
) # skip const magic blocks (Attribute::Handlers) |
4283
|
|
|
|
|
|
|
{ |
4284
|
0
|
|
|
|
|
0
|
my $stash = $gv->STASH; |
4285
|
|
|
|
|
|
|
#warn sprintf("$cvstashname\::$cvname 0x%x -> XSUBANY", $CvFLAGS) if $debug{cv}; |
4286
|
0
|
|
|
|
|
0
|
my $sv = $cv->XSUBANY; |
4287
|
|
|
|
|
|
|
warn sprintf( "CV CONST 0x%x %s::%s -> 0x%x as %s\n", $$gv, $cvstashname, $cvname, |
4288
|
0
|
0
|
|
|
|
0
|
$sv, ref $sv) if $debug{cv}; |
4289
|
|
|
|
|
|
|
# warn sprintf( "%s::%s\n", $cvstashname, $cvname) if $debug{sub}; |
4290
|
0
|
|
|
|
|
0
|
my $stsym = $stash->save; |
4291
|
0
|
|
|
|
|
0
|
my $name = cstring($cvname); |
4292
|
0
|
0
|
|
|
|
0
|
if ($] >= 5.016) { # need to check 'Encode::XS' constant encodings |
4293
|
|
|
|
|
|
|
# warn "$sv CONSTSUB $name"; |
4294
|
0
|
0
|
0
|
|
|
0
|
if ((ref($sv) eq 'B::IV' or ref($sv) eq 'B::PVMG') and $sv->FLAGS & SVf_ROK) { |
|
|
|
0
|
|
|
|
|
4295
|
0
|
|
|
|
|
0
|
my $rv = $sv->RV; |
4296
|
0
|
0
|
0
|
|
|
0
|
if ($rv->FLAGS & (SVp_POK|SVf_IOK) and $rv->IVX > LOWEST_IMAGEBASE) { |
4297
|
0
|
|
|
|
|
0
|
patch_dlsym($rv, $fullname, $rv->IVX); |
4298
|
|
|
|
|
|
|
} |
4299
|
|
|
|
|
|
|
} |
4300
|
|
|
|
|
|
|
} |
4301
|
|
|
|
|
|
|
# scalarref: t/CORE/v5.22/t/op/const-optree.t at curpad_syms[6] |
4302
|
|
|
|
|
|
|
# main::__ANON__ -> CxPOPSUB_DONE=SCALAR |
4303
|
|
|
|
|
|
|
# TODO Attribute::Handlers #171, test 176 |
4304
|
0
|
0
|
0
|
|
|
0
|
if ($sv and ref($sv) and ref($sv) =~ /^(SCALAR|ARRAY|HASH|CODE|REF)$/) { |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
4305
|
|
|
|
|
|
|
# Save XSUBANY, maybe ARRAY or HASH also? |
4306
|
0
|
0
|
|
|
|
0
|
warn "SCALAR const sub $cvstashname::$cvname -> $sv\n" if $debug{cv}; |
4307
|
0
|
|
|
|
|
0
|
my $vsym = svref_2object( \$sv )->save; |
4308
|
0
|
|
|
|
|
0
|
my $cvi = "cv".$cv_index++; |
4309
|
0
|
|
|
|
|
0
|
$decl->add("Static CV* $cvi;"); |
4310
|
0
|
|
|
|
|
0
|
$init->add("$cvi = newCONSTSUB( $stsym, $name, (SV*)$vsym );"); |
4311
|
0
|
|
|
|
|
0
|
return savesym( $cv, $cvi ); |
4312
|
|
|
|
|
|
|
} |
4313
|
|
|
|
|
|
|
elsif ($sv and ref($sv) =~ /^B::[ANRPI]/) { # use constant => () |
4314
|
0
|
|
|
|
|
0
|
my $vsym = $sv->save; |
4315
|
0
|
|
|
|
|
0
|
my $cvi = "cv".$cv_index++; |
4316
|
0
|
|
|
|
|
0
|
$decl->add("Static CV* $cvi;"); |
4317
|
0
|
|
|
|
|
0
|
$init->add("$cvi = newCONSTSUB( $stsym, $name, (SV*)$vsym );"); |
4318
|
0
|
|
|
|
|
0
|
return savesym( $cv, $cvi ); |
4319
|
|
|
|
|
|
|
} else { |
4320
|
0
|
0
|
|
|
|
0
|
warn "Warning: Undefined const sub $cvstashname::$cvname -> $sv\n" if $verbose; |
4321
|
|
|
|
|
|
|
} |
4322
|
|
|
|
|
|
|
} |
4323
|
|
|
|
|
|
|
|
4324
|
|
|
|
|
|
|
# This define is forwarded to the real sv below |
4325
|
|
|
|
|
|
|
# The new method, which saves a SV only works since 5.10 (? Does not work in newer perls) |
4326
|
0
|
|
|
|
|
0
|
my $sv_ix = $svsect->index + 1; |
4327
|
0
|
|
|
|
|
0
|
my $xpvcv_ix; |
4328
|
0
|
|
|
|
|
0
|
my $new_cv_fw = 0;#$PERL510; # XXX this does not work yet |
4329
|
0
|
0
|
|
|
|
0
|
if ($new_cv_fw) { |
4330
|
0
|
|
|
|
|
0
|
$sym = savesym( $cv, "CVIX$sv_ix" ); |
4331
|
|
|
|
|
|
|
} else { |
4332
|
0
|
|
|
|
|
0
|
$svsect->add("CVIX$sv_ix"); |
4333
|
0
|
0
|
|
|
|
0
|
$svsect->debug( "&".$fullname, $cv->flagspv ) if $debug{flags}; |
4334
|
0
|
|
|
|
|
0
|
$xpvcv_ix = $xpvcvsect->index + 1; |
4335
|
0
|
|
|
|
|
0
|
$xpvcvsect->add("XPVCVIX$xpvcv_ix"); |
4336
|
|
|
|
|
|
|
# Save symbol now so that GvCV() doesn't recurse back to us via CvGV() |
4337
|
0
|
|
|
|
|
0
|
$sym = savesym( $cv, "&sv_list[$sv_ix]" ); |
4338
|
|
|
|
|
|
|
} |
4339
|
|
|
|
|
|
|
|
4340
|
|
|
|
|
|
|
warn sprintf( "saving %s CV 0x%x as %s\n", $fullname, $$cv, $sym ) |
4341
|
0
|
0
|
|
|
|
0
|
if $debug{cv}; |
4342
|
0
|
0
|
0
|
|
|
0
|
if (!$$root and $] < 5.010) { |
4343
|
0
|
|
|
|
|
0
|
$package_pv = $cvstashname; |
4344
|
0
|
|
|
|
|
0
|
push_package($package_pv); |
4345
|
|
|
|
|
|
|
} |
4346
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'utf8::SWASHNEW') { # bypass utf8::AUTOLOAD, a new 5.13.9 mess |
4347
|
0
|
|
|
|
|
0
|
load_utf8_heavy(); |
4348
|
|
|
|
|
|
|
} |
4349
|
|
|
|
|
|
|
|
4350
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'IO::Socket::SSL::SSL_Context::new') { |
4351
|
0
|
0
|
0
|
|
|
0
|
if ($IO::Socket::SSL::VERSION ge '1.956' and $IO::Socket::SSL::VERSION lt '1.995') { |
4352
|
|
|
|
|
|
|
# See https://code.google.com/p/perl-compiler/issues/detail?id=317 |
4353
|
|
|
|
|
|
|
# https://rt.cpan.org/Ticket/Display.html?id=95452 |
4354
|
0
|
|
|
|
|
0
|
warn "Warning: Your IO::Socket::SSL version $IO::Socket::SSL::VERSION is unsupported to create\n". |
4355
|
|
|
|
|
|
|
" a server. You need to upgrade IO::Socket::SSL to at least 1.995 [CPAN #95452]\n"; |
4356
|
|
|
|
|
|
|
} |
4357
|
|
|
|
|
|
|
} |
4358
|
|
|
|
|
|
|
|
4359
|
0
|
0
|
0
|
|
|
0
|
if (!$$root && !$cvxsub) { |
4360
|
0
|
|
|
|
|
0
|
my $reloaded; |
4361
|
0
|
0
|
|
|
|
0
|
if ($cvstashname =~ /^(bytes|utf8)$/) { # no autoload, force compile-time |
|
|
0
|
|
|
|
|
|
4362
|
0
|
|
|
|
|
0
|
force_heavy($cvstashname); |
4363
|
0
|
|
|
|
|
0
|
$cv = svref_2object( \&{"$cvstashname\::$cvname"} ); |
|
0
|
|
|
|
|
0
|
|
4364
|
0
|
|
|
|
|
0
|
$reloaded = 1; |
4365
|
|
|
|
|
|
|
} elsif ($fullname eq 'Coro::State::_jit') { # 293 |
4366
|
|
|
|
|
|
|
# need to force reload the jit src |
4367
|
0
|
|
|
|
|
0
|
my ($pl) = grep { m|^Coro/jit-| } keys %INC; |
|
0
|
|
|
|
|
0
|
|
4368
|
0
|
0
|
|
|
|
0
|
if ($pl) { |
4369
|
0
|
|
|
|
|
0
|
delete $INC{$pl}; |
4370
|
0
|
|
|
|
|
0
|
require $pl; |
4371
|
0
|
|
|
|
|
0
|
$cv = svref_2object( \&{$fullname} ); |
|
0
|
|
|
|
|
0
|
|
4372
|
0
|
|
|
|
|
0
|
$reloaded = 1; |
4373
|
|
|
|
|
|
|
} |
4374
|
|
|
|
|
|
|
} |
4375
|
0
|
0
|
|
|
|
0
|
if ($reloaded) { |
4376
|
0
|
|
|
|
|
0
|
$gv = $cv->GV; |
4377
|
|
|
|
|
|
|
warn sprintf( "Redefined CV 0x%x as PVGV 0x%x %s CvFLAGS=0x%x\n", |
4378
|
0
|
0
|
|
|
|
0
|
$$cv, $$gv, $fullname, $CvFLAGS ) if $debug{cv}; |
4379
|
0
|
|
|
|
|
0
|
$sym = savesym( $cv, $sym ); |
4380
|
0
|
|
|
|
|
0
|
$root = $cv->ROOT; |
4381
|
0
|
|
|
|
|
0
|
$cvxsub = $cv->XSUB; |
4382
|
|
|
|
|
|
|
} |
4383
|
|
|
|
|
|
|
} |
4384
|
0
|
0
|
0
|
|
|
0
|
if ( !$$root && !$cvxsub ) { |
4385
|
0
|
0
|
|
|
|
0
|
if ( my $auto = try_autoload( $cvstashname, $cvname ) ) { |
4386
|
0
|
0
|
|
|
|
0
|
if (ref $auto eq 'B::CV') { # explicit goto or UNIVERSAL |
4387
|
0
|
|
|
|
|
0
|
$root = $auto->ROOT; |
4388
|
0
|
|
|
|
|
0
|
$cvxsub = $auto->XSUB; |
4389
|
0
|
0
|
|
|
|
0
|
if ($$auto) { |
4390
|
|
|
|
|
|
|
# XXX This has now created a wrong GV name! |
4391
|
0
|
|
|
|
|
0
|
my $oldcv = $cv; |
4392
|
0
|
|
|
|
|
0
|
$cv = $auto ; # This is new. i.e. via AUTOLOAD or UNIVERSAL, in another stash |
4393
|
0
|
|
|
|
|
0
|
my $gvnew = $cv->GV; |
4394
|
0
|
0
|
|
|
|
0
|
if ($$gvnew) { |
4395
|
0
|
0
|
0
|
|
|
0
|
if ($cvstashname ne $gvnew->STASH->NAME or $cvname ne $gvnew->NAME) { # UNIVERSAL or AUTOLOAD |
4396
|
0
|
|
|
|
|
0
|
my $newname = $gvnew->STASH->NAME."::".$gvnew->NAME; |
4397
|
0
|
0
|
|
|
|
0
|
warn " New $newname autoloaded. remove old cv\n" if $debug{sub}; # and wrong GV? |
4398
|
0
|
0
|
|
|
|
0
|
unless ($new_cv_fw) { |
4399
|
0
|
|
|
|
|
0
|
$svsect->remove; |
4400
|
0
|
|
|
|
|
0
|
$xpvcvsect->remove; |
4401
|
|
|
|
|
|
|
} |
4402
|
0
|
|
|
|
|
0
|
delsym($oldcv); |
4403
|
0
|
0
|
|
|
|
0
|
return $cv->save($newname) if !$PERL510; |
4404
|
|
|
|
|
|
|
|
4405
|
55
|
|
|
55
|
|
272
|
no strict 'refs'; |
|
55
|
|
|
|
|
71
|
|
|
55
|
|
|
|
|
266326
|
|
4406
|
0
|
|
|
|
|
0
|
my $newsym = svref_2object( \*{$newname} )->save; |
|
0
|
|
|
|
|
0
|
|
4407
|
0
|
0
|
|
|
|
0
|
my $cvsym = defined objsym($cv) ? objsym($cv) : $cv->save($newname); |
4408
|
0
|
0
|
|
|
|
0
|
if (my $oldsym = objsym($gv)) { |
4409
|
0
|
0
|
|
|
|
0
|
warn "Alias polluted $oldsym to $newsym\n" if $debug{gv}; |
4410
|
0
|
|
|
|
|
0
|
$init->add("$oldsym = $newsym;"); |
4411
|
0
|
|
|
|
|
0
|
delsym($gv); |
4412
|
|
|
|
|
|
|
}# else { |
4413
|
|
|
|
|
|
|
#$init->add("GvCV_set(gv_fetchpv(\"$fullname\", GV_ADD, SVt_PV), (CV*)NULL);"); |
4414
|
|
|
|
|
|
|
#} |
4415
|
0
|
|
|
|
|
0
|
return $cvsym; |
4416
|
|
|
|
|
|
|
} |
4417
|
|
|
|
|
|
|
} |
4418
|
0
|
|
|
|
|
0
|
$sym = savesym( $cv, "&sv_list[$sv_ix]" ); # GOTO |
4419
|
0
|
0
|
|
|
|
0
|
warn "$fullname GOTO\n" if $verbose; |
4420
|
|
|
|
|
|
|
} |
4421
|
|
|
|
|
|
|
} else { |
4422
|
|
|
|
|
|
|
# Recalculated root and xsub |
4423
|
0
|
|
|
|
|
0
|
$root = $cv->ROOT; |
4424
|
0
|
|
|
|
|
0
|
$cvxsub = $cv->XSUB; |
4425
|
0
|
|
|
|
|
0
|
my $gv = $cv->GV; |
4426
|
0
|
0
|
|
|
|
0
|
if ($$gv) { |
4427
|
0
|
0
|
0
|
|
|
0
|
if ($cvstashname ne $gv->STASH->NAME or $cvname ne $gv->NAME) { # UNIVERSAL or AUTOLOAD |
4428
|
0
|
|
|
|
|
0
|
my $newname = $gv->STASH->NAME."::".$gv->NAME; |
4429
|
0
|
0
|
|
|
|
0
|
warn "Recalculated root and xsub $newname. remove old cv\n" if $verbose; |
4430
|
0
|
|
|
|
|
0
|
$svsect->remove; |
4431
|
0
|
|
|
|
|
0
|
$xpvcvsect->remove; |
4432
|
0
|
|
|
|
|
0
|
delsym($cv); |
4433
|
0
|
|
|
|
|
0
|
return $cv->save($newname); |
4434
|
|
|
|
|
|
|
} |
4435
|
|
|
|
|
|
|
} |
4436
|
|
|
|
|
|
|
} |
4437
|
0
|
0
|
0
|
|
|
0
|
if ( $$root || $cvxsub ) { |
4438
|
0
|
0
|
0
|
|
|
0
|
warn "Successful forced autoload\n" if $verbose and $debug{cv}; |
4439
|
|
|
|
|
|
|
} |
4440
|
|
|
|
|
|
|
} |
4441
|
|
|
|
|
|
|
} |
4442
|
0
|
0
|
|
|
|
0
|
if (!$$root) { |
4443
|
0
|
0
|
0
|
|
|
0
|
if ($fullname ne 'threads::tid' |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
4444
|
|
|
|
|
|
|
and $fullname ne 'main::main::' |
4445
|
0
|
|
|
|
|
0
|
and ($PERL510 and !defined(&{"$cvstashname\::AUTOLOAD"}))) |
4446
|
|
|
|
|
|
|
{ |
4447
|
|
|
|
|
|
|
# XXX What was here? |
4448
|
|
|
|
|
|
|
} |
4449
|
0
|
0
|
|
|
|
0
|
if (exists &$fullname) { |
|
|
0
|
|
|
|
|
|
4450
|
0
|
0
|
|
|
|
0
|
warn "Warning: Empty &".$fullname."\n" if $debug{sub}; |
4451
|
0
|
0
|
0
|
|
|
0
|
$init->add( "/* empty CV $fullname */" ) if $verbose or $debug{sub}; |
4452
|
|
|
|
|
|
|
} elsif ($cv->is_lexsub($gv)) { |
4453
|
|
|
|
|
|
|
# need to find the attached lexical sub (#130 + #341) at run-time |
4454
|
|
|
|
|
|
|
# in the PadNAMES array. So keep the empty PVCV |
4455
|
0
|
0
|
|
|
|
0
|
warn "lexsub &".$fullname." saved as empty $sym\n" if $debug{sub}; |
4456
|
|
|
|
|
|
|
} else { |
4457
|
0
|
0
|
|
|
|
0
|
warn "Warning: &".$fullname." not found\n" if $debug{sub}; |
4458
|
0
|
0
|
0
|
|
|
0
|
$init->add( "/* CV $fullname not found */" ) if $verbose or $debug{sub}; |
4459
|
|
|
|
|
|
|
# This block broke test 15, disabled |
4460
|
0
|
0
|
0
|
|
|
0
|
if ($sv_ix == $svsect->index and !$new_cv_fw) { # can delete, is the last SV |
4461
|
|
|
|
|
|
|
warn "No definition for sub $fullname (unable to autoload), skip CV[$sv_ix]\n" |
4462
|
0
|
0
|
|
|
|
0
|
if $debug{cv}; |
4463
|
0
|
|
|
|
|
0
|
$svsect->remove; |
4464
|
0
|
|
|
|
|
0
|
$xpvcvsect->remove; |
4465
|
0
|
|
|
|
|
0
|
delsym( $cv ); |
4466
|
|
|
|
|
|
|
# Empty CV (methods) must be skipped not to disturb method resolution |
4467
|
|
|
|
|
|
|
# (e.g. t/testm.sh POSIX) |
4468
|
0
|
|
|
|
|
0
|
return '0'; |
4469
|
|
|
|
|
|
|
} else { |
4470
|
|
|
|
|
|
|
# interim &AUTOLOAD saved, cannot delete. e.g. Fcntl, POSIX |
4471
|
|
|
|
|
|
|
warn "No definition for sub $fullname (unable to autoload), stub CV[$sv_ix]\n" |
4472
|
0
|
0
|
0
|
|
|
0
|
if $debug{cv} or $verbose; |
4473
|
|
|
|
|
|
|
# continue, must save the 2 symbols from above |
4474
|
|
|
|
|
|
|
} |
4475
|
|
|
|
|
|
|
} |
4476
|
|
|
|
|
|
|
} |
4477
|
|
|
|
|
|
|
|
4478
|
0
|
|
|
|
|
0
|
my $startfield = 0; |
4479
|
0
|
|
|
|
|
0
|
my $padlist = $cv->PADLIST; |
4480
|
0
|
|
|
|
|
0
|
set_curcv $cv; |
4481
|
0
|
|
|
|
|
0
|
my $padlistsym = 'NULL'; |
4482
|
0
|
|
|
|
|
0
|
my $pv = $cv->PV; |
4483
|
0
|
|
|
|
|
0
|
my $xsub = 0; |
4484
|
0
|
|
|
|
|
0
|
my $xsubany = "{0}"; |
4485
|
0
|
0
|
|
|
|
0
|
if ($$root) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
4486
|
|
|
|
|
|
|
warn sprintf( "saving op tree for CV 0x%x, root=0x%x\n", |
4487
|
|
|
|
|
|
|
$$cv, $$root ) |
4488
|
0
|
0
|
0
|
|
|
0
|
if $debug{cv} and $debug{gv}; |
4489
|
0
|
|
|
|
|
0
|
my $ppname = ""; |
4490
|
0
|
0
|
0
|
|
|
0
|
if ($cv->is_lexsub($gv)) { |
|
|
0
|
|
|
|
|
|
4491
|
0
|
0
|
|
|
|
0
|
my $name = $cv->can('NAME_HEK') ? $cv->NAME_HEK : "anonlex"; |
4492
|
0
|
|
|
|
|
0
|
$ppname = "pp_lexsub_".$name; |
4493
|
0
|
|
|
|
|
0
|
$fullname = "".$name; |
4494
|
|
|
|
|
|
|
} |
4495
|
|
|
|
|
|
|
elsif ($gv and $$gv) { |
4496
|
0
|
|
|
|
|
0
|
my ($stashname, $gvname); |
4497
|
0
|
|
|
|
|
0
|
$stashname = $gv->STASH->NAME; |
4498
|
0
|
|
|
|
|
0
|
$gvname = $gv->NAME; |
4499
|
0
|
|
|
|
|
0
|
$fullname = $stashname.'::'.$gvname; |
4500
|
0
|
0
|
|
|
|
0
|
$ppname = ( ${ $gv->FORM } == $$cv ) ? "pp_form_" : "pp_sub_"; |
|
0
|
|
|
|
|
0
|
|
4501
|
0
|
0
|
|
|
|
0
|
if ( $gvname ne "__ANON__" ) { |
4502
|
0
|
0
|
|
|
|
0
|
$ppname .= ( $stashname eq "main" ) ? $gvname : "$stashname\::$gvname"; |
4503
|
0
|
|
|
|
|
0
|
$ppname =~ s/::/__/g; |
4504
|
0
|
|
|
|
|
0
|
$ppname =~ s/(\W)/sprintf("0x%x", ord($1))/ge; |
|
0
|
|
|
|
|
0
|
|
4505
|
0
|
0
|
|
|
|
0
|
if ( $gvname eq "INIT" ) { |
4506
|
0
|
|
|
|
|
0
|
$ppname .= "_$initsub_index"; |
4507
|
0
|
|
|
|
|
0
|
$initsub_index++; |
4508
|
|
|
|
|
|
|
} |
4509
|
|
|
|
|
|
|
} |
4510
|
|
|
|
|
|
|
} |
4511
|
0
|
0
|
|
|
|
0
|
if ( !$ppname ) { |
4512
|
0
|
|
|
|
|
0
|
$ppname = "pp_anonsub_$anonsub_index"; |
4513
|
0
|
|
|
|
|
0
|
$anonsub_index++; |
4514
|
|
|
|
|
|
|
} |
4515
|
0
|
|
|
|
|
0
|
$startfield = saveoptree( $ppname, $root, $cv->START, $padlist->ARRAY ); # XXX padlist is ignored |
4516
|
|
|
|
|
|
|
#warn sprintf( "done saving op tree for CV 0x%x, flags (%s), name %s, root=0x%x => start=%s\n", |
4517
|
|
|
|
|
|
|
# $$cv, $debug{flags}?$cv->flagspv:sprintf("0x%x",$cv->FLAGS), $ppname, $$root, $startfield ) |
4518
|
|
|
|
|
|
|
# if $debug{cv}; |
4519
|
|
|
|
|
|
|
# XXX missing cv_start for AUTOLOAD on 5.8 |
4520
|
0
|
0
|
|
|
|
0
|
$startfield = objsym($root->next) unless $startfield; # 5.8 autoload has only root |
4521
|
0
|
0
|
|
|
|
0
|
$startfield = "0" unless $startfield; # XXX either CONST ANON or empty body |
4522
|
0
|
0
|
|
|
|
0
|
if ($$padlist) { |
4523
|
|
|
|
|
|
|
# XXX readonly comppad names and symbols invalid |
4524
|
|
|
|
|
|
|
#local $B::C::pv_copy_on_grow = 1 if $B::C::ro_inc; |
4525
|
|
|
|
|
|
|
warn sprintf( "saving PADLIST 0x%x for CV 0x%x\n", $$padlist, $$cv ) |
4526
|
0
|
0
|
0
|
|
|
0
|
if $debug{cv} and $debug{gv}; |
4527
|
|
|
|
|
|
|
# XXX avlen 2 |
4528
|
0
|
|
|
|
|
0
|
$padlistsym = $padlist->save($fullname.' :pad', $cv); |
4529
|
|
|
|
|
|
|
warn sprintf( "done saving %s 0x%x for CV 0x%x\n", |
4530
|
|
|
|
|
|
|
$padlistsym, $$padlist, $$cv ) |
4531
|
0
|
0
|
0
|
|
|
0
|
if $debug{cv} and $debug{gv}; |
4532
|
|
|
|
|
|
|
# do not record a forward for the pad only |
4533
|
|
|
|
|
|
|
|
4534
|
|
|
|
|
|
|
# issue 298: dynamic CvPADLIST(&END) since 5.18 - END{} blocks |
4535
|
|
|
|
|
|
|
# and #169 and #304 Attribute::Handlers |
4536
|
0
|
0
|
0
|
|
|
0
|
if ($] > 5.017 and |
|
|
|
0
|
|
|
|
|
4537
|
|
|
|
|
|
|
($B::C::dyn_padlist or $fullname =~ /^(main::END|main::INIT|Attribute::Handlers)/)) |
4538
|
|
|
|
|
|
|
{ |
4539
|
0
|
|
|
|
|
0
|
$init->add("{ /* &$fullname needs a dynamic padlist */", |
4540
|
|
|
|
|
|
|
" PADLIST *pad;", |
4541
|
|
|
|
|
|
|
" Newxz(pad, sizeof(PADLIST), PADLIST);", |
4542
|
|
|
|
|
|
|
" Copy($padlistsym, pad, sizeof(PADLIST), char);", |
4543
|
|
|
|
|
|
|
" CvPADLIST($sym) = pad;", |
4544
|
|
|
|
|
|
|
"}"); |
4545
|
|
|
|
|
|
|
} else { |
4546
|
0
|
|
|
|
|
0
|
$init->add( "CvPADLIST($sym) = $padlistsym;" ); |
4547
|
|
|
|
|
|
|
} |
4548
|
|
|
|
|
|
|
} |
4549
|
0
|
0
|
|
|
|
0
|
warn $fullname."\n" if $debug{sub}; |
4550
|
|
|
|
|
|
|
} |
4551
|
|
|
|
|
|
|
elsif ($cv->is_lexsub($gv)) { |
4552
|
|
|
|
|
|
|
; |
4553
|
|
|
|
|
|
|
} |
4554
|
|
|
|
|
|
|
elsif (!exists &$fullname) { |
4555
|
0
|
0
|
|
|
|
0
|
warn $fullname." not found\n" if $debug{sub}; |
4556
|
|
|
|
|
|
|
warn "No definition for sub $fullname (unable to autoload)\n" |
4557
|
0
|
0
|
|
|
|
0
|
if $debug{cv}; |
4558
|
0
|
0
|
0
|
|
|
0
|
$init->add( "/* $fullname not found */" ) if $verbose or $debug{sub}; |
4559
|
|
|
|
|
|
|
# XXX empty CV should not be saved. #159, #235 |
4560
|
|
|
|
|
|
|
# $svsect->remove( $sv_ix ); |
4561
|
|
|
|
|
|
|
# $xpvcvsect->remove( $xpvcv_ix ); |
4562
|
|
|
|
|
|
|
# delsym( $cv ); |
4563
|
0
|
0
|
|
|
|
0
|
if (!$new_cv_fw) { |
4564
|
0
|
|
|
|
|
0
|
$symsect->add("XPVCVIX$xpvcv_ix\t0"); |
4565
|
|
|
|
|
|
|
} |
4566
|
0
|
0
|
|
|
|
0
|
$CvFLAGS &= ~0x1000 if $PERL514; # CVf_DYNFILE |
4567
|
0
|
0
|
0
|
|
|
0
|
$CvFLAGS &= ~0x400 if $gv and $$gv and $PERL514; #CVf_CVGV_RC |
|
|
|
0
|
|
|
|
|
4568
|
0
|
0
|
|
|
|
0
|
$symsect->add(sprintf( |
4569
|
|
|
|
|
|
|
"CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x".($PERL510?", {0}":''), |
4570
|
|
|
|
|
|
|
$sv_ix, $xpvcv_ix, $cv->REFCNT, $CvFLAGS)); |
4571
|
0
|
|
|
|
|
0
|
return get_cv($fullname, 0); |
4572
|
|
|
|
|
|
|
} |
4573
|
|
|
|
|
|
|
|
4574
|
|
|
|
|
|
|
# Now it is time to record the CV |
4575
|
0
|
0
|
|
|
|
0
|
if ($new_cv_fw) { |
4576
|
0
|
|
|
|
|
0
|
$sv_ix = $svsect->index + 1; |
4577
|
0
|
0
|
|
|
|
0
|
if (!$cvforward{$sym}) { # avoid duplicates |
4578
|
0
|
|
|
|
|
0
|
$symsect->add(sprintf("%s\t&sv_list[%d]", $sym, $sv_ix )); # forward the old CVIX to the new CV |
4579
|
0
|
|
|
|
|
0
|
$cvforward{$sym}++; |
4580
|
|
|
|
|
|
|
} |
4581
|
0
|
|
|
|
|
0
|
$sym = savesym( $cv, "&sv_list[$sv_ix]" ); |
4582
|
|
|
|
|
|
|
} |
4583
|
|
|
|
|
|
|
|
4584
|
|
|
|
|
|
|
# $pv = '' unless defined $pv; # Avoid use of undef warnings |
4585
|
|
|
|
|
|
|
#warn sprintf( "CV prototype %s for CV 0x%x\n", cstring($pv), $$cv ) |
4586
|
|
|
|
|
|
|
# if $pv and $debug{cv}; |
4587
|
0
|
0
|
|
|
|
0
|
my $proto = defined $pv ? cstring($pv) : 'NULL'; |
4588
|
0
|
|
|
|
|
0
|
my $pvsym = 'NULL'; |
4589
|
0
|
0
|
|
|
|
0
|
my $cur = defined $pv ? $cv->CUR : 0; |
4590
|
0
|
|
|
|
|
0
|
my $len = $cur + 1; |
4591
|
0
|
0
|
0
|
|
|
0
|
$len++ if IsCOW($cv) and !$B::C::cow; |
4592
|
0
|
0
|
|
|
|
0
|
$len = 0 if $B::C::const_strings; |
4593
|
|
|
|
|
|
|
# need to survive cv_undef as there is no protection against static CVs |
4594
|
0
|
0
|
|
|
|
0
|
my $refcnt = $cv->REFCNT + ($PERL510 ? 1 : 0); |
4595
|
|
|
|
|
|
|
# GV cannot be initialized statically |
4596
|
0
|
|
|
|
|
0
|
my $xcv_outside = ${ $cv->OUTSIDE }; |
|
0
|
|
|
|
|
0
|
|
4597
|
0
|
0
|
0
|
|
|
0
|
if ($xcv_outside == ${ main_cv() } and !$MULTI) { |
|
0
|
0
|
|
|
|
0
|
|
4598
|
|
|
|
|
|
|
# Provide a temp. debugging hack for CvOUTSIDE. The address of the symbol &PL_main_cv |
4599
|
|
|
|
|
|
|
# is known to the linker, the address of the value PL_main_cv not. This is set later |
4600
|
|
|
|
|
|
|
# (below) at run-time. |
4601
|
0
|
|
|
|
|
0
|
$xcv_outside = '&PL_main_cv'; |
4602
|
|
|
|
|
|
|
} elsif (ref($cv->OUTSIDE) eq 'B::CV') { |
4603
|
0
|
|
|
|
|
0
|
$xcv_outside = 0; # just a placeholder for a run-time GV |
4604
|
|
|
|
|
|
|
} |
4605
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
|
|
0
|
|
|
|
|
|
4606
|
0
|
|
|
|
|
0
|
$pvsym = save_hek($pv,$fullname,1); |
4607
|
|
|
|
|
|
|
# XXX issue 84: we need to check the cv->PV ptr not the value. |
4608
|
|
|
|
|
|
|
# "" is different to NULL for prototypes |
4609
|
0
|
0
|
|
|
|
0
|
$len = $cur ? $cur+1 : 0; |
4610
|
|
|
|
|
|
|
# TODO: |
4611
|
|
|
|
|
|
|
# my $ourstash = "0"; # TODO stash name to bless it (test 16: "main::") |
4612
|
0
|
0
|
|
|
|
0
|
if ($PERL522) { |
|
|
0
|
|
|
|
|
|
4613
|
0
|
|
|
|
|
0
|
$CvFLAGS &= ~0x1000; # CVf_DYNFILE off |
4614
|
0
|
0
|
|
|
|
0
|
$CvFLAGS |= 0x200000 if $CPERL52; # CVf_STATIC on |
4615
|
0
|
|
|
|
|
0
|
my $xpvc = sprintf |
4616
|
|
|
|
|
|
|
# stash magic cur {len} cvstash {start} {root} {cvgv} cvfile {cvpadlist} outside outside_seq cvflags cvdepth |
4617
|
|
|
|
|
|
|
("Nullhv, {0}, %u, {%u}, %s, {%s}, {s\\_%x}, {%s}, %s, {%s}, (CV*)%s, %s, 0x%x, %d", |
4618
|
|
|
|
|
|
|
$cur, $len, "Nullhv",#CvSTASH later |
4619
|
|
|
|
|
|
|
$startfield, $$root, |
4620
|
|
|
|
|
|
|
"0", #GV later |
4621
|
|
|
|
|
|
|
"NULL", #cvfile later (now a HEK) |
4622
|
|
|
|
|
|
|
$padlistsym, |
4623
|
|
|
|
|
|
|
$xcv_outside, #if main_cv set later |
4624
|
|
|
|
|
|
|
ivx($cv->OUTSIDE_SEQ), |
4625
|
|
|
|
|
|
|
$CvFLAGS, |
4626
|
|
|
|
|
|
|
$cv->DEPTH); |
4627
|
|
|
|
|
|
|
# repro only with 5.15.* threaded -q (70c0620) Encode::Alias::define_alias |
4628
|
0
|
0
|
|
|
|
0
|
warn "lexwarnsym in XPVCV OUTSIDE: $xpvc" if $xpvc =~ /, \(CV\*\)iv\d/; # t/testc.sh -q -O3 227 |
4629
|
0
|
0
|
|
|
|
0
|
if (!$new_cv_fw) { |
4630
|
0
|
|
|
|
|
0
|
$symsect->add("XPVCVIX$xpvcv_ix\t$xpvc"); |
4631
|
|
|
|
|
|
|
#$symsect->add |
4632
|
|
|
|
|
|
|
# (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}"), |
4633
|
|
|
|
|
|
|
# $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS |
4634
|
|
|
|
|
|
|
# )); |
4635
|
|
|
|
|
|
|
} else { |
4636
|
0
|
|
|
|
|
0
|
$xpvcvsect->comment('STASH mg_u cur len CV_STASH START_U ROOT_U GV file PADLIST OUTSIDE outside_seq flags depth'); |
4637
|
0
|
|
|
|
|
0
|
$xpvcvsect->add($xpvc); |
4638
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {%s}", |
4639
|
|
|
|
|
|
|
$xpvcvsect->index, $cv->REFCNT, $cv->FLAGS, |
4640
|
|
|
|
|
|
|
$CPERL52 ? $proto : "0")); |
4641
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $cv->flagspv ) if $debug{flags}; |
4642
|
|
|
|
|
|
|
} |
4643
|
|
|
|
|
|
|
} elsif ($PERL514) { |
4644
|
|
|
|
|
|
|
# cv_undef wants to free it when CvDYNFILE(cv) is true. |
4645
|
|
|
|
|
|
|
# E.g. DateTime: boot_POSIX. newXS reuses cv if autoloaded. So turn it off globally. |
4646
|
0
|
|
|
|
|
0
|
$CvFLAGS &= ~0x1000; # CVf_DYNFILE off |
4647
|
0
|
|
|
|
|
0
|
my $xpvc = sprintf |
4648
|
|
|
|
|
|
|
# stash magic cur len cvstash start root cvgv cvfile cvpadlist outside outside_seq cvflags cvdepth |
4649
|
|
|
|
|
|
|
("Nullhv, {0}, %u, %u, %s, {%s}, {s\\_%x}, %s, %s, %s, (CV*)%s, %s, 0x%x, %d", |
4650
|
|
|
|
|
|
|
$cur, $len, "Nullhv",#CvSTASH later |
4651
|
|
|
|
|
|
|
$startfield, $$root, |
4652
|
|
|
|
|
|
|
"0", #GV later |
4653
|
|
|
|
|
|
|
"NULL", #cvfile later (now a HEK) |
4654
|
|
|
|
|
|
|
$padlistsym, |
4655
|
|
|
|
|
|
|
$xcv_outside, #if main_cv set later |
4656
|
|
|
|
|
|
|
ivx($cv->OUTSIDE_SEQ), |
4657
|
|
|
|
|
|
|
$CvFLAGS, |
4658
|
|
|
|
|
|
|
$cv->DEPTH); |
4659
|
|
|
|
|
|
|
#warn "lexwarnsym in XPVCV OUTSIDE: $xpvc" if $xpvc =~ /, \(CV\*\)iv\d/; # t/testc.sh -q -O3 227 |
4660
|
0
|
0
|
|
|
|
0
|
if (!$new_cv_fw) { |
4661
|
0
|
|
|
|
|
0
|
$symsect->add("XPVCVIX$xpvcv_ix\t$xpvc"); |
4662
|
|
|
|
|
|
|
#$symsect->add |
4663
|
|
|
|
|
|
|
# (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}"), |
4664
|
|
|
|
|
|
|
# $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS |
4665
|
|
|
|
|
|
|
# )); |
4666
|
|
|
|
|
|
|
} else { |
4667
|
0
|
|
|
|
|
0
|
$xpvcvsect->comment('STASH mg_u cur len CV_STASH START_U ROOT_U GV file PADLIST OUTSIDE outside_seq flags depth'); |
4668
|
0
|
|
|
|
|
0
|
$xpvcvsect->add($xpvc); |
4669
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {0}", |
4670
|
|
|
|
|
|
|
$xpvcvsect->index, $cv->REFCNT, $cv->FLAGS)); |
4671
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $cv->flagspv ) if $debug{flags}; |
4672
|
|
|
|
|
|
|
} |
4673
|
|
|
|
|
|
|
} else { # 5.10-5.13 |
4674
|
|
|
|
|
|
|
# Note: GvFORM ends also here. #149 (B::FM), t/testc.sh -O3 -DGCF,-v 149 |
4675
|
0
|
0
|
|
|
|
0
|
my $depth = ref($cv) eq 'B::CV' ? $cv->DEPTH : 0; |
4676
|
0
|
0
|
|
|
|
0
|
my $outside_seq = ref($cv) eq 'B::CV' ? $cv->OUTSIDE_SEQ : '0'; # XXX? #238 |
4677
|
0
|
|
|
|
|
0
|
my $xpvc = sprintf |
4678
|
|
|
|
|
|
|
("{%d}, %u, %u, {%s}, {%s}, %s," |
4679
|
|
|
|
|
|
|
." %s, {%s}, {s\\_%x}, %s, %s, %s," |
4680
|
|
|
|
|
|
|
." (CV*)%s, %s, 0x%x", |
4681
|
|
|
|
|
|
|
0, # GvSTASH later. test 29 or Test::Harness |
4682
|
|
|
|
|
|
|
$cur, $len, |
4683
|
|
|
|
|
|
|
$depth, |
4684
|
|
|
|
|
|
|
"NULL", "Nullhv", #MAGIC + STASH later |
4685
|
|
|
|
|
|
|
"Nullhv",#CvSTASH later |
4686
|
|
|
|
|
|
|
$startfield, |
4687
|
|
|
|
|
|
|
$$root, |
4688
|
|
|
|
|
|
|
"0", #GV later |
4689
|
|
|
|
|
|
|
"NULL", #cv_file later (now a HEK) |
4690
|
|
|
|
|
|
|
$padlistsym, |
4691
|
|
|
|
|
|
|
$xcv_outside, #if main_cv set later |
4692
|
|
|
|
|
|
|
$outside_seq, |
4693
|
|
|
|
|
|
|
$CvFLAGS |
4694
|
|
|
|
|
|
|
); |
4695
|
0
|
0
|
|
|
|
0
|
if (!$new_cv_fw) { |
4696
|
0
|
|
|
|
|
0
|
$symsect->add("XPVCVIX$xpvcv_ix\t$xpvc"); |
4697
|
|
|
|
|
|
|
#$symsect->add |
4698
|
|
|
|
|
|
|
# (sprintf("CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x, {0}", |
4699
|
|
|
|
|
|
|
# $sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS |
4700
|
|
|
|
|
|
|
# )); |
4701
|
|
|
|
|
|
|
} else { |
4702
|
0
|
|
|
|
|
0
|
$xpvcvsect->comment('GvSTASH cur len depth mg_u MG_STASH CV_STASH START_U ROOT_U CV_GV cv_file PADLIST OUTSIDE outside_seq cv_flags'); |
4703
|
0
|
|
|
|
|
0
|
$xpvcvsect->add($xpvc); |
4704
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x, {0}", |
4705
|
|
|
|
|
|
|
$xpvcvsect->index, $cv->REFCNT, $cv->FLAGS)); |
4706
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $cv->flagspv ) if $debug{flags}; |
4707
|
|
|
|
|
|
|
} |
4708
|
|
|
|
|
|
|
} |
4709
|
0
|
0
|
|
|
|
0
|
if ($$cv) { |
4710
|
0
|
0
|
0
|
|
|
0
|
if ($PERL518 and (!$gv or ref($gv) eq 'B::SPECIAL')) { |
|
|
|
0
|
|
|
|
|
4711
|
0
|
0
|
|
|
|
0
|
my $lexsub = $cv->can('NAME_HEK') ? $cv->NAME_HEK : "_anonlex_"; |
4712
|
0
|
0
|
|
|
|
0
|
$lexsub = '' unless defined $lexsub; |
4713
|
0
|
0
|
|
|
|
0
|
warn "lexsub name $lexsub" if $debug{gv}; |
4714
|
0
|
|
|
|
|
0
|
my ($cstring, $cur, $utf8) = strlen_flags($lexsub); |
4715
|
0
|
0
|
0
|
|
|
0
|
if (!$PERL56 and $utf8) { |
4716
|
0
|
|
|
|
|
0
|
$cur = -$cur; |
4717
|
|
|
|
|
|
|
} |
4718
|
0
|
|
|
|
|
0
|
$init->add( "{ /* need a dynamic name hek */", |
4719
|
|
|
|
|
|
|
sprintf(" HEK *lexhek = share_hek(savepvn(%s, %d), %d);", |
4720
|
|
|
|
|
|
|
$cstring, abs($cur), $cur), |
4721
|
|
|
|
|
|
|
sprintf(" CvNAME_HEK_set(s\\_%x, lexhek);", $$cv), |
4722
|
|
|
|
|
|
|
"}"); |
4723
|
|
|
|
|
|
|
} else { |
4724
|
0
|
|
|
|
|
0
|
my $gvstash = $gv->STASH; |
4725
|
|
|
|
|
|
|
# defer GvSTASH because with DEBUGGING it checks for GP but |
4726
|
|
|
|
|
|
|
# there's no GP yet. |
4727
|
|
|
|
|
|
|
# But with -fstash the gvstash is set later |
4728
|
0
|
0
|
0
|
|
|
0
|
$init->add( sprintf( "GvXPVGV(s\\_%x)->xnv_u.xgv_stash = s\\_%x;", |
4729
|
|
|
|
|
|
|
$$cv, $$gvstash ) ) if $gvstash and !$B::C::stash; |
4730
|
|
|
|
|
|
|
warn sprintf( "done saving GvSTASH 0x%x for CV 0x%x\n", $$gvstash, $$cv ) |
4731
|
0
|
0
|
0
|
|
|
0
|
if $gvstash and $debug{cv} and $debug{gv}; |
|
|
|
0
|
|
|
|
|
4732
|
|
|
|
|
|
|
} |
4733
|
|
|
|
|
|
|
} |
4734
|
0
|
0
|
|
|
|
0
|
if ( $cv->OUTSIDE_SEQ ) { |
4735
|
0
|
|
|
|
|
0
|
my $cop = $symtable{ sprintf( "s\\_%x", $cv->OUTSIDE_SEQ ) }; |
4736
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "CvOUTSIDE_SEQ(%s) = %s;", $sym, $cop ) ) if $cop; |
4737
|
|
|
|
|
|
|
} |
4738
|
|
|
|
|
|
|
} |
4739
|
|
|
|
|
|
|
elsif ($PERL56) { |
4740
|
0
|
|
|
|
|
0
|
my $xpvc = sprintf("%s, %u, %u, %s, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub, " |
4741
|
|
|
|
|
|
|
."$xsubany, Nullgv, \"\", %d, s\\_%x, (CV*)%s, 0x%x", |
4742
|
|
|
|
|
|
|
$proto, $cur, $len, ivx($cv->IVX), |
4743
|
|
|
|
|
|
|
nvx($cv->NVX), $startfield, $$root, $cv->DEPTH, |
4744
|
|
|
|
|
|
|
$$padlist, $xcv_outside, $cv->CvFLAGS |
4745
|
|
|
|
|
|
|
); |
4746
|
0
|
0
|
|
|
|
0
|
if ($new_cv_fw) { |
4747
|
0
|
|
|
|
|
0
|
$xpvcvsect->comment('pv cur len off nv magic mg_stash cv_stash start root xsub ' |
4748
|
|
|
|
|
|
|
.'xsubany cv_gv cv_file cv_depth cv_padlist cv_outside cv_flags'); |
4749
|
0
|
|
|
|
|
0
|
$xpvcvsect->add($xpvc); |
4750
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x"), |
4751
|
|
|
|
|
|
|
$xpvcvsect->index, $cv->REFCNT, $cv->FLAGS); |
4752
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $cv->flagspv ) if $debug{flags}; |
4753
|
|
|
|
|
|
|
} else { |
4754
|
0
|
|
|
|
|
0
|
$symsect->add("XPVCVIX$xpvcv_ix\t$xpvc"); |
4755
|
|
|
|
|
|
|
} |
4756
|
|
|
|
|
|
|
} |
4757
|
|
|
|
|
|
|
else { #5.8 |
4758
|
0
|
|
|
|
|
0
|
my $xpvc = sprintf("%s, %u, %u, %s, %s, 0, Nullhv, Nullhv, %s, s\\_%x, $xsub," |
4759
|
|
|
|
|
|
|
." $xsubany, Nullgv, \"\", %d, s\\_%x, (CV*)s\\_%x, 0x%x, 0x%x", |
4760
|
|
|
|
|
|
|
$proto, $cur, $len, ivx($cv->IVX), |
4761
|
|
|
|
|
|
|
nvx($cv->NVX), $startfield, $$root, $cv->DEPTH, |
4762
|
|
|
|
|
|
|
$$padlist, $xcv_outside, $cv->CvFLAGS, $cv->OUTSIDE_SEQ |
4763
|
|
|
|
|
|
|
); |
4764
|
0
|
0
|
|
|
|
0
|
if ($new_cv_fw) { |
4765
|
0
|
|
|
|
|
0
|
$xpvcvsect->comment('pv cur len off nv magic mg_stash cv_stash ' |
4766
|
|
|
|
|
|
|
.'start root xsub xsubany cv_gv cv_file cv_depth cv_padlist ' |
4767
|
|
|
|
|
|
|
.'cv_outside cv_flags outside_seq'); |
4768
|
0
|
|
|
|
|
0
|
$xpvcvsect->add($xpvc); |
4769
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvcv_list[%d], $u32fmt, 0x%x"), |
4770
|
|
|
|
|
|
|
$xpvcvsect->index, $cv->REFCNT, $cv->FLAGS); |
4771
|
0
|
0
|
|
|
|
0
|
$svsect->debug( $fullname, $cv->flagspv ) if $debug{flags}; |
4772
|
|
|
|
|
|
|
} else { |
4773
|
0
|
|
|
|
|
0
|
$symsect->add("XPVCVIX$xpvcv_ix\t$xpvc"); |
4774
|
|
|
|
|
|
|
} |
4775
|
|
|
|
|
|
|
} |
4776
|
|
|
|
|
|
|
|
4777
|
0
|
0
|
0
|
|
|
0
|
if ($CPERL52 and $Config{uselongdouble}) { |
4778
|
|
|
|
|
|
|
# some very odd static struct init bug: CvOUTSIDE is pointing to CvROOT, CvROOT is corrupt. |
4779
|
|
|
|
|
|
|
# CvPADLIST also pointing somewhere else. with gcc-5 and 4.8. |
4780
|
0
|
|
|
|
|
0
|
$init->add(sprintf("xpvcv_list[$xpvcv_ix].xcv_root_u.xcv_root = s\\_%x;", $$root)); |
4781
|
0
|
|
|
|
|
0
|
$init->add("xpvcv_list[$xpvcv_ix].xcv_padlist_u.xcv_padlist = $padlistsym;"); |
4782
|
|
|
|
|
|
|
} |
4783
|
|
|
|
|
|
|
|
4784
|
0
|
|
|
|
|
0
|
$xcv_outside = ${ $cv->OUTSIDE }; |
|
0
|
|
|
|
|
0
|
|
4785
|
0
|
0
|
0
|
|
|
0
|
if ($xcv_outside == ${ main_cv() } or ref($cv->OUTSIDE) eq 'B::CV') { |
|
0
|
0
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
|
|
4786
|
|
|
|
|
|
|
# patch CvOUTSIDE at run-time |
4787
|
0
|
0
|
|
|
|
0
|
if ( $xcv_outside == ${ main_cv() } ) { |
|
0
|
|
|
|
|
0
|
|
4788
|
0
|
|
|
|
|
0
|
$init->add( "CvOUTSIDE($sym) = PL_main_cv;", |
4789
|
|
|
|
|
|
|
"SvREFCNT_inc(PL_main_cv);" ); |
4790
|
0
|
0
|
|
|
|
0
|
if ($$padlist) { |
4791
|
0
|
0
|
|
|
|
0
|
if ($PERL522) { |
|
|
0
|
|
|
|
|
|
4792
|
0
|
|
|
|
|
0
|
$init->add( "CvPADLIST($sym)->xpadl_outid = CvPADLIST(PL_main_cv)->xpadl_id;"); |
4793
|
|
|
|
|
|
|
} elsif ($] >= 5.017005) { |
4794
|
0
|
|
|
|
|
0
|
$init->add( "CvPADLIST($sym)->xpadl_outid = PadlistNAMES(CvPADLIST(PL_main_cv));"); |
4795
|
|
|
|
|
|
|
} |
4796
|
|
|
|
|
|
|
} |
4797
|
|
|
|
|
|
|
} else { |
4798
|
0
|
|
|
|
|
0
|
$init->add( sprintf("CvOUTSIDE(%s) = (CV*)s\\_%x;", $sym, $xcv_outside) ); |
4799
|
|
|
|
|
|
|
#if ($PERL522) { |
4800
|
|
|
|
|
|
|
# $init->add( sprintf("CvPADLIST(%s)->xpadl_outid = CvPADLIST(s\\_%x)->xpadl_id;", |
4801
|
|
|
|
|
|
|
# $sym, $xcv_outside)); |
4802
|
|
|
|
|
|
|
#} |
4803
|
|
|
|
|
|
|
} |
4804
|
|
|
|
|
|
|
} |
4805
|
|
|
|
|
|
|
elsif ($] >= 5.017005 and $xcv_outside and $$padlist) { |
4806
|
0
|
|
|
|
|
0
|
my $padl = $cv->OUTSIDE->PADLIST->save; |
4807
|
0
|
0
|
|
|
|
0
|
if ($PERL522) { |
4808
|
0
|
|
|
|
|
0
|
$init->add( sprintf("CvPADLIST(%s)->xpadl_outid = CvPADLIST(s\\_%x)->xpadl_id;", |
4809
|
|
|
|
|
|
|
$sym, $xcv_outside)); |
4810
|
|
|
|
|
|
|
} else { |
4811
|
|
|
|
|
|
|
# Make sure that the outer padlist is allocated before PadlistNAMES is accessed. |
4812
|
|
|
|
|
|
|
# This needs to be postponed (test 227) |
4813
|
0
|
|
|
|
|
0
|
$init1->add( sprintf( "CvPADLIST(%s)->xpadl_outid = PadlistNAMES(%s);", $sym, $padl) ); |
4814
|
|
|
|
|
|
|
} |
4815
|
|
|
|
|
|
|
} |
4816
|
0
|
0
|
0
|
|
|
0
|
if ($gv and $$gv) { |
4817
|
|
|
|
|
|
|
#test 16: Can't call method "FETCH" on unblessed reference. gdb > b S_method_common |
4818
|
0
|
0
|
0
|
|
|
0
|
warn sprintf( "Saving GV 0x%x for CV 0x%x\n", $$gv, $$cv ) if $debug{cv} and $debug{gv}; |
4819
|
0
|
|
|
|
|
0
|
$gv->save; |
4820
|
0
|
0
|
|
|
|
0
|
if ($PERL514) { # FIXME 5.18.0 with lexsubs |
4821
|
|
|
|
|
|
|
# XXX gvcv might be PVMG |
4822
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "CvGV_set((CV*)%s, (GV*)%s);", $sym, objsym($gv)) ); |
4823
|
|
|
|
|
|
|
# Since 5.13.3 and CvGV_set there are checks that the CV is not RC (refcounted). |
4824
|
|
|
|
|
|
|
# Assertion "!CvCVGV_RC(cv)" failed: file "gv.c", line 219, function: Perl_cvgv_set |
4825
|
|
|
|
|
|
|
# We init with CvFLAGS = 0 and set it later, as successfully done in the Bytecode compiler |
4826
|
0
|
0
|
|
|
|
0
|
if ($CvFLAGS & 0x0400) { # CVf_CVGV_RC |
4827
|
|
|
|
|
|
|
warn sprintf( "CvCVGV_RC turned off. CV flags=0x%x %s CvFLAGS=0x%x \n", |
4828
|
|
|
|
|
|
|
$cv->FLAGS, $debug{flags}?$cv->flagspv:"", $CvFLAGS & ~0x400) |
4829
|
0
|
0
|
|
|
|
0
|
if $debug{cv}; |
|
|
0
|
|
|
|
|
|
4830
|
|
|
|
|
|
|
$init->add( sprintf( "CvFLAGS((CV*)%s) = 0x%x; %s", $sym, $CvFLAGS, |
4831
|
0
|
0
|
|
|
|
0
|
$debug{flags}?"/* ".$cv->flagspv." */":"" ) ); |
4832
|
|
|
|
|
|
|
} |
4833
|
0
|
|
|
|
|
0
|
$init->add("CvSTART($sym) = $startfield;"); # XXX TODO someone is overwriting CvSTART also |
4834
|
|
|
|
|
|
|
} else { |
4835
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "CvGV(%s) = %s;", $sym, objsym($gv) ) ); |
4836
|
|
|
|
|
|
|
} |
4837
|
|
|
|
|
|
|
warn sprintf("done saving GV 0x%x for CV 0x%x\n", |
4838
|
0
|
0
|
0
|
|
|
0
|
$$gv, $$cv) if $debug{cv} and $debug{gv}; |
4839
|
|
|
|
|
|
|
} |
4840
|
0
|
0
|
|
|
|
0
|
unless ($optimize_cop) { |
4841
|
0
|
|
|
|
|
0
|
my $file = $cv->FILE(); |
4842
|
0
|
0
|
0
|
|
|
0
|
if ($MULTI) { |
|
|
0
|
|
|
|
|
|
4843
|
0
|
|
|
|
|
0
|
$init->add( savepvn( "CvFILE($sym)", $file ) ); |
4844
|
|
|
|
|
|
|
} elsif ($B::C::const_strings && length $file) { |
4845
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "CvFILE(%s) = (char *) %s;", $sym, constpv( $file ) ) ); |
4846
|
|
|
|
|
|
|
} else { |
4847
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "CvFILE(%s) = %s;", $sym, cstring( $file ) ) ); |
4848
|
|
|
|
|
|
|
} |
4849
|
|
|
|
|
|
|
} |
4850
|
0
|
|
|
|
|
0
|
my $stash = $cv->STASH; |
4851
|
0
|
0
|
0
|
|
|
0
|
if ($$stash and ref($stash)) { |
4852
|
|
|
|
|
|
|
# $init->add("/* saving STASH $fullname */\n" if $debug{cv}; |
4853
|
0
|
|
|
|
|
0
|
$stash->save($fullname); |
4854
|
|
|
|
|
|
|
# $sym fixed test 27 |
4855
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "CvSTASH_set((CV*)%s, s\\_%x);", $sym, $$stash ) ); |
4856
|
|
|
|
|
|
|
# 5.18 bless does not inc sv_objcount anymore. broken by ddf23d4a1ae (#208) |
4857
|
|
|
|
|
|
|
# We workaround this 5.18 de-optimization by adding it if at least a DESTROY |
4858
|
|
|
|
|
|
|
# method exists. |
4859
|
0
|
0
|
0
|
|
|
0
|
$init->add("++PL_sv_objcount;") if $cvname eq 'DESTROY' and $] >= 5.017011; |
4860
|
|
|
|
|
|
|
warn sprintf( "done saving STASH 0x%x for CV 0x%x\n", $$stash, $$cv ) |
4861
|
0
|
0
|
0
|
|
|
0
|
if $debug{cv} and $debug{gv}; |
4862
|
|
|
|
|
|
|
} |
4863
|
0
|
|
|
|
|
0
|
my $magic = $cv->MAGIC; |
4864
|
0
|
0
|
0
|
|
|
0
|
if ($magic and $$magic) { |
4865
|
0
|
|
|
|
|
0
|
$cv->save_magic($fullname); # XXX will this work? |
4866
|
|
|
|
|
|
|
} |
4867
|
0
|
0
|
|
|
|
0
|
if (!$new_cv_fw) { |
4868
|
0
|
0
|
|
|
|
0
|
$symsect->add(sprintf( |
4869
|
|
|
|
|
|
|
"CVIX%d\t(XPVCV*)&xpvcv_list[%u], $u32fmt, 0x%x".($PERL510?", {0}":''), |
4870
|
|
|
|
|
|
|
$sv_ix, $xpvcv_ix, $cv->REFCNT, $cv->FLAGS |
4871
|
|
|
|
|
|
|
) |
4872
|
|
|
|
|
|
|
); |
4873
|
|
|
|
|
|
|
} |
4874
|
0
|
0
|
|
|
|
0
|
if ($cur) { |
4875
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Saving CV proto %s for CV $sym 0x%x\n", cstring($pv), $$cv ) if $debug{cv}; |
4876
|
|
|
|
|
|
|
} |
4877
|
|
|
|
|
|
|
# issue 84: empty prototypes sub xx(){} vs sub xx{} |
4878
|
0
|
0
|
|
|
|
0
|
if (defined $pv) { |
4879
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and $cur) { |
|
|
0
|
|
|
|
|
|
4880
|
0
|
|
|
|
|
0
|
$init->add( sprintf("SvPVX(&sv_list[%d]) = HEK_KEY(%s);", $sv_ix, $pvsym)); |
4881
|
|
|
|
|
|
|
} elsif (!$B::C::const_strings) { # not static, they are freed when redefined |
4882
|
0
|
|
|
|
|
0
|
$init->add( sprintf("SvPVX(&sv_list[%d]) = savepvn(%s, %u);", |
4883
|
|
|
|
|
|
|
$sv_ix, $proto, $cur)); |
4884
|
|
|
|
|
|
|
} else { |
4885
|
0
|
|
|
|
|
0
|
$init->add( sprintf("SvPVX(&sv_list[%d]) = %s;", |
4886
|
|
|
|
|
|
|
$sv_ix, $proto)); |
4887
|
|
|
|
|
|
|
} |
4888
|
|
|
|
|
|
|
} |
4889
|
0
|
0
|
|
|
|
0
|
$cv->OUTSIDE->save if $xcv_outside; |
4890
|
0
|
|
|
|
|
0
|
return $sym; |
4891
|
|
|
|
|
|
|
} |
4892
|
|
|
|
|
|
|
|
4893
|
|
|
|
|
|
|
package B::C; |
4894
|
|
|
|
|
|
|
my @_v = Internals::V() if $] >= 5.011; |
4895
|
0
|
|
|
0
|
|
0
|
sub __ANON__::_V { @_v }; |
4896
|
|
|
|
|
|
|
|
4897
|
|
|
|
|
|
|
sub B::GV::save { |
4898
|
0
|
|
|
0
|
|
0
|
my ($gv, $filter) = @_; |
4899
|
0
|
|
|
|
|
0
|
my $sym = objsym($gv); |
4900
|
0
|
0
|
|
|
|
0
|
if ( defined($sym) ) { |
4901
|
0
|
0
|
|
|
|
0
|
warn sprintf( "GV 0x%x already saved as $sym\n", $$gv ) if $debug{gv}; |
4902
|
0
|
|
|
|
|
0
|
return $sym; |
4903
|
|
|
|
|
|
|
} |
4904
|
|
|
|
|
|
|
else { |
4905
|
0
|
|
|
|
|
0
|
my $ix = $gv_index++; |
4906
|
0
|
|
|
|
|
0
|
$sym = savesym( $gv, "gv_list[$ix]" ); |
4907
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Saving GV 0x%x as $sym\n", $$gv ) if $debug{gv}; |
4908
|
|
|
|
|
|
|
} |
4909
|
|
|
|
|
|
|
warn sprintf( " GV %s $sym type=%d, flags=0x%x %s\n", $gv->NAME, |
4910
|
|
|
|
|
|
|
# B::SV::SvTYPE not with 5.6 |
4911
|
0
|
0
|
0
|
|
|
0
|
B::SV::SvTYPE($gv), $gv->FLAGS) if $debug{gv} and !$PERL56; |
4912
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and $gv->FLAGS & 0x40000000) { # SVpbm_VALID |
4913
|
0
|
0
|
|
|
|
0
|
warn sprintf( " GV $sym isa FBM\n") if $debug{gv}; |
4914
|
0
|
|
|
|
|
0
|
return B::BM::save($gv); |
4915
|
|
|
|
|
|
|
} |
4916
|
|
|
|
|
|
|
|
4917
|
0
|
|
|
|
|
0
|
my $gvname = $gv->NAME; |
4918
|
0
|
|
|
|
|
0
|
my $package; |
4919
|
0
|
0
|
|
|
|
0
|
if (ref($gv->STASH) eq 'B::SPECIAL') { |
4920
|
0
|
|
|
|
|
0
|
$package = '__ANON__'; |
4921
|
0
|
0
|
|
|
|
0
|
warn sprintf( "GV STASH = SPECIAL $gvname\n") if $debug{gv}; |
4922
|
|
|
|
|
|
|
} else { |
4923
|
0
|
|
|
|
|
0
|
$package = $gv->STASH->NAME; |
4924
|
|
|
|
|
|
|
} |
4925
|
0
|
0
|
|
|
|
0
|
return q/(SV*)&PL_sv_undef/ if skip_pkg($package); |
4926
|
|
|
|
|
|
|
|
4927
|
0
|
|
|
|
|
0
|
my $fullname = $package . "::" . $gvname; |
4928
|
0
|
|
|
|
|
0
|
my $fancyname; |
4929
|
|
|
|
|
|
|
sub Save_HV() { 1 } |
4930
|
|
|
|
|
|
|
sub Save_AV() { 2 } |
4931
|
|
|
|
|
|
|
sub Save_SV() { 4 } |
4932
|
|
|
|
|
|
|
sub Save_CV() { 8 } |
4933
|
|
|
|
|
|
|
sub Save_FORM() { 16 } |
4934
|
|
|
|
|
|
|
sub Save_IO() { 32 } |
4935
|
0
|
0
|
0
|
|
|
0
|
if ( $filter and $filter =~ m/ :pad/ ) { |
4936
|
0
|
|
|
|
|
0
|
$fancyname = cstring($filter); |
4937
|
0
|
|
|
|
|
0
|
$filter = 0; |
4938
|
|
|
|
|
|
|
} else { |
4939
|
0
|
|
|
|
|
0
|
$fancyname = cstring($fullname); |
4940
|
|
|
|
|
|
|
} |
4941
|
|
|
|
|
|
|
# checked for defined'ness in Carp. So the GV must exist, the CV not |
4942
|
0
|
0
|
0
|
|
|
0
|
if ($fullname =~ /^threads::(tid|AUTOLOAD)$/ and !$ITHREADS) { |
4943
|
0
|
|
|
|
|
0
|
$filter = Save_CV; |
4944
|
|
|
|
|
|
|
} |
4945
|
|
|
|
|
|
|
# no need to assign any SV/AV/HV to them (172) |
4946
|
0
|
0
|
0
|
|
|
0
|
if ($PERL518 and $fullname =~ /^DynaLoader::dl_( |
4947
|
|
|
|
|
|
|
require_symbols| |
4948
|
|
|
|
|
|
|
modules| |
4949
|
|
|
|
|
|
|
shared_objects| |
4950
|
|
|
|
|
|
|
resolve_using| |
4951
|
|
|
|
|
|
|
librefs)/x) |
4952
|
|
|
|
|
|
|
{ |
4953
|
0
|
|
|
|
|
0
|
$filter = Save_SV + Save_AV + Save_HV; |
4954
|
|
|
|
|
|
|
} |
4955
|
|
|
|
|
|
|
# skip static %Encode::Encoding since 5.20. GH #200. |
4956
|
|
|
|
|
|
|
# Let it be initialized by boot_Encode/Encode_XSEncoding |
4957
|
|
|
|
|
|
|
#if ($] >= 5.020 and $fullname eq 'Encode::Encoding') { |
4958
|
|
|
|
|
|
|
# warn "skip %Encode::Encoding - XS initialized\n" if $debug{gv}; |
4959
|
|
|
|
|
|
|
# $filter = Save_HV; |
4960
|
|
|
|
|
|
|
#} |
4961
|
|
|
|
|
|
|
|
4962
|
0
|
|
|
|
|
0
|
my $is_empty = $gv->is_empty; |
4963
|
0
|
0
|
0
|
|
|
0
|
if (!defined $gvname and $is_empty) { # 5.8 curpad name |
4964
|
0
|
|
|
|
|
0
|
return q/(SV*)&PL_sv_undef/; |
4965
|
|
|
|
|
|
|
} |
4966
|
0
|
0
|
|
|
|
0
|
my $name = $package eq 'main' ? $gvname : $fullname; |
4967
|
0
|
|
|
|
|
0
|
my $cname = cstring($name); |
4968
|
0
|
0
|
0
|
|
|
0
|
my $notqual = ($] >= 5.008009 and $package eq 'main') ? 'GV_NOTQUAL' : '0'; |
4969
|
0
|
0
|
|
|
|
0
|
warn " GV name is $fancyname\n" if $debug{gv}; |
4970
|
0
|
|
|
|
|
0
|
my $egvsym; |
4971
|
0
|
|
|
|
|
0
|
my $is_special = ref($gv) eq 'B::SPECIAL'; |
4972
|
|
|
|
|
|
|
|
4973
|
|
|
|
|
|
|
# If we come across a stash, we therefore have code using this symbol. |
4974
|
|
|
|
|
|
|
# But this does not mean that we need to save the package then. |
4975
|
|
|
|
|
|
|
# if (defined %Exporter::) should not import Exporter, it should return undef. |
4976
|
|
|
|
|
|
|
#if ( $gvname =~ m/::$/ ) { |
4977
|
|
|
|
|
|
|
# my $package = $gvname; |
4978
|
|
|
|
|
|
|
# $package =~ s/::$//; |
4979
|
|
|
|
|
|
|
# mark_package($package); #wrong |
4980
|
|
|
|
|
|
|
#} |
4981
|
0
|
0
|
|
|
|
0
|
if ($fullname =~ /^(bytes|utf8)::AUTOLOAD$/) { |
4982
|
0
|
|
|
|
|
0
|
$gv = force_heavy($package); # defer to run-time autoload, or compile it in? |
4983
|
0
|
|
|
|
|
0
|
$sym = savesym( $gv, $sym ); # override new gv ptr to sym |
4984
|
|
|
|
|
|
|
} |
4985
|
0
|
0
|
|
|
|
0
|
if ( !$is_empty ) { |
4986
|
0
|
|
|
|
|
0
|
my $egv = $gv->EGV; |
4987
|
0
|
0
|
0
|
|
|
0
|
unless (ref($egv) eq 'B::SPECIAL' or ref($egv->STASH) eq 'B::SPECIAL') { |
4988
|
0
|
|
|
|
|
0
|
my $estash = $egv->STASH->NAME; |
4989
|
0
|
0
|
|
|
|
0
|
if ( $$gv != $$egv ) { |
4990
|
|
|
|
|
|
|
warn(sprintf( "EGV name is %s, saving it now\n", |
4991
|
|
|
|
|
|
|
$estash . "::" . $egv->NAME ) |
4992
|
0
|
0
|
|
|
|
0
|
) if $debug{gv}; |
4993
|
0
|
|
|
|
|
0
|
$egvsym = $egv->save; |
4994
|
|
|
|
|
|
|
} |
4995
|
|
|
|
|
|
|
} |
4996
|
|
|
|
|
|
|
} |
4997
|
|
|
|
|
|
|
#if ($fullname eq 'threads::tid' and !$ITHREADS) { # checked for defined'ness in Carp |
4998
|
|
|
|
|
|
|
# $init->add(qq[$sym = (GV*)&PL_sv_undef;]); |
4999
|
|
|
|
|
|
|
# return $sym; |
5000
|
|
|
|
|
|
|
#} |
5001
|
0
|
0
|
0
|
|
|
0
|
if ($fullname =~ /^main::STDOUT$/i and $PERL56) { |
5002
|
0
|
|
|
|
|
0
|
return 'Nullgv'; # perl.c: setdefout(Nullgv) |
5003
|
|
|
|
|
|
|
} |
5004
|
0
|
|
|
|
|
0
|
my $core_syms = {ENV => 'PL_envgv', |
5005
|
|
|
|
|
|
|
ARGV => 'PL_argvgv', |
5006
|
|
|
|
|
|
|
INC => 'PL_incgv', |
5007
|
|
|
|
|
|
|
STDIN => 'PL_stdingv', |
5008
|
|
|
|
|
|
|
STDERR => 'PL_stderrgv', |
5009
|
|
|
|
|
|
|
"\010" => 'PL_hintgv', # ^H |
5010
|
|
|
|
|
|
|
"_" => 'PL_defgv', |
5011
|
|
|
|
|
|
|
"@" => 'PL_errgv', |
5012
|
|
|
|
|
|
|
"\022" => 'PL_replgv', # ^R |
5013
|
|
|
|
|
|
|
}; |
5014
|
0
|
|
|
|
|
0
|
my $is_coresym; |
5015
|
|
|
|
|
|
|
# those are already initialized in init_predump_symbols() |
5016
|
|
|
|
|
|
|
# and init_main_stash() |
5017
|
0
|
|
|
|
|
0
|
for my $s (sort keys %$core_syms) { |
5018
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'main::'.$s) { |
5019
|
0
|
|
|
|
|
0
|
$sym = savesym( $gv, $core_syms->{$s} ); |
5020
|
|
|
|
|
|
|
# $init->add( sprintf( "SvREFCNT($sym) = $u32fmt;", $gv->REFCNT ) ); |
5021
|
|
|
|
|
|
|
# return $sym; |
5022
|
0
|
|
|
|
|
0
|
$is_coresym++; |
5023
|
|
|
|
|
|
|
} |
5024
|
|
|
|
|
|
|
} |
5025
|
0
|
0
|
0
|
|
|
0
|
if ($fullname =~ /^main::std(in|out|err)$/) { # same as uppercase above |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
5026
|
0
|
|
|
|
|
0
|
$init->add(qq[$sym = gv_fetchpv($cname, $notqual, SVt_PVGV);]); |
5027
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) ); |
5028
|
0
|
|
|
|
|
0
|
return $sym; |
5029
|
|
|
|
|
|
|
} |
5030
|
|
|
|
|
|
|
elsif ($fullname eq 'main::0') { # dollar_0 already handled before, so don't overwrite it |
5031
|
0
|
|
|
|
|
0
|
$init->add(qq[$sym = gv_fetchpv($cname, $notqual, SVt_PV);]); |
5032
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) ); |
5033
|
0
|
|
|
|
|
0
|
return $sym; |
5034
|
|
|
|
|
|
|
} |
5035
|
|
|
|
|
|
|
elsif ($B::C::ro_inc and $fullname =~ /^main::([0-9])$/) { # ignore PV regexp captures with -O2 |
5036
|
0
|
|
|
|
|
0
|
$filter = Save_SV; |
5037
|
|
|
|
|
|
|
} |
5038
|
|
|
|
|
|
|
# gv_fetchpv loads Errno resp. Tie::Hash::NamedCapture, but needs *INC #90 |
5039
|
|
|
|
|
|
|
#elsif ( $fullname eq 'main::!' or $fullname eq 'main::+' or $fullname eq 'main::-') { |
5040
|
|
|
|
|
|
|
# $init1->add(qq[$sym = gv_fetchpv($name, TRUE, SVt_PVGV);]); # defer until INC is setup |
5041
|
|
|
|
|
|
|
# $init1->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT ) ); |
5042
|
|
|
|
|
|
|
# return $sym; |
5043
|
|
|
|
|
|
|
#} |
5044
|
0
|
|
|
|
|
0
|
my $svflags = $gv->FLAGS; |
5045
|
0
|
|
|
|
|
0
|
my $savefields = 0; |
5046
|
|
|
|
|
|
|
|
5047
|
0
|
|
|
|
|
0
|
my $gp; |
5048
|
0
|
0
|
|
|
|
0
|
my $gvadd = $notqual ? "$notqual|GV_ADD" : "GV_ADD"; |
5049
|
0
|
0
|
0
|
|
|
0
|
if ( $PERL510 and $gv->isGV_with_GP and !$is_coresym) { |
|
|
0
|
0
|
|
|
|
|
5050
|
0
|
|
|
|
|
0
|
$gp = $gv->GP; # B limitation |
5051
|
|
|
|
|
|
|
# warn "XXX EGV='$egvsym' for IMPORTED_HV" if $gv->GvFLAGS & 0x40; |
5052
|
0
|
0
|
0
|
|
|
0
|
if ( defined($egvsym) && $egvsym !~ m/Null/ ) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5053
|
|
|
|
|
|
|
warn(sprintf("Shared GV alias for *$fullname 0x%x%s %s to $egvsym\n", |
5054
|
|
|
|
|
|
|
$svflags, $debug{flags} ? "(".$gv->flagspv.")" : "", |
5055
|
0
|
0
|
|
|
|
0
|
)) if $debug{gv}; |
|
|
0
|
|
|
|
|
|
5056
|
|
|
|
|
|
|
# Shared glob *foo = *bar |
5057
|
0
|
0
|
|
|
|
0
|
$init->add("$sym = ".gv_fetchpvn($package eq 'main' ? $gvname : $fullname, |
5058
|
|
|
|
|
|
|
"$gvadd|GV_ADDMULTI", "SVt_PVGV").";"); |
5059
|
0
|
|
|
|
|
0
|
$init->add( "GvGP_set($sym, GvGP($egvsym));" ); |
5060
|
0
|
|
|
|
|
0
|
$is_empty = 1; |
5061
|
|
|
|
|
|
|
} |
5062
|
|
|
|
|
|
|
elsif ( $gp and exists $gptable{0+$gp} ) { |
5063
|
|
|
|
|
|
|
warn(sprintf("Shared GvGP for *$fullname 0x%x%s %s GP:0x%x\n", |
5064
|
|
|
|
|
|
|
$svflags, $debug{flags} ? "(".$gv->flagspv.")" : "", |
5065
|
|
|
|
|
|
|
$gv->FILE, $gp |
5066
|
0
|
0
|
|
|
|
0
|
)) if $debug{gv}; |
|
|
0
|
|
|
|
|
|
5067
|
0
|
|
|
|
|
0
|
$init->add("$sym = ".gv_fetchpvn($name, $notqual, "SVt_PVGV").";"); |
5068
|
0
|
|
|
|
|
0
|
$init->add( sprintf("GvGP_set(%s, %s);", $sym, $gptable{0+$gp}) ); |
5069
|
0
|
|
|
|
|
0
|
$is_empty = 1; |
5070
|
|
|
|
|
|
|
} |
5071
|
|
|
|
|
|
|
elsif ( $gp and !$is_empty and $gvname =~ /::$/) { |
5072
|
|
|
|
|
|
|
warn(sprintf("Shared GvGP for stash %$fullname 0x%x%s %s GP:0x%x\n", |
5073
|
|
|
|
|
|
|
$svflags, $debug{flags} ? "(".$gv->flagspv.")" : "", |
5074
|
|
|
|
|
|
|
$gv->FILE, $gp |
5075
|
0
|
0
|
|
|
|
0
|
)) if $debug{gv}; |
|
|
0
|
|
|
|
|
|
5076
|
0
|
|
|
|
|
0
|
$init->add("$sym = ".gv_fetchpvn($name, "GV_ADD", "SVt_PVHV").";"); |
5077
|
0
|
0
|
|
|
|
0
|
$gptable{0+$gp} = "GvGP($sym)" if 0+$gp; |
5078
|
|
|
|
|
|
|
} |
5079
|
|
|
|
|
|
|
elsif ( $gp and !$is_empty ) { |
5080
|
|
|
|
|
|
|
warn(sprintf("New GV for *$fullname 0x%x%s %s GP:0x%x\n", |
5081
|
|
|
|
|
|
|
$svflags, $debug{flags} ? "(".$gv->flagspv.")" : "", |
5082
|
|
|
|
|
|
|
$gv->FILE, $gp |
5083
|
0
|
0
|
|
|
|
0
|
)) if $debug{gv}; |
|
|
0
|
|
|
|
|
|
5084
|
|
|
|
|
|
|
# XXX !PERL510 and OPf_COP_TEMP we need to fake PL_curcop for gp_file hackery |
5085
|
0
|
|
|
|
|
0
|
$init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PV").";"); |
5086
|
|
|
|
|
|
|
#$init->add(qq[$sym = gv_fetchpv($name, $gvadd, SVt_PV);]); |
5087
|
0
|
|
|
|
|
0
|
$savefields = Save_HV | Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO; |
5088
|
0
|
|
|
|
|
0
|
$gptable{0+$gp} = "GvGP($sym)"; |
5089
|
|
|
|
|
|
|
} |
5090
|
|
|
|
|
|
|
else { |
5091
|
0
|
|
|
|
|
0
|
$init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PVGV").";"); |
5092
|
|
|
|
|
|
|
# $init->add(qq[$sym = gv_fetchpv($name, $gvadd, SVt_PVGV);]); |
5093
|
|
|
|
|
|
|
} |
5094
|
|
|
|
|
|
|
} elsif (!$is_coresym) { |
5095
|
0
|
|
|
|
|
0
|
$init->add("$sym = ".gv_fetchpvn($name, $gvadd, "SVt_PV").";"); |
5096
|
|
|
|
|
|
|
# $init->add(qq[$sym = gv_fetchpv($name, $gvadd, SVt_PV);]); |
5097
|
|
|
|
|
|
|
} |
5098
|
0
|
|
|
|
|
0
|
my $gvflags = $gv->GvFLAGS; |
5099
|
0
|
0
|
0
|
|
|
0
|
if ($gvflags > 256 and !$PERL510) { # $gv->GvFLAGS as U8 single byte only |
5100
|
0
|
|
|
|
|
0
|
$gvflags = $gvflags & 255; |
5101
|
|
|
|
|
|
|
} |
5102
|
|
|
|
|
|
|
$init->add( sprintf( "SvFLAGS(%s) = 0x%x;%s", $sym, $svflags, |
5103
|
|
|
|
|
|
|
$debug{flags}?" /* ".$gv->flagspv." */":"" ), |
5104
|
|
|
|
|
|
|
sprintf( "GvFLAGS(%s) = 0x%x; %s", $sym, $gvflags, |
5105
|
0
|
0
|
|
|
|
0
|
$debug{flags}?"/* ".$gv->flagspv(SVt_PVGV)." */":"" )); |
|
|
0
|
|
|
|
|
|
5106
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "GvLINE(%s) = %d;", $sym, |
|
|
0
|
|
|
|
|
|
5107
|
|
|
|
|
|
|
($gv->LINE > 2147483647 # S32 INT_MAX |
5108
|
|
|
|
|
|
|
? 4294967294 - $gv->LINE |
5109
|
|
|
|
|
|
|
: $gv->LINE ))) |
5110
|
|
|
|
|
|
|
unless $is_empty; |
5111
|
|
|
|
|
|
|
|
5112
|
|
|
|
|
|
|
# XXX hack for when Perl accesses PVX of GVs, only if SvPOK |
5113
|
|
|
|
|
|
|
#if (!($svflags && 0x400)) { # defer to run-time (0x400 -> SvPOK) for convenience |
5114
|
|
|
|
|
|
|
# XXX also empty "main::" destruction accesses a PVX, so do not check if_empty |
5115
|
0
|
0
|
|
|
|
0
|
if ( !$PERL510 ) { |
5116
|
0
|
|
|
|
|
0
|
$init->add("if (SvPOK($sym) && !SvPVX($sym)) SvPVX($sym) = (char*)emptystring;"); |
5117
|
|
|
|
|
|
|
} |
5118
|
|
|
|
|
|
|
|
5119
|
|
|
|
|
|
|
# walksymtable creates an extra reference to the GV (#197) |
5120
|
0
|
0
|
|
|
|
0
|
if ( $gv->REFCNT > 1 ) { |
5121
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "SvREFCNT(%s) = $u32fmt;", $sym, $gv->REFCNT) ); |
5122
|
|
|
|
|
|
|
} |
5123
|
0
|
0
|
|
|
|
0
|
return $sym if $is_empty; |
5124
|
|
|
|
|
|
|
|
5125
|
0
|
|
|
|
|
0
|
my $gvrefcnt = $gv->GvREFCNT; |
5126
|
0
|
0
|
|
|
|
0
|
if ( $gvrefcnt > 1 ) { |
5127
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvREFCNT(%s) += $u32fmt;", $sym, $gvrefcnt - 1) ); |
5128
|
|
|
|
|
|
|
} |
5129
|
|
|
|
|
|
|
|
5130
|
0
|
0
|
|
|
|
0
|
warn "check which savefields for \"$gvname\"\n" if $debug{gv}; |
5131
|
|
|
|
|
|
|
# some non-alphabetic globs require some parts to be saved |
5132
|
|
|
|
|
|
|
# ( ex. %!, but not $! ) |
5133
|
0
|
0
|
0
|
|
|
0
|
if ( $gvname !~ /^([^A-Za-z]|STDIN|STDOUT|STDERR|ARGV|SIG|ENV)$/ ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
5134
|
0
|
|
|
|
|
0
|
$savefields = Save_HV | Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO; |
5135
|
|
|
|
|
|
|
} |
5136
|
|
|
|
|
|
|
elsif ( $fullname eq 'main::!' ) { #Errno |
5137
|
0
|
|
|
|
|
0
|
$savefields = Save_HV | Save_SV | Save_CV; |
5138
|
|
|
|
|
|
|
} |
5139
|
|
|
|
|
|
|
elsif ( $fullname eq 'main::ENV' or $fullname eq 'main::SIG' ) { |
5140
|
0
|
|
|
|
|
0
|
$savefields = Save_AV | Save_SV | Save_CV | Save_FORM | Save_IO; |
5141
|
|
|
|
|
|
|
} |
5142
|
|
|
|
|
|
|
elsif ( $fullname eq 'main::ARGV' ) { |
5143
|
0
|
|
|
|
|
0
|
$savefields = Save_HV | Save_SV | Save_CV | Save_FORM | Save_IO; |
5144
|
|
|
|
|
|
|
} |
5145
|
|
|
|
|
|
|
elsif ( $fullname =~ /^main::STD(IN|OUT|ERR)$/ ) { |
5146
|
0
|
|
|
|
|
0
|
$savefields = Save_FORM | Save_IO; |
5147
|
|
|
|
|
|
|
} |
5148
|
0
|
0
|
0
|
|
|
0
|
$savefields &= ~$filter if ($filter and $filter !~ m/ :pad/ |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5149
|
|
|
|
|
|
|
and $filter =~ m/^\d+$/ and $filter > 0 and $filter < 64); |
5150
|
|
|
|
|
|
|
# issue 79: Only save stashes for stashes. |
5151
|
|
|
|
|
|
|
# But not other values to avoid recursion into unneeded territory. |
5152
|
|
|
|
|
|
|
# We walk via savecv, not via stashes. |
5153
|
0
|
0
|
0
|
|
|
0
|
if (ref($gv) eq 'B::STASHGV' and $gvname !~ /::$/) { |
5154
|
0
|
|
|
|
|
0
|
return $sym; |
5155
|
|
|
|
|
|
|
} |
5156
|
|
|
|
|
|
|
|
5157
|
|
|
|
|
|
|
# attributes::bootstrap is created in perl_parse. |
5158
|
|
|
|
|
|
|
# Saving it would overwrite it, because perl_init() is |
5159
|
|
|
|
|
|
|
# called after perl_parse(). But we need to xsload it. |
5160
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'attributes::bootstrap') { |
5161
|
0
|
0
|
|
|
|
0
|
unless ( defined( &{ $package . '::bootstrap' } ) ) { |
|
0
|
|
|
|
|
0
|
|
5162
|
0
|
0
|
|
|
|
0
|
warn "Forcing bootstrap of $package\n" if $verbose; |
5163
|
0
|
|
|
|
|
0
|
eval { $package->bootstrap }; |
|
0
|
|
|
|
|
0
|
|
5164
|
|
|
|
|
|
|
} |
5165
|
0
|
|
|
|
|
0
|
mark_package('attributes', 1); |
5166
|
0
|
0
|
|
|
|
0
|
if ($] >= 5.011) { |
5167
|
0
|
|
|
|
|
0
|
$savefields &= ~Save_CV; |
5168
|
0
|
|
|
|
|
0
|
$xsub{attributes} = 'Dynamic-'. $INC{'attributes.pm'}; # XSLoader |
5169
|
0
|
|
|
|
|
0
|
$use_xsloader = 1; |
5170
|
|
|
|
|
|
|
} else { |
5171
|
0
|
|
|
|
|
0
|
$xsub{attributes} = 'Static'; |
5172
|
|
|
|
|
|
|
} |
5173
|
|
|
|
|
|
|
} |
5174
|
|
|
|
|
|
|
|
5175
|
|
|
|
|
|
|
# avoid overly dynamic POSIX redefinition warnings: GH #335, #345 |
5176
|
0
|
0
|
0
|
|
|
0
|
if ($PERL522 and $fullname =~ /^POSIX::M/) { |
5177
|
0
|
|
|
|
|
0
|
$savefields &= ~Save_CV; |
5178
|
|
|
|
|
|
|
} |
5179
|
0
|
|
|
|
|
0
|
my $gvsv; |
5180
|
0
|
0
|
|
|
|
0
|
if ($savefields) { |
5181
|
|
|
|
|
|
|
# Don't save subfields of special GVs (*_, *1, *# and so on) |
5182
|
0
|
0
|
|
|
|
0
|
warn "GV::save saving subfields $savefields\n" if $debug{gv}; |
5183
|
0
|
|
|
|
|
0
|
$gvsv = $gv->SV; |
5184
|
0
|
0
|
0
|
|
|
0
|
if ( $$gvsv && $savefields & Save_SV ) { |
5185
|
0
|
0
|
|
|
|
0
|
warn "GV::save \$".$sym." $gvsv\n" if $debug{gv}; |
5186
|
0
|
|
|
|
|
0
|
my $core_svs = { # special SV syms to assign to the right GvSV |
5187
|
|
|
|
|
|
|
"\\" => 'PL_ors_sv', |
5188
|
|
|
|
|
|
|
"/" => 'PL_rs', |
5189
|
|
|
|
|
|
|
"@" => 'PL_errors', |
5190
|
|
|
|
|
|
|
}; |
5191
|
0
|
|
|
|
|
0
|
for my $s (sort keys %$core_svs) { |
5192
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'main::'.$s) { |
5193
|
0
|
|
|
|
|
0
|
savesym( $gvsv, $core_svs->{$s} ); # TODO: This could bypass BEGIN settings (->save is ignored) |
5194
|
|
|
|
|
|
|
} |
5195
|
|
|
|
|
|
|
} |
5196
|
0
|
0
|
0
|
|
|
0
|
if ($gvname eq 'VERSION' and $xsub{$package} and $gvsv->FLAGS & SVf_ROK and !$PERL56) { |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5197
|
0
|
0
|
|
|
|
0
|
warn "Strip overload from $package\::VERSION, fails to xs boot (issue 91)\n" if $debug{gv}; |
5198
|
0
|
|
|
|
|
0
|
my $rv = $gvsv->object_2svref(); |
5199
|
0
|
|
|
|
|
0
|
my $origsv = $$rv; |
5200
|
55
|
|
|
55
|
|
353
|
no strict 'refs'; |
|
55
|
|
|
|
|
90
|
|
|
55
|
|
|
|
|
28120
|
|
5201
|
0
|
|
|
|
|
0
|
${$fullname} = "$origsv"; |
|
0
|
|
|
|
|
0
|
|
5202
|
0
|
|
|
|
|
0
|
svref_2object(\${$fullname})->save($fullname); |
|
0
|
|
|
|
|
0
|
|
5203
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvSVn(%s) = (SV*)s\\_%x;", $sym, $$gvsv ) ); |
5204
|
|
|
|
|
|
|
} else { |
5205
|
0
|
|
|
|
|
0
|
$gvsv->save($fullname); #even NULL save it, because of gp_free nonsense |
5206
|
|
|
|
|
|
|
# we need sv magic for the core_svs (PL_rs -> gv) (#314) |
5207
|
0
|
0
|
|
|
|
0
|
if (exists $core_svs->{$gvname}) { |
5208
|
0
|
0
|
|
|
|
0
|
if ($gvname eq "\\") { # ORS special case #318 (initially NULL) |
5209
|
0
|
|
|
|
|
0
|
return $sym; |
5210
|
|
|
|
|
|
|
} else { |
5211
|
0
|
0
|
|
|
|
0
|
$gvsv->save_magic($fullname) if ref($gvsv) eq 'B::PVMG'; |
5212
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "SvREFCNT(s\\_%x) += 1;", $$gvsv ) ); |
5213
|
|
|
|
|
|
|
} |
5214
|
|
|
|
|
|
|
} |
5215
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvSVn(%s) = (SV*)s\\_%x;", $sym, $$gvsv ) ); |
5216
|
|
|
|
|
|
|
} |
5217
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'main::$') { # $$ = PerlProc_getpid() issue #108 |
5218
|
0
|
0
|
|
|
|
0
|
warn sprintf( " GV $sym \$\$ perlpid\n") if $debug{gv}; |
5219
|
0
|
|
|
|
|
0
|
$init->add( "sv_setiv(GvSV($sym), (IV)PerlProc_getpid());" ); |
5220
|
|
|
|
|
|
|
} |
5221
|
0
|
0
|
|
|
|
0
|
warn "GV::save \$$fullname\n" if $debug{gv}; |
5222
|
|
|
|
|
|
|
} |
5223
|
0
|
|
|
|
|
0
|
my $gvav = $gv->AV; |
5224
|
0
|
0
|
0
|
|
|
0
|
if ( $$gvav && $savefields & Save_AV ) { |
5225
|
0
|
0
|
|
|
|
0
|
warn "GV::save \@$fullname\n" if $debug{gv}; |
5226
|
0
|
|
|
|
|
0
|
$gvav->save($fullname); |
5227
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvAV(%s) = s\\_%x;", $sym, $$gvav ) ); |
5228
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'main::-') { |
5229
|
0
|
|
|
|
|
0
|
$init->add( sprintf("AvFILLp(s\\_%x) = -1;", $$gvav), |
5230
|
|
|
|
|
|
|
sprintf("AvMAX(s\\_%x) = -1;", $$gvav)); |
5231
|
|
|
|
|
|
|
} |
5232
|
|
|
|
|
|
|
} |
5233
|
0
|
|
|
|
|
0
|
my $gvhv = $gv->HV; |
5234
|
0
|
0
|
0
|
|
|
0
|
if ( $$gvhv && $savefields & Save_HV ) { |
5235
|
0
|
0
|
|
|
|
0
|
if ($fullname ne 'main::ENV') { |
5236
|
0
|
0
|
|
|
|
0
|
warn "GV::save \%$fullname\n" if $debug{gv}; |
5237
|
0
|
0
|
0
|
|
|
0
|
if ($fullname eq 'main::!') { # force loading Errno |
|
|
0
|
|
|
|
|
|
5238
|
0
|
|
|
|
|
0
|
$init->add("/* \%! force saving of Errno */"); |
5239
|
0
|
|
|
|
|
0
|
mark_package('Config', 1); # Errno needs Config to set the EGV |
5240
|
0
|
|
|
|
|
0
|
walk_syms('Config'); |
5241
|
0
|
|
|
|
|
0
|
mark_package('Errno', 1); # B::C needs Errno but does not import $! |
5242
|
|
|
|
|
|
|
} elsif ($fullname eq 'main::+' or $fullname eq 'main::-') { |
5243
|
0
|
|
|
|
|
0
|
$init->add("/* \%$gvname force saving of Tie::Hash::NamedCapture */"); |
5244
|
0
|
0
|
|
|
|
0
|
if ($PERL514) { |
5245
|
0
|
|
|
|
|
0
|
mark_package('Config', 1); # DynaLoader needs Config to set the EGV |
5246
|
0
|
|
|
|
|
0
|
walk_syms('Config'); |
5247
|
0
|
|
|
|
|
0
|
svref_2object(\&{'Tie::Hash::NamedCapture::bootstrap'})->save; |
|
0
|
|
|
|
|
0
|
|
5248
|
|
|
|
|
|
|
} |
5249
|
0
|
|
|
|
|
0
|
mark_package('Tie::Hash::NamedCapture', 1); |
5250
|
|
|
|
|
|
|
} |
5251
|
|
|
|
|
|
|
# skip static %Encode::Encoding since 5.20. GH #200. sv_upgrade cannot upgrade itself. |
5252
|
|
|
|
|
|
|
# Let it be initialized by boot_Encode/Encode_XSEncodingm with exceptions. |
5253
|
|
|
|
|
|
|
# GH #200 and t/testc.sh 75 |
5254
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.020 and $fullname eq 'Encode::Encoding') { |
|
|
0
|
|
|
|
|
|
5255
|
0
|
0
|
|
|
|
0
|
warn "skip some %Encode::Encoding - XS initialized\n" if $debug{gv}; |
5256
|
0
|
|
|
|
|
0
|
my %tmp_Encode_Encoding = %Encode::Encoding; |
5257
|
0
|
|
|
|
|
0
|
%Encode::Encoding = (); # but we need some non-XS encoding keys |
5258
|
0
|
|
|
|
|
0
|
for my $k (qw(utf8 utf-8-strict Unicode Internal Guess)) { |
5259
|
0
|
0
|
|
|
|
0
|
$Encode::Encoding{$k} = $tmp_Encode_Encoding{$k} if exists $tmp_Encode_Encoding{$k}; |
5260
|
|
|
|
|
|
|
} |
5261
|
0
|
|
|
|
|
0
|
$gvhv->save($fullname); |
5262
|
0
|
|
|
|
|
0
|
$init->add( "/* deferred some XS enc pointers for \%Encode::Encoding */", |
5263
|
|
|
|
|
|
|
sprintf("GvHV(%s) = s\\_%x;", $sym, $$gvhv ) ); |
5264
|
0
|
|
|
|
|
0
|
%Encode::Encoding = %tmp_Encode_Encoding; |
5265
|
|
|
|
|
|
|
} |
5266
|
|
|
|
|
|
|
# XXX TODO 49: crash at BEGIN { %warnings::Bits = ... } |
5267
|
|
|
|
|
|
|
elsif ($fullname ne 'main::INC') { |
5268
|
0
|
|
|
|
|
0
|
$gvhv->save($fullname); |
5269
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvHV(%s) = s\\_%x;", $sym, $$gvhv ) ); |
5270
|
|
|
|
|
|
|
} |
5271
|
|
|
|
|
|
|
} |
5272
|
|
|
|
|
|
|
} |
5273
|
0
|
|
|
|
|
0
|
my $gvcv = $gv->CV; |
5274
|
0
|
0
|
0
|
|
|
0
|
if ( !$$gvcv and $savefields & Save_CV ) { |
5275
|
0
|
0
|
|
|
|
0
|
warn "Empty CV $fullname, AUTOLOAD and try again\n" if $debug{gv}; |
5276
|
55
|
|
|
55
|
|
255
|
no strict 'refs'; |
|
55
|
|
|
|
|
73
|
|
|
55
|
|
|
|
|
10576
|
|
5277
|
|
|
|
|
|
|
# Fix test 31, catch unreferenced AUTOLOAD. The downside: |
5278
|
|
|
|
|
|
|
# It stores the whole optree and all its children. |
5279
|
|
|
|
|
|
|
# Similar with test 39: re::is_regexp |
5280
|
0
|
|
|
|
|
0
|
svref_2object( \*{"$package\::AUTOLOAD"} )->save |
5281
|
0
|
0
|
0
|
|
|
0
|
if $package and exists ${"$package\::"}{AUTOLOAD}; |
|
0
|
|
|
|
|
0
|
|
5282
|
0
|
|
|
|
|
0
|
svref_2object( \*{"$package\::CLONE"} )->save |
5283
|
0
|
0
|
0
|
|
|
0
|
if $package and exists ${"$package\::"}{CLONE}; |
|
0
|
|
|
|
|
0
|
|
5284
|
0
|
|
|
|
|
0
|
$gvcv = $gv->CV; # try again |
5285
|
|
|
|
|
|
|
} |
5286
|
0
|
0
|
0
|
|
|
0
|
if ( $$gvcv and $savefields & Save_CV |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5287
|
|
|
|
|
|
|
and ref($gvcv) eq 'B::CV' |
5288
|
|
|
|
|
|
|
and ref($gvcv->GV->EGV) ne 'B::SPECIAL' |
5289
|
|
|
|
|
|
|
and !skip_pkg($package) ) |
5290
|
|
|
|
|
|
|
{ |
5291
|
0
|
|
|
|
|
0
|
my $package = $gvcv->GV->EGV->STASH->NAME; |
5292
|
0
|
|
|
|
|
0
|
my $oname = $gvcv->GV->EGV->NAME; |
5293
|
0
|
|
|
|
|
0
|
my $origname = $package . "::" . $oname; |
5294
|
0
|
|
|
|
|
0
|
my $cvsym; |
5295
|
0
|
0
|
0
|
|
|
0
|
if ( $gvcv->XSUB and $oname ne '__ANON__' and $fullname ne $origname ) { #XSUB CONSTSUB alias |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5296
|
|
|
|
|
|
|
warn "Boot $package, XS CONSTSUB alias of $fullname to $origname\n" |
5297
|
0
|
0
|
|
|
|
0
|
if $debug{pkg}; |
5298
|
0
|
|
|
|
|
0
|
mark_package($package, 1); |
5299
|
|
|
|
|
|
|
{ |
5300
|
55
|
|
|
55
|
|
220
|
no strict 'refs'; |
|
55
|
|
|
|
|
80
|
|
|
55
|
|
|
|
|
61849
|
|
|
0
|
|
|
|
|
0
|
|
5301
|
0
|
|
|
|
|
0
|
svref_2object( \&{"$package\::bootstrap"} )->save |
5302
|
0
|
0
|
0
|
|
|
0
|
if $package and defined &{"$package\::bootstrap"}; |
|
0
|
|
|
|
|
0
|
|
5303
|
|
|
|
|
|
|
} |
5304
|
|
|
|
|
|
|
# XXX issue 57: incomplete xs dependency detection |
5305
|
0
|
|
|
|
|
0
|
my %hack_xs_detect = |
5306
|
|
|
|
|
|
|
('Scalar::Util' => 'List::Util', |
5307
|
|
|
|
|
|
|
'Sub::Exporter' => 'Params::Util', |
5308
|
|
|
|
|
|
|
); |
5309
|
0
|
0
|
|
|
|
0
|
if (my $dep = $hack_xs_detect{$package}) { |
5310
|
0
|
|
|
|
|
0
|
svref_2object( \&{"$dep\::bootstrap"} )->save; |
|
0
|
|
|
|
|
0
|
|
5311
|
|
|
|
|
|
|
} |
5312
|
|
|
|
|
|
|
# must save as a 'stub' so newXS() has a CV to populate |
5313
|
0
|
0
|
|
|
|
0
|
warn "save stub CvGV for $sym GP assignments $origname\n" if $debug{gv}; |
5314
|
0
|
|
|
|
|
0
|
$init2->add( |
5315
|
|
|
|
|
|
|
sprintf("if ((sv = (SV*)%s))", get_cv($origname, "GV_ADD")), |
5316
|
|
|
|
|
|
|
sprintf(" GvCV_set(%s, (CV*)SvREFCNT_inc_simple_NN(sv));", $sym)); |
5317
|
|
|
|
|
|
|
# TODO: add evtl. to SvRV also. |
5318
|
|
|
|
|
|
|
} |
5319
|
|
|
|
|
|
|
elsif (!$PERL510 or $gp) { |
5320
|
0
|
0
|
|
|
|
0
|
if ($fullname eq 'Internals::V') { # local_patches if $] >= 5.011 |
5321
|
0
|
|
|
|
|
0
|
$gvcv = svref_2object( \&__ANON__::_V ); |
5322
|
|
|
|
|
|
|
} |
5323
|
|
|
|
|
|
|
# TODO: may need fix CvGEN if >0 to re-validate the CV methods |
5324
|
|
|
|
|
|
|
# on PERL510 (>0 +
|
5325
|
0
|
0
|
|
|
|
0
|
warn "GV::save &$fullname...\n" if $debug{gv}; |
5326
|
0
|
|
|
|
|
0
|
$cvsym = $gvcv->save($fullname); |
5327
|
|
|
|
|
|
|
# backpatch "$sym = gv_fetchpv($name, GV_ADD, SVt_PV)" to SVt_PVCV |
5328
|
0
|
0
|
|
|
|
0
|
if ($cvsym =~ /get_cv/) { |
|
|
0
|
|
|
|
|
|
5329
|
0
|
0
|
0
|
|
|
0
|
if (!$xsub{$package} and in_static_core($package, $gvname)) { |
|
|
0
|
|
|
|
|
|
5330
|
0
|
|
|
|
|
0
|
my $in_gv; |
5331
|
0
|
|
|
|
|
0
|
for (@{ $init->[-1]{current} }) { |
|
0
|
|
|
|
|
0
|
|
5332
|
0
|
0
|
|
|
|
0
|
if ($in_gv) { |
5333
|
0
|
|
|
|
|
0
|
s/^.*\Q$sym\E.*=.*;//; |
5334
|
0
|
|
|
|
|
0
|
s/GvGP_set\(\Q$sym\E.*;//; |
5335
|
|
|
|
|
|
|
} |
5336
|
0
|
|
|
|
|
0
|
my $gv_get = gv_fetchpvn($name, "GV_ADD", "SVt_PV"); |
5337
|
0
|
|
|
|
|
0
|
my $new_gv_get = gv_fetchpvn($name, "GV_ADD", "SVt_PVCV"); |
5338
|
0
|
0
|
|
|
|
0
|
if (/^\Q$sym = $gv_get;\E/) { |
5339
|
0
|
|
|
|
|
0
|
s/^\Q$sym = $gv_get;\E/$sym = $new_gv_get;/; |
5340
|
0
|
|
|
|
|
0
|
$in_gv++; |
5341
|
0
|
0
|
|
|
|
0
|
warn "removed $sym GP assignments $origname (core CV)\n" if $debug{gv}; |
5342
|
|
|
|
|
|
|
} |
5343
|
|
|
|
|
|
|
} |
5344
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvCV_set(%s, (CV*)SvREFCNT_inc(%s));", $sym, $cvsym )); |
5345
|
|
|
|
|
|
|
} |
5346
|
|
|
|
|
|
|
elsif ($xsub{$package}) { |
5347
|
|
|
|
|
|
|
# must save as a 'stub' so newXS() has a CV to populate later in dl_init() |
5348
|
0
|
0
|
|
|
|
0
|
warn "save stub CvGV for $sym GP assignments $origname (XS CV)\n" if $debug{gv}; |
5349
|
0
|
0
|
|
|
|
0
|
my $get_cv = get_cv($oname ne "__ANON__" ? $origname : $fullname, "GV_ADD"); |
5350
|
0
|
|
|
|
|
0
|
$init2->add(sprintf("if ((sv = (SV*)%s))", $get_cv), |
5351
|
|
|
|
|
|
|
sprintf(" GvCV_set(%s, (CV*)SvREFCNT_inc_simple_NN(sv));", $sym)); |
5352
|
|
|
|
|
|
|
} |
5353
|
|
|
|
|
|
|
else { |
5354
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvCV_set(%s, (CV*)(%s));", $sym, $cvsym )); |
5355
|
|
|
|
|
|
|
} |
5356
|
0
|
0
|
|
|
|
0
|
if ($gvcv->XSUBANY) { |
5357
|
|
|
|
|
|
|
# some XSUB's set this field. but which part? |
5358
|
0
|
|
|
|
|
0
|
my $xsubany = $gvcv->XSUBANY; |
5359
|
0
|
0
|
|
|
|
0
|
if ($package =~ /^DBI::(common|db|dr|st)/) { |
|
|
0
|
|
|
|
|
|
5360
|
|
|
|
|
|
|
# DBI uses the any_ptr for dbi_ima_t *ima, and all dr,st,db,fd,xx handles |
5361
|
|
|
|
|
|
|
# for which several ptrs need to be patched. #359 |
5362
|
|
|
|
|
|
|
# the ima is internal only |
5363
|
0
|
|
|
|
|
0
|
my $dr = $1; |
5364
|
|
|
|
|
|
|
warn sprintf("eval_pv: DBI->_install_method(%s-) (XSUBANY=0x%x)\n", |
5365
|
0
|
0
|
0
|
|
|
0
|
$fullname, $xsubany) if $verbose and $debug{cv}; |
5366
|
0
|
|
|
|
|
0
|
$init2->add_eval(sprintf("DBI->_install_method('%s', 'DBI.pm', \$DBI::DBI_methods{%s}{%s})", |
5367
|
|
|
|
|
|
|
$fullname, $dr, $fullname)); |
5368
|
|
|
|
|
|
|
} elsif ($package eq 'Tie::Hash::NamedCapture') { |
5369
|
|
|
|
|
|
|
# pretty high _ALIAS CvXSUBANY.any_i32 values |
5370
|
|
|
|
|
|
|
} else { |
5371
|
|
|
|
|
|
|
# try if it points to an already registered symbol |
5372
|
0
|
|
|
|
|
0
|
my $anyptr = $symtable{ sprintf( "s\\_%x", $xsubany ) }; |
5373
|
0
|
0
|
0
|
|
|
0
|
if ($anyptr and $xsubany > 1000) { # not a XsubAliases |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
5374
|
0
|
|
|
|
|
0
|
$init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_ptr = &%s;", $sym, $anyptr )); |
5375
|
|
|
|
|
|
|
} # some heuristics TODO. long or ptr? TODO 32bit |
5376
|
|
|
|
|
|
|
elsif ($xsubany > 0x100000 |
5377
|
|
|
|
|
|
|
and ($xsubany < 0xffffff00 or $xsubany > 0xffffffff)) |
5378
|
|
|
|
|
|
|
{ |
5379
|
0
|
0
|
0
|
|
|
0
|
if ($package eq 'POSIX' and $gvname =~ /^is/) { |
|
|
0
|
0
|
|
|
|
|
5380
|
|
|
|
|
|
|
# need valid XSANY.any_dptr |
5381
|
0
|
|
|
|
|
0
|
$init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_dptr = (void*)&%s;", $sym, $gvname)); |
5382
|
|
|
|
|
|
|
} elsif ($package eq 'List::MoreUtils' and $gvname =~ /_iterator$/) { |
5383
|
|
|
|
|
|
|
# should be only the 2 iterators |
5384
|
0
|
|
|
|
|
0
|
$init2->add( sprintf( "CvXSUBANY(GvCV(%s)).any_ptr = (void*)&%s;", $sym, |
5385
|
|
|
|
|
|
|
"XS_List__MoreUtils__".$gvname)); |
5386
|
|
|
|
|
|
|
} else { |
5387
|
0
|
0
|
|
|
|
0
|
warn sprintf("TODO: Skipping %s->XSUBANY = 0x%x\n", $fullname, $xsubany ) if $verbose; |
5388
|
0
|
|
|
|
|
0
|
$init2->add( sprintf( "/* TODO CvXSUBANY(GvCV(%s)).any_ptr = 0x%lx; */", $sym, $xsubany )); |
5389
|
|
|
|
|
|
|
} |
5390
|
|
|
|
|
|
|
} elsif ($package eq 'Fcntl') { |
5391
|
|
|
|
|
|
|
# S_ macro values |
5392
|
|
|
|
|
|
|
} else { |
5393
|
|
|
|
|
|
|
# most likely any_i32 values for the XsubAliases provided by xsubpp |
5394
|
0
|
|
|
|
|
0
|
$init2->add( sprintf( "/* CvXSUBANY(GvCV(%s)).any_i32 = 0x%x; XSUB Alias */", $sym, $xsubany )); |
5395
|
|
|
|
|
|
|
} |
5396
|
|
|
|
|
|
|
} |
5397
|
|
|
|
|
|
|
} |
5398
|
|
|
|
|
|
|
} |
5399
|
|
|
|
|
|
|
elsif ($cvsym =~ /^(cv|&sv_list)/) { |
5400
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvCV_set(%s, (CV*)(%s));", $sym, $cvsym )); |
5401
|
|
|
|
|
|
|
} |
5402
|
|
|
|
|
|
|
else { |
5403
|
0
|
0
|
0
|
|
|
0
|
warn "wrong CvGV for $sym $origname: $cvsym\n" if $debug{gv} or $verbose; |
5404
|
|
|
|
|
|
|
} |
5405
|
|
|
|
|
|
|
} |
5406
|
|
|
|
|
|
|
# special handling for backref magic |
5407
|
0
|
0
|
0
|
|
|
0
|
if ($PERL514 and $cvsym and $cvsym !~ /(get_cv|NULL|lexwarn)/ and $gv->MAGICAL) { |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5408
|
0
|
|
|
|
|
0
|
my @magic = $gv->MAGIC; |
5409
|
0
|
|
|
|
|
0
|
foreach my $mg (@magic) { |
5410
|
0
|
0
|
|
|
|
0
|
if ($mg->TYPE eq '<') { |
5411
|
0
|
|
|
|
|
0
|
$init->add( "sv_magic((SV*)$sym, (SV*)$cvsym, '<', 0, 0);", |
5412
|
|
|
|
|
|
|
"CvCVGV_RC_off($cvsym);"); |
5413
|
0
|
0
|
|
|
|
0
|
if (!($mg->FLAGS & 2)) { |
5414
|
0
|
|
|
|
|
0
|
mg_RC_off($mg, $sym, '<'); # 390 |
5415
|
|
|
|
|
|
|
} |
5416
|
|
|
|
|
|
|
} |
5417
|
|
|
|
|
|
|
} |
5418
|
|
|
|
|
|
|
} |
5419
|
|
|
|
|
|
|
} |
5420
|
0
|
0
|
0
|
|
|
0
|
if (!$PERL510 or $gp) { |
5421
|
0
|
0
|
|
|
|
0
|
if ( $] > 5.009 ) { |
5422
|
|
|
|
|
|
|
# TODO implement heksect to place all heks at the beginning |
5423
|
|
|
|
|
|
|
#$heksect->add($gv->FILE); |
5424
|
|
|
|
|
|
|
#$init->add(sprintf("GvFILE_HEK($sym) = hek_list[%d];", $heksect->index)); |
5425
|
|
|
|
|
|
|
|
5426
|
|
|
|
|
|
|
# XXX Maybe better leave it NULL or asis, than fighting broken |
5427
|
0
|
0
|
0
|
|
|
0
|
if ($B::C::stash and $fullname =~ /::$/) { |
5428
|
|
|
|
|
|
|
# ignore stash hek asserts when adding the stash |
5429
|
|
|
|
|
|
|
# he->shared_he_he.hent_hek == hek assertions (#46 with IO::Poll::) |
5430
|
|
|
|
|
|
|
} else { |
5431
|
0
|
|
|
|
|
0
|
my $file = save_hek($gv->FILE,$fullname,1); |
5432
|
0
|
0
|
0
|
|
|
0
|
$init->add(sprintf("GvFILE_HEK(%s) = %s;", $sym, $file)) |
5433
|
|
|
|
|
|
|
if $file ne 'NULL' and !$optimize_cop; |
5434
|
|
|
|
|
|
|
} |
5435
|
|
|
|
|
|
|
# $init->add(sprintf("GvNAME_HEK($sym) = %s;", save_hek($gv->NAME))) if $gv->NAME; |
5436
|
|
|
|
|
|
|
} else { |
5437
|
|
|
|
|
|
|
# XXX ifdef USE_ITHREADS and PL_curcop->op_flags & OPf_COP_TEMP |
5438
|
|
|
|
|
|
|
# GvFILE is at gp+1 |
5439
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "GvFILE(%s) = %s;", $sym, cstring( $gv->FILE ) )) |
5440
|
|
|
|
|
|
|
unless $optimize_cop; |
5441
|
|
|
|
|
|
|
warn "GV::save GvFILE(*$fullname) " . cstring( $gv->FILE ) . "\n" |
5442
|
0
|
0
|
0
|
|
|
0
|
if $debug{gv} and !$ITHREADS; |
5443
|
|
|
|
|
|
|
} |
5444
|
0
|
|
|
|
|
0
|
my $gvform = $gv->FORM; |
5445
|
0
|
0
|
0
|
|
|
0
|
if ( $$gvform && $savefields & Save_FORM ) { |
5446
|
0
|
0
|
|
|
|
0
|
warn "GV::save GvFORM(*$fullname) ...\n" if $debug{gv}; |
5447
|
0
|
|
|
|
|
0
|
$gvform->save($fullname); |
5448
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvFORM(%s) = (CV*)s\\_%x;", $sym, $$gvform )); |
5449
|
|
|
|
|
|
|
# glob_assign_glob analog to CV |
5450
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf( "SvREFCNT_inc(s\\_%x);", $$gvform )) if $PERL510; |
5451
|
0
|
0
|
|
|
|
0
|
warn "GV::save GvFORM(*$fullname) done\n" if $debug{gv}; |
5452
|
|
|
|
|
|
|
} |
5453
|
0
|
|
|
|
|
0
|
my $gvio = $gv->IO; |
5454
|
0
|
0
|
0
|
|
|
0
|
if ( $$gvio && $savefields & Save_IO ) { |
5455
|
0
|
0
|
|
|
|
0
|
warn "GV::save GvIO(*$fullname)...\n" if $debug{gv}; |
5456
|
0
|
0
|
0
|
|
|
0
|
if ( $fullname =~ m/::DATA$/ && |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5457
|
|
|
|
|
|
|
( $fullname eq 'main::DATA' or $B::C::save_data_fh) ) # -O2 or 5.8 |
5458
|
|
|
|
|
|
|
{ |
5459
|
55
|
|
|
55
|
|
288
|
no strict 'refs'; |
|
55
|
|
|
|
|
83
|
|
|
55
|
|
|
|
|
2247
|
|
5460
|
0
|
|
|
|
|
0
|
my $fh = *{$fullname}{IO}; |
|
0
|
|
|
|
|
0
|
|
5461
|
55
|
|
|
55
|
|
212
|
use strict 'refs'; |
|
55
|
|
|
|
|
83
|
|
|
55
|
|
|
|
|
479673
|
|
5462
|
0
|
0
|
|
|
|
0
|
warn "GV::save_data $sym, $fullname ...\n" if $debug{gv}; |
5463
|
0
|
|
|
|
|
0
|
$gvio->save($fullname, 'is_DATA'); |
5464
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) ); |
5465
|
0
|
0
|
|
|
|
0
|
$gvio->save_data( $sym, $fullname, <$fh> ) if $fh->opened; |
5466
|
|
|
|
|
|
|
} elsif ( $fullname =~ m/::DATA$/ && !$B::C::save_data_fh ) { |
5467
|
0
|
|
|
|
|
0
|
$gvio->save($fullname, 'is_DATA'); |
5468
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) ); |
5469
|
0
|
|
|
|
|
0
|
warn "Warning: __DATA__ handle $fullname not stored. Need -O2 or -fsave-data.\n"; |
5470
|
|
|
|
|
|
|
} else { |
5471
|
0
|
|
|
|
|
0
|
$gvio->save($fullname); |
5472
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "GvIOp(%s) = s\\_%x;", $sym, $$gvio ) ); |
5473
|
|
|
|
|
|
|
} |
5474
|
0
|
0
|
|
|
|
0
|
warn "GV::save GvIO(*$fullname) done\n" if $debug{gv}; |
5475
|
|
|
|
|
|
|
} |
5476
|
0
|
|
|
|
|
0
|
$init->add(""); |
5477
|
|
|
|
|
|
|
} |
5478
|
|
|
|
|
|
|
} |
5479
|
|
|
|
|
|
|
# Shouldn't need to do save_magic since gv_fetchpv handles that. Esp. < and IO not |
5480
|
|
|
|
|
|
|
# $gv->save_magic($fullname) if $PERL510; |
5481
|
0
|
0
|
|
|
|
0
|
warn "GV::save *$fullname done\n" if $debug{gv}; |
5482
|
0
|
|
|
|
|
0
|
return $sym; |
5483
|
|
|
|
|
|
|
} |
5484
|
|
|
|
|
|
|
|
5485
|
|
|
|
|
|
|
sub B::AV::save { |
5486
|
0
|
|
|
0
|
|
0
|
my ($av, $fullname, $cv) = @_; |
5487
|
0
|
|
|
|
|
0
|
my $sym = objsym($av); |
5488
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
5489
|
|
|
|
|
|
|
|
5490
|
0
|
0
|
|
|
|
0
|
$fullname = '' unless $fullname; |
5491
|
0
|
|
|
|
|
0
|
my ($fill, $avreal, $max, $static_av, $av_cow, $av_cog); |
5492
|
0
|
|
|
|
|
0
|
my $ispadlist = ref($av) eq 'B::PADLIST'; |
5493
|
0
|
|
|
|
|
0
|
my $ispadnamelist = ref($av) eq 'B::PADNAMELIST'; |
5494
|
0
|
0
|
0
|
|
|
0
|
if ($ispadnamelist or $ispadlist) { |
5495
|
0
|
|
|
|
|
0
|
$fill = $av->MAX; |
5496
|
|
|
|
|
|
|
} else { |
5497
|
|
|
|
|
|
|
# cornercase: tied array without FETCHSIZE |
5498
|
0
|
|
|
|
|
0
|
eval { $fill = $av->FILL; }; |
|
0
|
|
|
|
|
0
|
|
5499
|
0
|
0
|
|
|
|
0
|
$fill = -1 if $@; # catch error in tie magic |
5500
|
|
|
|
|
|
|
} |
5501
|
0
|
|
|
|
|
0
|
$max = $fill; |
5502
|
0
|
0
|
|
|
|
0
|
my $svpcast = $ispadlist ? "(PAD*)" : "(SV*)"; |
5503
|
0
|
0
|
|
|
|
0
|
$svpcast = "(PADNAME*)" if $ispadnamelist; |
5504
|
|
|
|
|
|
|
|
5505
|
0
|
0
|
0
|
|
|
0
|
if ($PERL522 and $ispadnamelist) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5506
|
0
|
|
|
|
|
0
|
$padnlsect->comment("xpadnl_fill, xpadnl_alloc, xpadnl_max, xpadnl_max_named, xpadnl_refcnt"); |
5507
|
|
|
|
|
|
|
# TODO: max_named walk all names and look for non-empty names |
5508
|
0
|
|
|
|
|
0
|
my $refcnt = $av->REFCNT + 1; # XXX defer free to global destruction: 28 |
5509
|
0
|
|
|
|
|
0
|
my $maxnamed = $av->MAXNAMED; |
5510
|
0
|
|
|
|
|
0
|
$padnlsect->add("$fill, NULL, $fill, $maxnamed, $refcnt /* +1 */"); |
5511
|
0
|
|
|
|
|
0
|
$padnl_index = $padnlsect->index; |
5512
|
0
|
|
|
|
|
0
|
$sym = savesym( $av, "&padnamelist_list[$padnl_index]" ); |
5513
|
0
|
|
|
|
|
0
|
push @B::C::static_free, $sym; |
5514
|
|
|
|
|
|
|
} |
5515
|
|
|
|
|
|
|
elsif ($ispadlist and $] >= 5.021008) { # id+outid as U32 (PL_padlist_generation++) |
5516
|
0
|
|
|
|
|
0
|
$padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_id, xpadl_outid"); |
5517
|
0
|
|
|
|
|
0
|
my ($id, $outid) = ($av->ID, $av->OUTID); |
5518
|
0
|
|
|
|
|
0
|
$padlistsect->add("$fill, NULL, $id, $outid"); |
5519
|
0
|
|
|
|
|
0
|
$padlist_index = $padlistsect->index; |
5520
|
0
|
|
|
|
|
0
|
$sym = savesym( $av, "&padlist_list[$padlist_index]" ); |
5521
|
|
|
|
|
|
|
} |
5522
|
|
|
|
|
|
|
elsif ($ispadlist and $] >= 5.017006 and $] < 5.021008) { # id added again with b4db586814 |
5523
|
0
|
|
|
|
|
0
|
$padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_outid"); |
5524
|
0
|
|
|
|
|
0
|
$padlistsect->add("$fill, NULL, NULL"); # Perl_pad_new(0) |
5525
|
0
|
|
|
|
|
0
|
$padlist_index = $padlistsect->index; |
5526
|
0
|
|
|
|
|
0
|
$sym = savesym( $av, "&padlist_list[$padlist_index]" ); |
5527
|
0
|
0
|
0
|
|
|
0
|
if ($cv and $cv->OUTSIDE and ref($cv->OUTSIDE) ne 'B::SPECIAL' and $cv->OUTSIDE->PADLIST) { |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5528
|
0
|
|
|
|
|
0
|
my $outid = $cv->OUTSIDE->PADLIST->save(); |
5529
|
0
|
0
|
|
|
|
0
|
$init->add("($sym)->xpadl_outid = (PADNAMELIST*)$outid;") if $outid; |
5530
|
|
|
|
|
|
|
} |
5531
|
|
|
|
|
|
|
} |
5532
|
|
|
|
|
|
|
elsif ($ispadlist and $] >= 5.017004) { |
5533
|
0
|
|
|
|
|
0
|
$padlistsect->comment("xpadl_max, xpadl_alloc, xpadl_id, xpadl_outid"); |
5534
|
0
|
|
|
|
|
0
|
$padlistsect->add("$fill, NULL, 0, 0"); # Perl_pad_new(0) |
5535
|
0
|
|
|
|
|
0
|
$padlist_index = $padlistsect->index; |
5536
|
0
|
|
|
|
|
0
|
$sym = savesym( $av, "&padlist_list[$padlist_index]" ); |
5537
|
0
|
0
|
0
|
|
|
0
|
if ($cv and $cv->OUTSIDE and ref($cv->OUTSIDE) ne 'B::SPECIAL' and $cv->OUTSIDE->PADLIST) { |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5538
|
0
|
|
|
|
|
0
|
my $outid = $cv->OUTSIDE->PADLIST->save(); |
5539
|
0
|
0
|
|
|
|
0
|
$init->add("($sym)->xpadl_outid = (PADNAMELIST*)$outid;") if $outid; |
5540
|
|
|
|
|
|
|
} |
5541
|
|
|
|
|
|
|
} |
5542
|
|
|
|
|
|
|
# we set it static, not perl. (c)perl only observes it. |
5543
|
|
|
|
|
|
|
# decide if to store the array static (with run-time cow overhead) or dynamic |
5544
|
|
|
|
|
|
|
elsif ($CPERL52 and $B::C::av_init and $fill > -1 |
5545
|
|
|
|
|
|
|
and (isAvSTATIC($av) or canAvSTATIC($av, $fullname))) |
5546
|
|
|
|
|
|
|
{ |
5547
|
0
|
|
|
|
|
0
|
$xpvavsect->comment( "stash, magic, fill, max, static alloc" ); |
5548
|
0
|
|
|
|
|
0
|
my $alloc = ""; |
5549
|
0
|
|
|
|
|
0
|
my $count = 0; |
5550
|
0
|
|
|
|
|
0
|
my $flags = $av->FLAGS; |
5551
|
|
|
|
|
|
|
# decide upon cow (const array, SVf_READONLY) or just cog (forbid av_extend) |
5552
|
0
|
0
|
0
|
|
|
0
|
my $av_cow = ($flags & SVf_READONLY or $fullname =~ /(::ISA|::INC|curpad_name)$/) ? 1 : 0; |
5553
|
0
|
|
|
|
|
0
|
my $magic = ''; # need to skip ->ARRAY with 'D' magic, test 90 |
5554
|
0
|
|
|
|
|
0
|
foreach my $mg ($av->MAGIC) { |
5555
|
0
|
|
|
|
|
0
|
$magic = $mg->TYPE; |
5556
|
0
|
0
|
|
|
|
0
|
if ($magic eq 'D') { |
5557
|
0
|
|
|
|
|
0
|
last; |
5558
|
|
|
|
|
|
|
} |
5559
|
|
|
|
|
|
|
} |
5560
|
0
|
0
|
|
|
|
0
|
my @array = $magic eq 'D' ? () : $av->ARRAY; |
5561
|
0
|
|
|
|
|
0
|
my $n = scalar @array; |
5562
|
0
|
0
|
|
|
|
0
|
my $name = ($av_cow ? "avcow_" : "avcog_") . $n; |
5563
|
0
|
|
|
|
|
0
|
my $avstaticsect; |
5564
|
0
|
0
|
|
|
|
0
|
if ($av_cow) { |
5565
|
0
|
0
|
|
|
|
0
|
$avcowsect{ $n } = new B::C::Section($name, \%symtable, 0) unless exists $avcowsect{ $n }; |
5566
|
0
|
|
|
|
|
0
|
$avstaticsect = $avcowsect{ $n }; |
5567
|
|
|
|
|
|
|
} else { |
5568
|
0
|
0
|
|
|
|
0
|
$avcogsect{ $n } = new B::C::Section($name, \%symtable, 0) unless exists $avcogsect{ $n }; |
5569
|
0
|
|
|
|
|
0
|
$avstaticsect = $avcogsect{ $n }; |
5570
|
|
|
|
|
|
|
} |
5571
|
0
|
|
|
|
|
0
|
my $sect = sprintf("&%s_list[%u]", $name, $avstaticsect->index + 1); |
5572
|
|
|
|
|
|
|
# protect against duplicates |
5573
|
0
|
|
|
|
|
0
|
$sym = savesym( $av, sprintf("(AV*)&sv_list[%u]", $svsect->index + 1)); |
5574
|
|
|
|
|
|
|
|
5575
|
|
|
|
|
|
|
# $B::C::const_strings = 0 if $flags & 0x40008000 == 0x40008000; # SVp_SCREAM|SVpbm_VALID |
5576
|
0
|
0
|
|
|
|
0
|
my @values = map { $_->save($fullname."[".$count++."]") || () } @array; |
|
0
|
|
|
|
|
0
|
|
5577
|
0
|
|
|
|
|
0
|
for (my $i=0; $i <= $#array; $i++) { |
5578
|
|
|
|
|
|
|
# if any value is non-static (GV), fall back to dynamic AV::save |
5579
|
0
|
0
|
|
|
|
0
|
if (!is_constant($values[$i])) { |
5580
|
0
|
|
|
|
|
0
|
$alloc = ''; |
5581
|
0
|
|
|
|
|
0
|
last; |
5582
|
|
|
|
|
|
|
} |
5583
|
0
|
|
|
|
|
0
|
$alloc .= $values[$i].", "; |
5584
|
|
|
|
|
|
|
} |
5585
|
0
|
0
|
0
|
|
|
0
|
if ($alloc and $n) { |
5586
|
0
|
|
|
|
|
0
|
$static_av = 1; |
5587
|
|
|
|
|
|
|
warn sprintf("turn on %s %s\n", $av_cow ? "AvIsCOW" : "AvSTATIC", $sym, $fullname) |
5588
|
0
|
0
|
|
|
|
0
|
if $debug{av}; |
|
|
0
|
|
|
|
|
|
5589
|
0
|
|
|
|
|
0
|
$flags |= SVf_IsCOW; # turn on AvSTATIC |
5590
|
|
|
|
|
|
|
# $flags |= SVf_READONLY if $av_cow; # and turn on COW |
5591
|
0
|
|
|
|
|
0
|
$alloc = substr($alloc,0,-2); |
5592
|
0
|
|
|
|
|
0
|
$avstaticsect->add( $alloc ); |
5593
|
0
|
|
|
|
|
0
|
$xpvavsect->add("Nullhv, {0}, $fill, $max, (SV**)$sect"); |
5594
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}", |
5595
|
|
|
|
|
|
|
$xpvavsect->index, $av->REFCNT, $flags, |
5596
|
|
|
|
|
|
|
($C99?".svu_array=(SV**)":"(char*)").$sect)); |
5597
|
0
|
|
|
|
|
0
|
$sym = savesym( $av, sprintf("(AV*)&sv_list[%u]", $svsect->index)); |
5598
|
|
|
|
|
|
|
} else { |
5599
|
|
|
|
|
|
|
warn sprintf("turn off AvSTATIC %s %s\n", $sym, $fullname) |
5600
|
0
|
0
|
|
|
|
0
|
if $debug{av}; |
5601
|
0
|
|
|
|
|
0
|
$flags &= ~SVf_IsCOW; # turn off AvSTATIC |
5602
|
0
|
|
|
|
|
0
|
my $line = "Nullhv, {0}, -1, -1, 0"; |
5603
|
0
|
0
|
0
|
|
|
0
|
$line = "Nullhv, {0}, $fill, $max, 0" if $B::C::av_init or $B::C::av_init2; |
5604
|
0
|
|
|
|
|
0
|
$xpvavsect->add($line); |
5605
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {0}", |
5606
|
|
|
|
|
|
|
$xpvavsect->index, $av->REFCNT, $flags)); |
5607
|
|
|
|
|
|
|
} |
5608
|
|
|
|
|
|
|
} |
5609
|
|
|
|
|
|
|
elsif ($PERL514) { |
5610
|
0
|
|
|
|
|
0
|
$xpvavsect->comment( "stash, magic, fill, max, alloc" ); |
5611
|
|
|
|
|
|
|
# 5.13.3: STASH, MAGIC, fill max ALLOC |
5612
|
0
|
|
|
|
|
0
|
my $line = "Nullhv, {0}, -1, -1, 0"; |
5613
|
0
|
0
|
0
|
|
|
0
|
$line = "Nullhv, {0}, $fill, $max, 0" if $B::C::av_init or $B::C::av_init2; |
5614
|
0
|
|
|
|
|
0
|
$xpvavsect->add($line); |
5615
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}", |
5616
|
|
|
|
|
|
|
$xpvavsect->index, $av->REFCNT, $av->FLAGS, |
5617
|
|
|
|
|
|
|
'0')); |
5618
|
|
|
|
|
|
|
#$avreal = $av->FLAGS & 0x40000000; # SVpav_REAL (unused) |
5619
|
|
|
|
|
|
|
} |
5620
|
|
|
|
|
|
|
elsif ($PERL510) { |
5621
|
0
|
|
|
|
|
0
|
$xpvavsect->comment( "xnv_u, fill, max, xiv_u, magic, stash" ); |
5622
|
|
|
|
|
|
|
# 5.9.4+: nvu fill max iv MG STASH |
5623
|
0
|
|
|
|
|
0
|
my $line = "{0}, -1, -1, {0}, {0}, Nullhv"; |
5624
|
0
|
0
|
0
|
|
|
0
|
$line = "{0}, $fill, $max, {0}, {0}, Nullhv" if $B::C::av_init or $B::C::av_init2; |
5625
|
0
|
0
|
|
|
|
0
|
$line = "Nullhv, {0}, $fill, $max, NULL" if $PERL514; |
5626
|
0
|
|
|
|
|
0
|
$xpvavsect->add($line); |
5627
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x, {%s}", |
5628
|
|
|
|
|
|
|
$xpvavsect->index, $av->REFCNT, $av->FLAGS, |
5629
|
|
|
|
|
|
|
'0')); |
5630
|
|
|
|
|
|
|
#$avreal = $av->FLAGS & 0x40000000; # SVpav_REAL (unused) |
5631
|
|
|
|
|
|
|
} |
5632
|
|
|
|
|
|
|
else { |
5633
|
0
|
|
|
|
|
0
|
$xpvavsect->comment( "array, fill, max, off, nv, magic, stash, alloc, arylen, flags" ); |
5634
|
|
|
|
|
|
|
# 5.8: ARRAY fill max off nv MG STASH ALLOC arylen flags |
5635
|
0
|
|
|
|
|
0
|
my $line = "0, -1, -1, 0, 0.0, 0, Nullhv, 0, 0"; |
5636
|
0
|
0
|
0
|
|
|
0
|
$line = "0, $fill, $max, 0, 0.0, 0, Nullhv, 0, 0" if $B::C::av_init or $B::C::av_init2; |
5637
|
0
|
0
|
|
|
|
0
|
$line .= sprintf( ", 0x%x", $av->AvFLAGS ) if $] < 5.009; |
5638
|
|
|
|
|
|
|
#$avreal = $av->AvFLAGS & 1; # AVf_REAL |
5639
|
0
|
|
|
|
|
0
|
$xpvavsect->add($line); |
5640
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvav_list[%d], $u32fmt, 0x%x", |
5641
|
|
|
|
|
|
|
$xpvavsect->index, $av->REFCNT, $av->FLAGS)); |
5642
|
|
|
|
|
|
|
} |
5643
|
|
|
|
|
|
|
|
5644
|
0
|
|
|
|
|
0
|
my ($magic, $av_index) = (''); |
5645
|
0
|
0
|
|
|
|
0
|
$svsect->debug($fullname, $av->flagspv) if $debug{flags}; |
5646
|
0
|
0
|
0
|
|
|
0
|
if (!$ispadlist and !$ispadnamelist) { |
5647
|
0
|
|
|
|
|
0
|
my $sv_ix = $svsect->index; |
5648
|
0
|
|
|
|
|
0
|
$av_index = $xpvavsect->index; |
5649
|
|
|
|
|
|
|
# protect against recursive self-references (Getopt::Long) |
5650
|
0
|
|
|
|
|
0
|
$sym = savesym( $av, "(AV*)&sv_list[$sv_ix]" ); |
5651
|
0
|
|
|
|
|
0
|
$magic = $av->save_magic($fullname); |
5652
|
0
|
0
|
0
|
|
|
0
|
push @B::C::static_free, $sym if $PERL518 and $av->FLAGS & SVs_OBJECT; |
5653
|
|
|
|
|
|
|
} |
5654
|
|
|
|
|
|
|
|
5655
|
0
|
0
|
|
|
|
0
|
if ( $debug{av} ) { |
5656
|
0
|
|
|
|
|
0
|
my $line = sprintf( "saving AV %s 0x%x [%s] FILL=%d", $fullname, $$av, B::class($av), $fill); |
5657
|
0
|
0
|
|
|
|
0
|
$line .= sprintf( " AvFLAGS=0x%x", $av->AvFLAGS ) if $] < 5.009; |
5658
|
0
|
|
|
|
|
0
|
warn "$line\n"; |
5659
|
|
|
|
|
|
|
} |
5660
|
|
|
|
|
|
|
|
5661
|
|
|
|
|
|
|
# XXX AVf_REAL is wrong test: need to save comppadlist but not stack |
5662
|
0
|
0
|
0
|
|
|
0
|
if ($fill > -1 and $magic !~ /D/ and !$static_av) { |
|
|
|
0
|
|
|
|
|
5663
|
0
|
|
|
|
|
0
|
my @array = $av->ARRAY; # crashes with D magic (Getopt::Long) |
5664
|
0
|
0
|
|
|
|
0
|
if ( $debug{av} ) { |
5665
|
0
|
|
|
|
|
0
|
my $i = 0; |
5666
|
0
|
|
|
|
|
0
|
foreach my $el (@array) { |
5667
|
0
|
|
|
|
|
0
|
my $val = ''; |
5668
|
|
|
|
|
|
|
# if SvIOK print iv, POK pv |
5669
|
0
|
0
|
|
|
|
0
|
if ($el->can('FLAGS')) { |
5670
|
0
|
0
|
|
|
|
0
|
$val = $el->IVX if $el->FLAGS & SVf_IOK; |
5671
|
0
|
0
|
|
|
|
0
|
$val = cstring($el->PV) if $el->FLAGS & SVf_POK; |
5672
|
|
|
|
|
|
|
} |
5673
|
0
|
|
|
|
|
0
|
warn sprintf( "AV $av \[%d] = %s $val\n", $i++, B::class($el) ); |
5674
|
|
|
|
|
|
|
} |
5675
|
|
|
|
|
|
|
} |
5676
|
|
|
|
|
|
|
|
5677
|
|
|
|
|
|
|
# my @names = map($_->save, @array); |
5678
|
|
|
|
|
|
|
# XXX Better ways to write loop? |
5679
|
|
|
|
|
|
|
# Perhaps svp[0] = ...; svp[1] = ...; svp[2] = ...; |
5680
|
|
|
|
|
|
|
# Perhaps I32 i = 0; svp[i++] = ...; svp[i++] = ...; svp[i++] = ...; |
5681
|
|
|
|
|
|
|
|
5682
|
|
|
|
|
|
|
# micro optimization: op/pat.t ( and other code probably ) |
5683
|
|
|
|
|
|
|
# has very large pads ( 20k/30k elements ) passing them to |
5684
|
|
|
|
|
|
|
# ->add is a performance bottleneck: passing them as a |
5685
|
|
|
|
|
|
|
# single string cuts runtime from 6min20sec to 40sec |
5686
|
|
|
|
|
|
|
|
5687
|
|
|
|
|
|
|
# you want to keep this out of the no_split/split |
5688
|
|
|
|
|
|
|
# map("\t*svp++ = (SV*)$_;", @names), |
5689
|
0
|
|
|
|
|
0
|
my $acc = ''; |
5690
|
|
|
|
|
|
|
# Init optimization by Nick Koston |
5691
|
|
|
|
|
|
|
# The idea is to create loops so there is less C code. In the real world this seems |
5692
|
|
|
|
|
|
|
# to reduce the memory usage ~ 3% and speed up startup time by about 8%. |
5693
|
0
|
|
|
|
|
0
|
my ($count, @values); |
5694
|
|
|
|
|
|
|
{ |
5695
|
0
|
|
|
|
|
0
|
local $B::C::const_strings = $B::C::const_strings; |
|
0
|
|
|
|
|
0
|
|
5696
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and !$ispadlist) { # force dynamic PADNAME strings |
5697
|
0
|
0
|
|
|
|
0
|
if ($] < 5.016) { $B::C::const_strings = 0 if $av->FLAGS & 0x40000000; } # SVpad_NAME |
|
0
|
0
|
|
|
|
0
|
|
5698
|
0
|
0
|
|
|
|
0
|
else { $B::C::const_strings = 0 if ($av->FLAGS & 0x40008000 == 0x40008000); } # SVp_SCREAM|SVpbm_VALID |
5699
|
|
|
|
|
|
|
} |
5700
|
0
|
0
|
|
|
|
0
|
@values = map { $_->save($fullname."[".$count++."]") || () } @array; |
|
0
|
|
|
|
|
0
|
|
5701
|
|
|
|
|
|
|
} |
5702
|
0
|
|
|
|
|
0
|
$count = 0; |
5703
|
0
|
|
|
|
|
0
|
for (my $i=0; $i <= $#array; $i++) { |
5704
|
0
|
0
|
0
|
|
|
0
|
if ($fullname =~ m/^(INIT|END)$/ and $values[$i] and ref $array[$i] eq 'B::CV') { |
|
|
|
0
|
|
|
|
|
5705
|
0
|
0
|
|
|
|
0
|
if ($array[$i]->XSUB) { |
5706
|
0
|
|
|
|
|
0
|
$values[$i] =~ s/, 0\)/, GV_ADD\)/; # GvCV filled in later |
5707
|
|
|
|
|
|
|
} |
5708
|
0
|
|
|
|
|
0
|
$values[$i] = sprintf("SvREFCNT_inc(%s);", $values[$i]); |
5709
|
|
|
|
|
|
|
} |
5710
|
0
|
0
|
0
|
|
|
0
|
if ( $use_svpop_speedup |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
5711
|
|
|
|
|
|
|
&& defined $values[$i] |
5712
|
|
|
|
|
|
|
&& defined $values[$i+1] |
5713
|
|
|
|
|
|
|
&& defined $values[$i+2] |
5714
|
|
|
|
|
|
|
&& $values[$i] =~ /^\&sv_list\[(\d+)\]/ |
5715
|
|
|
|
|
|
|
&& $values[$i+1] eq "&sv_list[" . ($1+1) . "]" |
5716
|
|
|
|
|
|
|
&& $values[$i+2] eq "&sv_list[" . ($1+2) . "]" ) |
5717
|
|
|
|
|
|
|
{ |
5718
|
0
|
|
|
|
|
0
|
$count=0; |
5719
|
0
|
|
0
|
|
|
0
|
while (defined($values[$i+$count+1]) and $values[$i+$count+1] eq "&sv_list[" . ($1+$count+1) . "]") { |
5720
|
0
|
|
|
|
|
0
|
$count++; |
5721
|
|
|
|
|
|
|
} |
5722
|
0
|
|
|
|
|
0
|
$acc .= "\tfor (gcount=" . $1 . "; gcount<" . ($1+$count+1) . "; gcount++) {" |
5723
|
|
|
|
|
|
|
." *svp++ = $svpcast&sv_list[gcount]; };\n\t"; |
5724
|
0
|
|
|
|
|
0
|
$i += $count; |
5725
|
|
|
|
|
|
|
} elsif ($use_av_undef_speedup |
5726
|
|
|
|
|
|
|
&& defined $values[$i] |
5727
|
|
|
|
|
|
|
&& defined $values[$i+1] |
5728
|
|
|
|
|
|
|
&& defined $values[$i+2] |
5729
|
|
|
|
|
|
|
&& $values[$i] =~ /^ptr_undef|&PL_sv_undef$/ |
5730
|
|
|
|
|
|
|
&& $values[$i+1] =~ /^ptr_undef|&PL_sv_undef$/ |
5731
|
|
|
|
|
|
|
&& $values[$i+2] =~ /^ptr_undef|&PL_sv_undef$/) |
5732
|
|
|
|
|
|
|
{ |
5733
|
0
|
|
|
|
|
0
|
$count=0; |
5734
|
0
|
|
0
|
|
|
0
|
while (defined $values[$i+$count+1] and $values[$i+$count+1] =~ /^ptr_undef|&PL_sv_undef$/) { |
5735
|
0
|
|
|
|
|
0
|
$count++; |
5736
|
|
|
|
|
|
|
} |
5737
|
0
|
|
|
|
|
0
|
$acc .= "\tfor (gcount=0; gcount<" . ($count+1) . "; gcount++) {" |
5738
|
|
|
|
|
|
|
." *svp++ = $svpcast&PL_sv_undef; };\n\t"; |
5739
|
0
|
|
|
|
|
0
|
$i += $count; |
5740
|
|
|
|
|
|
|
} else { # XXX 5.8.9d Test::NoWarnings has empty values |
5741
|
0
|
0
|
|
|
|
0
|
$acc .= "\t*svp++ = $svpcast" . ($values[$i] ? $values[$i] : '&PL_sv_undef') . ";\n\t"; |
5742
|
|
|
|
|
|
|
} |
5743
|
|
|
|
|
|
|
} |
5744
|
0
|
|
|
|
|
0
|
$init->no_split; |
5745
|
|
|
|
|
|
|
|
5746
|
0
|
0
|
|
|
|
0
|
if ($ispadnamelist) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
5747
|
0
|
|
|
|
|
0
|
my $fill1 = $fill+1; |
5748
|
0
|
|
|
|
|
0
|
$init->add("{", "\tPADNAME **svp;"); |
5749
|
0
|
0
|
|
|
|
0
|
$init->add("\tregister int gcount;") if $count; |
5750
|
0
|
|
|
|
|
0
|
$init->add( |
5751
|
|
|
|
|
|
|
"\tPADNAMELIST *padnl = $sym;", |
5752
|
|
|
|
|
|
|
sprintf("\tNewxz(svp, %d, PADNAME *);", $fill+1), |
5753
|
|
|
|
|
|
|
"\tPadnamelistARRAY(padnl) = svp;", |
5754
|
|
|
|
|
|
|
); |
5755
|
0
|
|
|
|
|
0
|
$init->add( substr( $acc, 0, -2 ) ); |
5756
|
0
|
|
|
|
|
0
|
$init->add("}"); |
5757
|
|
|
|
|
|
|
} |
5758
|
|
|
|
|
|
|
elsif ($ispadlist) { |
5759
|
0
|
|
|
|
|
0
|
my $fill1 = $fill+1; |
5760
|
0
|
|
|
|
|
0
|
$init->add("{", "\tPAD **svp;"); |
5761
|
0
|
0
|
|
|
|
0
|
$init->add("\tregister int gcount;") if $count; |
5762
|
0
|
|
|
|
|
0
|
$init->add( |
5763
|
|
|
|
|
|
|
"\tPADLIST *padl = $sym;", |
5764
|
|
|
|
|
|
|
sprintf("\tNewxz(svp, %d, PAD *);", $fill+1), |
5765
|
|
|
|
|
|
|
"\tPadlistARRAY(padl) = svp;", |
5766
|
|
|
|
|
|
|
); |
5767
|
0
|
|
|
|
|
0
|
$init->add( substr( $acc, 0, -2 ) ); |
5768
|
0
|
|
|
|
|
0
|
$init->add("}"); |
5769
|
|
|
|
|
|
|
} |
5770
|
|
|
|
|
|
|
# With -fav-init2 use independent_comalloc() |
5771
|
|
|
|
|
|
|
elsif ($B::C::av_init2) { |
5772
|
0
|
|
|
|
|
0
|
my $i = $av_index; |
5773
|
0
|
|
|
|
|
0
|
$xpvav_sizes[$i] = $fill; |
5774
|
0
|
|
|
|
|
0
|
my $init_add = "{ SV **svp = avchunks[$i]; AV *av = $sym;\n"; |
5775
|
0
|
0
|
|
|
|
0
|
$init_add .= "\tregister int gcount;\n" if $count; |
5776
|
0
|
0
|
|
|
|
0
|
if ($fill > -1) { |
5777
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
5778
|
0
|
|
|
|
|
0
|
$init_add .= "\tAvALLOC(av) = svp;\n". |
5779
|
|
|
|
|
|
|
"\tAvARRAY(av) = svp;\n"; |
5780
|
|
|
|
|
|
|
} else { |
5781
|
0
|
|
|
|
|
0
|
$init_add .= "\tAvALLOC(av) = svp;\n" . |
5782
|
|
|
|
|
|
|
# XXX Dirty hack from av.c:Perl_av_extend() |
5783
|
|
|
|
|
|
|
"\tSvPVX(av) = (char*)svp;"; |
5784
|
|
|
|
|
|
|
} |
5785
|
|
|
|
|
|
|
} |
5786
|
0
|
|
|
|
|
0
|
$init_add .= substr( $acc, 0, -2 ); |
5787
|
0
|
|
|
|
|
0
|
$init->add( $init_add . "}" ); |
5788
|
|
|
|
|
|
|
} |
5789
|
|
|
|
|
|
|
# With -fav-init faster initialize the array as the initial av_extend() |
5790
|
|
|
|
|
|
|
# is very expensive. |
5791
|
|
|
|
|
|
|
# The problem was calloc, not av_extend. |
5792
|
|
|
|
|
|
|
# Since we are always initializing every single element we don't need |
5793
|
|
|
|
|
|
|
# calloc, only malloc. wmemset'ting the pointer to PL_sv_undef |
5794
|
|
|
|
|
|
|
# might be faster also. |
5795
|
|
|
|
|
|
|
elsif ($B::C::av_init) { |
5796
|
0
|
|
|
|
|
0
|
$init->add( |
5797
|
|
|
|
|
|
|
"{", "\tSV **svp;", |
5798
|
|
|
|
|
|
|
"\tAV *av = $sym;"); |
5799
|
0
|
0
|
|
|
|
0
|
$init->add("\tregister int gcount;") if $count; |
5800
|
0
|
0
|
|
|
|
0
|
my $fill1 = $fill < 3 ? 3 : $fill+1; |
5801
|
0
|
0
|
|
|
|
0
|
if ($fill > -1) { |
5802
|
0
|
0
|
|
|
|
0
|
$fill1 = $fill+1 if $fullname eq 'END'; |
5803
|
|
|
|
|
|
|
# Perl_safesysmalloc (= calloc => malloc) or Perl_malloc (= mymalloc)? |
5804
|
0
|
0
|
|
|
|
0
|
if ($MYMALLOC) { |
5805
|
0
|
|
|
|
|
0
|
$init->add(sprintf("\tNewx(svp, %d, SV*);", $fill1), |
5806
|
|
|
|
|
|
|
"\tAvALLOC(av) = svp;"); |
5807
|
|
|
|
|
|
|
} else { |
5808
|
|
|
|
|
|
|
# Bypassing Perl_safesysmalloc on darwin fails with "free from wrong pool", test 25. |
5809
|
|
|
|
|
|
|
# So with DEBUGGING perls we have to track memory and use calloc. |
5810
|
0
|
|
|
|
|
0
|
$init->add("#ifdef PERL_TRACK_MEMPOOL", |
5811
|
|
|
|
|
|
|
sprintf("\tsvp = (SV**)Perl_safesysmalloc(%d * sizeof(SV*));", $fill1), |
5812
|
|
|
|
|
|
|
"#else", |
5813
|
|
|
|
|
|
|
sprintf("\tsvp = (SV**)malloc(%d * sizeof(SV*));", $fill1), |
5814
|
|
|
|
|
|
|
"#endif", |
5815
|
|
|
|
|
|
|
"\tAvALLOC(av) = svp;"); |
5816
|
|
|
|
|
|
|
} |
5817
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
5818
|
0
|
|
|
|
|
0
|
$init->add("\tAvARRAY(av) = svp;"); |
5819
|
|
|
|
|
|
|
} else { # read-only AvARRAY macro |
5820
|
|
|
|
|
|
|
# XXX Dirty hack from av.c:Perl_av_extend() |
5821
|
0
|
|
|
|
|
0
|
$init->add("\tSvPVX(av) = (char*)svp;"); |
5822
|
|
|
|
|
|
|
} |
5823
|
|
|
|
|
|
|
} |
5824
|
0
|
|
|
|
|
0
|
$init->add( substr( $acc, 0, -2 ) ); # AvFILLp already in XPVAV |
5825
|
0
|
|
|
|
|
0
|
$init->add( "}" ); |
5826
|
|
|
|
|
|
|
} |
5827
|
|
|
|
|
|
|
else { # unoptimized with the full av_extend() |
5828
|
0
|
0
|
|
|
|
0
|
my $fill1 = $fill < 3 ? 3 : $fill+1; |
5829
|
0
|
|
|
|
|
0
|
$init->add("{", "\tSV **svp;"); |
5830
|
0
|
0
|
|
|
|
0
|
$init->add("\tregister int gcount;") if $count; |
5831
|
0
|
|
|
|
|
0
|
$init->add("\tAV *av = $sym;\t/* $fullname */", |
5832
|
|
|
|
|
|
|
"\tav_extend(av, $fill1);", |
5833
|
|
|
|
|
|
|
"\tsvp = AvARRAY(av);"); |
5834
|
0
|
|
|
|
|
0
|
$init->add( substr( $acc, 0, -2 ) ); |
5835
|
0
|
|
|
|
|
0
|
$init->add( "\tAvFILLp(av) = $fill;" ); |
5836
|
0
|
|
|
|
|
0
|
$init->add( "}" ); |
5837
|
|
|
|
|
|
|
} |
5838
|
0
|
|
|
|
|
0
|
$init->split; |
5839
|
|
|
|
|
|
|
|
5840
|
|
|
|
|
|
|
# we really added a lot of lines ( B::C::InitSection->add |
5841
|
|
|
|
|
|
|
# should really scan for \n, but that would slow |
5842
|
|
|
|
|
|
|
# it down |
5843
|
0
|
|
|
|
|
0
|
$init->inc_count($#array); |
5844
|
|
|
|
|
|
|
} |
5845
|
|
|
|
|
|
|
else { |
5846
|
0
|
|
|
|
|
0
|
my $max = $av->MAX; |
5847
|
0
|
0
|
0
|
|
|
0
|
$init->add("av_extend($sym, $max);") |
5848
|
|
|
|
|
|
|
if $max > -1 and !$static_av; |
5849
|
|
|
|
|
|
|
} |
5850
|
0
|
0
|
|
|
|
0
|
$init->add("SvREADONLY_on($sym);") if $av_cow; |
5851
|
0
|
|
|
|
|
0
|
return $sym; |
5852
|
|
|
|
|
|
|
} |
5853
|
|
|
|
|
|
|
|
5854
|
|
|
|
|
|
|
sub B::HV::save { |
5855
|
0
|
|
|
0
|
|
0
|
my ($hv, $fullname) = @_; |
5856
|
0
|
0
|
|
|
|
0
|
$fullname = '' unless $fullname; |
5857
|
0
|
|
|
|
|
0
|
my $sym = objsym($hv); |
5858
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
5859
|
0
|
|
|
|
|
0
|
my $name = $hv->NAME; |
5860
|
0
|
|
|
|
|
0
|
my $is_stash = $name; |
5861
|
0
|
|
|
|
|
0
|
my $magic; |
5862
|
0
|
0
|
|
|
|
0
|
if ($name) { |
5863
|
|
|
|
|
|
|
# It's a stash. See issue 79 + test 46 |
5864
|
|
|
|
|
|
|
warn sprintf( "Saving stash HV \"%s\" from \"$fullname\" 0x%x MAX=%d\n", |
5865
|
0
|
0
|
|
|
|
0
|
$name, $$hv, $hv->MAX ) if $debug{hv}; |
5866
|
|
|
|
|
|
|
|
5867
|
|
|
|
|
|
|
# A perl bug means HvPMROOT isn't altered when a PMOP is freed. Usually |
5868
|
|
|
|
|
|
|
# the only symptom is that sv_reset tries to reset the PMf_USED flag of |
5869
|
|
|
|
|
|
|
# a trashed op but we look at the trashed op_type and segfault. |
5870
|
|
|
|
|
|
|
#my $adpmroot = ${$hv->PMROOT}; # XXX When was this fixed? |
5871
|
0
|
|
|
|
|
0
|
my $adpmroot = 0; |
5872
|
0
|
|
|
|
|
0
|
$sym = savestashpv($name); |
5873
|
0
|
|
|
|
|
0
|
savesym( $hv, $sym ); |
5874
|
0
|
0
|
|
|
|
0
|
if ($adpmroot) { |
5875
|
0
|
|
|
|
|
0
|
$init->add(sprintf( "HvPMROOT(hv%d) = (PMOP*)s\\_%x;", |
5876
|
|
|
|
|
|
|
$hv_index, $adpmroot ) ); |
5877
|
|
|
|
|
|
|
} |
5878
|
0
|
0
|
0
|
|
|
0
|
if ($PERL518 and $hv->FLAGS & SVf_AMAGIC and length($name)) { |
|
|
|
0
|
|
|
|
|
5879
|
|
|
|
|
|
|
# fix overload stringify |
5880
|
0
|
0
|
|
|
|
0
|
if ($hv->Gv_AMG) { # potentially removes the AMG flag |
5881
|
0
|
|
|
|
|
0
|
$init2->add( sprintf("mro_isa_changed_in(%s); /* %s */", $sym, $name)); |
5882
|
|
|
|
|
|
|
} |
5883
|
|
|
|
|
|
|
} |
5884
|
|
|
|
|
|
|
# Add aliases if namecount > 1 (GH #331) |
5885
|
|
|
|
|
|
|
# There was no B API for the count or multiple enames, so I added one. |
5886
|
0
|
0
|
|
|
|
0
|
my @enames = ($PERL514 ? $hv->ENAMES : ()); |
5887
|
0
|
0
|
|
|
|
0
|
if (@enames > 1) { |
5888
|
0
|
0
|
|
|
|
0
|
warn "Saving for $name multiple enames: ", join(" ",@enames), "\n" if $debug{hv}; |
5889
|
0
|
|
|
|
|
0
|
my $name_count = $hv->name_count; |
5890
|
|
|
|
|
|
|
# If the stash name is empty xhv_name_count is negative, and names[0] should |
5891
|
|
|
|
|
|
|
# be already set. but we rather write it. |
5892
|
0
|
|
|
|
|
0
|
$init->no_split; |
5893
|
0
|
|
|
|
|
0
|
my $hv_max = $hv->MAX + 1; |
5894
|
|
|
|
|
|
|
# unshift @enames, $name if $name_count < 0; # stashpv has already set names[0] |
5895
|
0
|
|
|
|
|
0
|
$init->add( "if (!SvOOK($sym)) {", # hv_auxinit is not exported |
5896
|
|
|
|
|
|
|
" HE **a;", |
5897
|
|
|
|
|
|
|
"#ifdef PERL_USE_LARGE_HV_ALLOC", |
5898
|
|
|
|
|
|
|
sprintf( " Newxz(a, PERL_HV_ARRAY_ALLOC_BYTES(%d) + sizeof(struct xpvhv_aux), HE*);", |
5899
|
|
|
|
|
|
|
$hv_max), |
5900
|
|
|
|
|
|
|
"#else", |
5901
|
|
|
|
|
|
|
sprintf( " Newxz(a, %d + sizeof(struct xpvhv_aux), HE*);", $hv_max), |
5902
|
|
|
|
|
|
|
"#endif", |
5903
|
|
|
|
|
|
|
" SvOOK_on($sym);", |
5904
|
|
|
|
|
|
|
"}", |
5905
|
|
|
|
|
|
|
"{", |
5906
|
|
|
|
|
|
|
" struct xpvhv_aux *aux = HvAUX($sym);", |
5907
|
|
|
|
|
|
|
sprintf( " Newx(aux->xhv_name_u.xhvnameu_names, %d, HEK*);", scalar @enames), |
5908
|
|
|
|
|
|
|
sprintf( " aux->xhv_name_count = %d;", $name_count)); |
5909
|
0
|
|
|
|
|
0
|
my $i = 0; |
5910
|
0
|
|
|
|
|
0
|
while (@enames) { |
5911
|
0
|
|
|
|
|
0
|
my ($cstring, $cur, $utf8) = strlen_flags(shift @enames); |
5912
|
0
|
0
|
|
|
|
0
|
$init->add( |
5913
|
|
|
|
|
|
|
sprintf( " aux->xhv_name_u.xhvnameu_names[%u] = share_hek(%s, %d);", |
5914
|
|
|
|
|
|
|
$i++, $cstring, $utf8 ? -$cur : $cur)); |
5915
|
|
|
|
|
|
|
} |
5916
|
0
|
|
|
|
|
0
|
$init->add( "}" ); |
5917
|
0
|
|
|
|
|
0
|
$init->split; |
5918
|
|
|
|
|
|
|
} |
5919
|
|
|
|
|
|
|
|
5920
|
|
|
|
|
|
|
# issue 79, test 46: save stashes to check for packages. |
5921
|
|
|
|
|
|
|
# and via B::STASHGV we only save stashes for stashes. |
5922
|
|
|
|
|
|
|
# For efficiency we skip most stash symbols unless -fstash. |
5923
|
|
|
|
|
|
|
# However it should be now safe to save all stash symbols. |
5924
|
|
|
|
|
|
|
# $fullname !~ /::$/ or |
5925
|
0
|
0
|
|
|
|
0
|
if (!$B::C::stash) { # -fno-stash: do not save stashes |
5926
|
0
|
|
|
|
|
0
|
$magic = $hv->save_magic('%'.$name.'::'); #symtab magic set in PMOP #188 (#267) |
5927
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and is_using_mro() && mro::get_mro($name) eq 'c3') { |
|
|
|
0
|
|
|
|
|
5928
|
0
|
|
|
|
|
0
|
B::C::make_c3($name); |
5929
|
|
|
|
|
|
|
} |
5930
|
0
|
0
|
0
|
|
|
0
|
if ($magic and $magic =~ /c/) { |
5931
|
0
|
0
|
|
|
|
0
|
warn "defer AMT magic of $name\n" if $debug{mg}; |
5932
|
|
|
|
|
|
|
# defer AMT magic of XS loaded hashes. #305 Encode::XS with tiehash magic |
5933
|
|
|
|
|
|
|
# $init1->add(qq[$sym = gv_stashpvn($cname, $len, GV_ADDWARN|GV_ADDMULTI);]); |
5934
|
|
|
|
|
|
|
} |
5935
|
0
|
|
|
|
|
0
|
return $sym; |
5936
|
|
|
|
|
|
|
} |
5937
|
0
|
0
|
0
|
|
|
0
|
return $sym if skip_pkg($name) or $name eq 'main'; |
5938
|
0
|
|
|
|
|
0
|
$init->add( "SvREFCNT_inc($sym);" ); |
5939
|
0
|
0
|
|
|
|
0
|
warn "Saving stash keys for HV \"$name\" from \"$fullname\"\n" if $debug{hv}; |
5940
|
|
|
|
|
|
|
} |
5941
|
|
|
|
|
|
|
|
5942
|
|
|
|
|
|
|
# Ordinary HV or Stash |
5943
|
|
|
|
|
|
|
# KEYS = 0, inc. dynamically below with hv_store. TODO: HvSTATIC readonly tables, |
5944
|
|
|
|
|
|
|
# without hv_store |
5945
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
5946
|
0
|
|
|
|
|
0
|
my $flags = $hv->FLAGS & ~SVf_READONLY; |
5947
|
0
|
0
|
|
|
|
0
|
$flags &= ~SVf_PROTECT if $PERL522; |
5948
|
0
|
0
|
|
|
|
0
|
if ($PERL514) { # fill removed with 5.13.1 |
5949
|
0
|
|
|
|
|
0
|
$xpvhvsect->comment( "stash mgu max keys" ); |
5950
|
0
|
|
|
|
|
0
|
$xpvhvsect->add(sprintf( "Nullhv, {0}, %d, %d", |
5951
|
|
|
|
|
|
|
$hv->MAX, 0 )); |
5952
|
|
|
|
|
|
|
} else { |
5953
|
0
|
|
|
|
|
0
|
$xpvhvsect->comment( "GVSTASH fill max keys MG STASH" ); |
5954
|
0
|
|
|
|
|
0
|
$xpvhvsect->add(sprintf( "{0}, %d, %d, {%d}, {0}, Nullhv", |
5955
|
|
|
|
|
|
|
0, $hv->MAX, 0 )); |
5956
|
|
|
|
|
|
|
} |
5957
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvhv_list[%d], $u32fmt, 0x%x, {0}", |
5958
|
|
|
|
|
|
|
$xpvhvsect->index, $hv->REFCNT, $flags)); |
5959
|
|
|
|
|
|
|
# XXX failed at 16 (tied magic) for %main:: |
5960
|
0
|
0
|
0
|
|
|
0
|
if (!$is_stash and ($] >= 5.010 and $hv->FLAGS & SVf_OOK)) { |
|
|
|
0
|
|
|
|
|
5961
|
0
|
|
|
|
|
0
|
$sym = sprintf("&sv_list[%d]", $svsect->index); |
5962
|
0
|
|
|
|
|
0
|
my $hv_max = $hv->MAX + 1; |
5963
|
|
|
|
|
|
|
# riter required, new _aux struct at the end of the HvARRAY. allocate ARRAY also. |
5964
|
0
|
|
|
|
|
0
|
$init->add("{\tHE **a;", |
5965
|
|
|
|
|
|
|
"#ifdef PERL_USE_LARGE_HV_ALLOC", |
5966
|
|
|
|
|
|
|
sprintf("\tNewxz(a, PERL_HV_ARRAY_ALLOC_BYTES(%d) + sizeof(struct xpvhv_aux), HE*);", |
5967
|
|
|
|
|
|
|
$hv_max), |
5968
|
|
|
|
|
|
|
"#else", |
5969
|
|
|
|
|
|
|
sprintf("\tNewxz(a, %d + sizeof(struct xpvhv_aux), HE*);", $hv_max), |
5970
|
|
|
|
|
|
|
"#endif", |
5971
|
|
|
|
|
|
|
"\tHvARRAY($sym) = a;", |
5972
|
|
|
|
|
|
|
sprintf("\tHvRITER_set($sym, %d);", $hv->RITER),"}"); |
5973
|
|
|
|
|
|
|
} |
5974
|
|
|
|
|
|
|
} # !5.10 |
5975
|
|
|
|
|
|
|
else { |
5976
|
0
|
|
|
|
|
0
|
$xpvhvsect->comment( "array fill max keys nv mg stash riter eiter pmroot name" ); |
5977
|
0
|
|
|
|
|
0
|
$xpvhvsect->add(sprintf( "0, 0, %d, 0, 0.0, 0, Nullhv, %d, 0, 0, 0", |
5978
|
|
|
|
|
|
|
$hv->MAX, $hv->RITER)); |
5979
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf( "&xpvhv_list[%d], $u32fmt, 0x%x", |
5980
|
|
|
|
|
|
|
$xpvhvsect->index, $hv->REFCNT, $hv->FLAGS)); |
5981
|
|
|
|
|
|
|
} |
5982
|
0
|
0
|
|
|
|
0
|
$svsect->debug($fullname, $hv->flagspv) if $debug{flags}; |
5983
|
0
|
|
|
|
|
0
|
my $sv_list_index = $svsect->index; |
5984
|
|
|
|
|
|
|
warn sprintf( "saving HV %s &sv_list[%d] 0x%x MAX=%d KEYS=%d\n", |
5985
|
0
|
0
|
|
|
|
0
|
"%".$fullname, $sv_list_index, $$hv, $hv->MAX, $hv->KEYS ) if $debug{hv}; |
5986
|
|
|
|
|
|
|
# XXX B does not keep the UTF8 flag [RT 120535] #200 |
5987
|
|
|
|
|
|
|
# shared heks only since 5.10, our fixed C.xs variant |
5988
|
0
|
0
|
0
|
|
|
0
|
my @contents = ($PERL510 && $hv->can('ARRAY_utf8')) ? $hv->ARRAY_utf8 : $hv->ARRAY; |
5989
|
|
|
|
|
|
|
# protect against recursive self-reference |
5990
|
|
|
|
|
|
|
# i.e. with use Moose at stash Class::MOP::Class::Immutable::Trait |
5991
|
|
|
|
|
|
|
# value => rv => cv => ... => rv => same hash |
5992
|
0
|
0
|
|
|
|
0
|
$sym = savesym( $hv, "(HV*)&sv_list[$sv_list_index]" ) unless $is_stash; |
5993
|
0
|
0
|
0
|
|
|
0
|
push @B::C::static_free, $sym if $PERL518 and $hv->FLAGS & SVs_OBJECT; |
5994
|
|
|
|
|
|
|
|
5995
|
0
|
0
|
|
|
|
0
|
if (@contents) { |
|
|
0
|
|
|
|
|
|
5996
|
0
|
|
|
|
|
0
|
local $B::C::const_strings = $B::C::const_strings; |
5997
|
0
|
|
|
|
|
0
|
my ($i, $length); |
5998
|
0
|
|
|
|
|
0
|
$length = scalar(@contents); |
5999
|
0
|
|
|
|
|
0
|
for ( $i = 1 ; $i < @contents ; $i += 2 ) { |
6000
|
0
|
|
|
|
|
0
|
my $key = $contents[$i - 1]; # string only |
6001
|
0
|
|
|
|
|
0
|
my $sv = $contents[$i]; |
6002
|
|
|
|
|
|
|
warn sprintf("HV recursion? with $fullname\{$key\} -> %s\n", $sv->RV) |
6003
|
|
|
|
|
|
|
if ref($sv) eq 'B::RV' |
6004
|
|
|
|
|
|
|
#and $sv->RV->isa('B::CV') |
6005
|
|
|
|
|
|
|
and defined objsym($sv) |
6006
|
0
|
0
|
0
|
|
|
0
|
and $debug{hv}; |
|
|
|
0
|
|
|
|
|
6007
|
0
|
0
|
|
|
|
0
|
if ($is_stash) { |
6008
|
0
|
0
|
0
|
|
|
0
|
if (ref($sv) eq "B::GV" and $sv->NAME =~ /::$/) { |
6009
|
0
|
|
|
|
|
0
|
$sv = bless $sv, "B::STASHGV"; # do not expand stash GV's only other stashes |
6010
|
0
|
0
|
|
|
|
0
|
warn "saving STASH $fullname".'{'.$key."}\n" if $debug{hv}; |
6011
|
0
|
|
|
|
|
0
|
$contents[$i] = $sv->save($fullname.'{'.$key.'}'); |
6012
|
|
|
|
|
|
|
} else { |
6013
|
0
|
0
|
|
|
|
0
|
warn "skip STASH symbol *",$fullname.$key,"\n" if $debug{hv}; |
6014
|
0
|
|
|
|
|
0
|
$contents[$i] = undef; |
6015
|
0
|
|
|
|
|
0
|
$length -= 2; |
6016
|
|
|
|
|
|
|
# warn "(length=$length)\n" if $debug{hv}; |
6017
|
|
|
|
|
|
|
} |
6018
|
|
|
|
|
|
|
} else { |
6019
|
0
|
0
|
|
|
|
0
|
warn "saving HV \$".$fullname.'{'.$key."} $sv\n" if $debug{hv}; |
6020
|
0
|
|
|
|
|
0
|
$contents[$i] = $sv->save($fullname.'{'.$key.'}'); |
6021
|
|
|
|
|
|
|
#if ($key eq "" and $] >= 5.010) { |
6022
|
|
|
|
|
|
|
# warn " turn off HvSHAREKEYS with empty keysv\n" if $debug{hv}; |
6023
|
|
|
|
|
|
|
# $init->add("HvSHAREKEYS_off(&sv_list[$sv_list_index]);"); |
6024
|
|
|
|
|
|
|
#} |
6025
|
|
|
|
|
|
|
} |
6026
|
|
|
|
|
|
|
} |
6027
|
0
|
0
|
|
|
|
0
|
if ($length) { # there may be skipped STASH symbols |
6028
|
0
|
|
|
|
|
0
|
$init->no_split; |
6029
|
0
|
0
|
|
|
|
0
|
$init->add( "{", |
6030
|
|
|
|
|
|
|
sprintf("\tHV *hv = %s%s;", $sym=~/^hv|\(HV/ ? '' : '(HV*)', $sym )); |
6031
|
0
|
|
|
|
|
0
|
while (@contents) { |
6032
|
0
|
|
|
|
|
0
|
my ( $key, $value ) = splice( @contents, 0, 2 ); |
6033
|
0
|
0
|
|
|
|
0
|
if ($value) { |
6034
|
0
|
0
|
0
|
|
|
0
|
$value = "(SV*)$value" if $value !~ /^&sv_list/ or ($PERL510 and $] < 5.012); |
|
|
|
0
|
|
|
|
|
6035
|
0
|
|
|
|
|
0
|
my ($cstring, $cur, $utf8) = strlen_flags($key); |
6036
|
|
|
|
|
|
|
# issue 272: if SvIsCOW(sv) && SvLEN(sv) == 0 => sharedhek (key == "") |
6037
|
|
|
|
|
|
|
# >= 5.10: SvSHARED_HASH: PV offset to hek_hash |
6038
|
0
|
0
|
|
|
|
0
|
$cur = -$cur if $utf8; |
6039
|
0
|
|
|
|
|
0
|
$init->add(sprintf( "\thv_store(hv, %s, %d, %s, 0);", |
6040
|
|
|
|
|
|
|
$cstring, $cur, $value )); # !! randomized hash keys |
6041
|
0
|
0
|
|
|
|
0
|
warn sprintf( " HV key \"%s\" = %s\n", $key, $value) if $debug{hv}; |
6042
|
0
|
0
|
0
|
|
|
0
|
if (!$swash_ToCf and $fullname =~ /^utf8::SWASHNEW/ |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
6043
|
|
|
|
|
|
|
and $cstring eq '"utf8\034unicore/To/Cf.pl\0340"' and $cur == 23) |
6044
|
|
|
|
|
|
|
{ |
6045
|
0
|
|
|
|
|
0
|
$swash_ToCf = $value; |
6046
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Found PL_utf8_tofold ToCf swash $value\n") if $verbose; |
6047
|
|
|
|
|
|
|
} |
6048
|
|
|
|
|
|
|
} |
6049
|
|
|
|
|
|
|
} |
6050
|
0
|
|
|
|
|
0
|
$init->add("}"); |
6051
|
0
|
|
|
|
|
0
|
$init->split; |
6052
|
0
|
0
|
|
|
|
0
|
$init->add( sprintf("HvTOTALKEYS(%s) = %d;", $sym, $length / 2)) if !$PERL56; |
6053
|
|
|
|
|
|
|
} |
6054
|
|
|
|
|
|
|
} elsif ($PERL514) { # empty contents still needs to set keys=0 |
6055
|
|
|
|
|
|
|
# test 36, 140 |
6056
|
0
|
|
|
|
|
0
|
$init->add( "HvTOTALKEYS($sym) = 0;"); |
6057
|
|
|
|
|
|
|
} |
6058
|
0
|
|
|
|
|
0
|
$magic = $hv->save_magic($fullname); |
6059
|
0
|
0
|
|
|
|
0
|
$init->add( "SvREADONLY_on($sym);") if $hv->FLAGS & SVf_READONLY; |
6060
|
0
|
0
|
|
|
|
0
|
if ($magic =~ /c/) { |
6061
|
|
|
|
|
|
|
# defer AMT magic of XS loaded stashes |
6062
|
0
|
|
|
|
|
0
|
my ($cname, $len, $utf8) = strlen_flags($name); |
6063
|
0
|
|
|
|
|
0
|
$init2->add(qq[$sym = gv_stashpvn($cname, $len, GV_ADDWARN|GV_ADDMULTI|$utf8);]); |
6064
|
|
|
|
|
|
|
} |
6065
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and $name and is_using_mro() and mro::get_mro($name) eq 'c3') { |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
6066
|
0
|
|
|
|
|
0
|
B::C::make_c3($name); |
6067
|
|
|
|
|
|
|
} |
6068
|
0
|
|
|
|
|
0
|
return $sym; |
6069
|
|
|
|
|
|
|
} |
6070
|
|
|
|
|
|
|
|
6071
|
|
|
|
|
|
|
sub B::IO::save_data { |
6072
|
0
|
|
|
0
|
|
0
|
my ( $io, $sym, $globname, @data ) = @_; |
6073
|
0
|
|
|
|
|
0
|
my $data = join '', @data; |
6074
|
|
|
|
|
|
|
# XXX using $DATA might clobber it! |
6075
|
0
|
|
|
|
|
0
|
my $ref = svref_2object( \\$data )->save; |
6076
|
0
|
0
|
|
|
|
0
|
$init->add("/* save $globname in RV ($ref) */") if $verbose; |
6077
|
0
|
|
|
|
|
0
|
$init->add( "GvSVn( $sym ) = (SV*)$ref;"); |
6078
|
|
|
|
|
|
|
|
6079
|
0
|
0
|
|
|
|
0
|
if ($PERL56) { |
6080
|
|
|
|
|
|
|
# Pseudo FileHandle |
6081
|
0
|
|
|
|
|
0
|
$init2->add_eval( sprintf 'open(%s, \'<\', $%s);', $globname, $globname ); |
6082
|
|
|
|
|
|
|
} else { # force inclusion of PerlIO::scalar as it was loaded in BEGIN. |
6083
|
0
|
|
|
|
|
0
|
$init2->add_eval( sprintf 'open(%s, \'<:scalar\', $%s);', $globname, $globname ); |
6084
|
|
|
|
|
|
|
# => eval_pv("open(main::DATA, '<:scalar', $main::DATA);",1); DATA being a ref to $data |
6085
|
0
|
|
|
|
|
0
|
$init->pre_destruct( sprintf 'eval_pv("close %s;", 1);', $globname ); |
6086
|
0
|
|
|
|
|
0
|
$use_xsloader = 1; # layers are not detected as XSUB CV, so force it |
6087
|
0
|
0
|
|
|
|
0
|
require PerlIO unless $savINC{'PerlIO.pm'}; |
6088
|
0
|
0
|
|
|
|
0
|
require PerlIO::scalar unless $savINC{'PerlIO/scalar.pm'}; |
6089
|
0
|
|
|
|
|
0
|
mark_package("PerlIO", 1); |
6090
|
0
|
|
|
|
|
0
|
$curINC{'PerlIO.pm'} = $INC{'PerlIO.pm'}; # as it was loaded from BEGIN |
6091
|
0
|
|
|
|
|
0
|
mark_package("PerlIO::scalar", 1); |
6092
|
0
|
|
|
|
|
0
|
$curINC{'PerlIO/scalar.pm'} = $INC{'PerlIO/scalar.pm'}; |
6093
|
0
|
|
|
|
|
0
|
$xsub{'PerlIO::scalar'} = 'Dynamic-'.$INC{'PerlIO/scalar.pm'}; # force dl_init boot |
6094
|
|
|
|
|
|
|
} |
6095
|
|
|
|
|
|
|
} |
6096
|
|
|
|
|
|
|
|
6097
|
|
|
|
|
|
|
sub B::IO::save { |
6098
|
0
|
|
|
0
|
|
0
|
my ($io, $fullname, $is_DATA) = @_; |
6099
|
0
|
|
|
|
|
0
|
my $sym = objsym($io); |
6100
|
0
|
0
|
|
|
|
0
|
return $sym if defined $sym; |
6101
|
0
|
|
|
|
|
0
|
my $pv = $io->PV; |
6102
|
0
|
0
|
|
|
|
0
|
$pv = '' unless defined $pv; |
6103
|
0
|
|
|
|
|
0
|
my ( $pvsym, $len, $cur ); |
6104
|
0
|
0
|
|
|
|
0
|
if ($pv) { |
6105
|
0
|
|
|
|
|
0
|
$pvsym = savepv($pv); |
6106
|
0
|
|
|
|
|
0
|
$cur = $io->CUR; |
6107
|
|
|
|
|
|
|
} else { |
6108
|
0
|
|
|
|
|
0
|
$pvsym = 'NULL'; |
6109
|
0
|
|
|
|
|
0
|
$cur = 0; |
6110
|
|
|
|
|
|
|
} |
6111
|
0
|
0
|
|
|
|
0
|
if ($cur) { |
6112
|
0
|
|
|
|
|
0
|
$len = $cur + 1; |
6113
|
0
|
0
|
0
|
|
|
0
|
$len++ if IsCOW($io) and !$B::C::cow; |
6114
|
|
|
|
|
|
|
} else { |
6115
|
0
|
|
|
|
|
0
|
$len = 0; |
6116
|
|
|
|
|
|
|
} |
6117
|
|
|
|
|
|
|
warn sprintf( "IO $fullname sv_list[%d] 0x%x (%s) = '%s'\n", $svsect->index+1, $$io, $io->SvTYPE, $pv ) |
6118
|
0
|
0
|
0
|
|
|
0
|
if $debug{sv} and $] > 5.008; # no method "SvTYPE" via package "B::IO" |
6119
|
0
|
0
|
|
|
|
0
|
if ($PERL514) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
6120
|
|
|
|
|
|
|
# IFP in sv.sv_u.svu_fp |
6121
|
0
|
|
|
|
|
0
|
$xpviosect->comment("STASH, xmg_u, cur, len, xiv_u, xio_ofp, xio_dirpu, page, page_len, ..., type, flags"); |
6122
|
0
|
|
|
|
|
0
|
my $tmpl = "Nullhv, /*STASH later*/\n\t{0}, /*MAGIC later*/\n\t%u, /*cur*/\n\t%u, /*len*/\n\t{%d}, /*LINES*/\n\t0, /*OFP later*/\n\t{0}, /*dirp_u later*/\n\t%d, /*PAGE*/\n\t%d, /*PAGE_LEN*/\n\t%d, /*LINES_LEFT*/\n\t%s, /*TOP_NAME*/\n\tNullgv, /*top_gv later*/\n\t%s, /*fmt_name*/\n\tNullgv, /*fmt_gv later*/\n\t%s, /*bottom_name*/\n\tNullgv, /*bottom_gv later*/\n\t%s, /*type*/\n\t0x%x /*flags*/"; |
6123
|
0
|
0
|
|
|
|
0
|
$tmpl =~ s{ /\*.+?\*/\n\t}{}g unless $verbose; |
6124
|
0
|
0
|
|
|
|
0
|
$tmpl =~ s{ /\*flags\*/$}{} unless $verbose; |
6125
|
0
|
|
|
|
|
0
|
$xpviosect->add( |
6126
|
|
|
|
|
|
|
sprintf($tmpl, |
6127
|
|
|
|
|
|
|
$cur, $len, |
6128
|
|
|
|
|
|
|
$io->LINES, # moved to IVX with 5.11.1 |
6129
|
|
|
|
|
|
|
$io->PAGE, $io->PAGE_LEN, |
6130
|
|
|
|
|
|
|
$io->LINES_LEFT, "NULL", |
6131
|
|
|
|
|
|
|
"NULL", "NULL", |
6132
|
|
|
|
|
|
|
cchar( $io->IoTYPE ), $io->IoFLAGS |
6133
|
|
|
|
|
|
|
) |
6134
|
|
|
|
|
|
|
); |
6135
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}", |
6136
|
|
|
|
|
|
|
$xpviosect->index, $io->REFCNT, $io->FLAGS, |
6137
|
|
|
|
|
|
|
$B::C::pv_copy_on_grow ? $pvsym : 0)); |
6138
|
|
|
|
|
|
|
} |
6139
|
|
|
|
|
|
|
elsif ($] > 5.011000) { |
6140
|
0
|
|
|
|
|
0
|
$xpviosect->comment("xnv_u, cur, len, lines, xmg_u, xmg_stash, xio_ifp, xio_ofp, xio_dirpu, ..., type, flags"); |
6141
|
0
|
|
|
|
|
0
|
my $tmpl = "{0}, /*xnv_u*/\n\t%u, /*cur*/\n\t%u, /*len*/\n\t{%d}, /*LINES*/\n\t{0}, /*MAGIC later*/\n\t(HV*)NULL, /*STASH later*/\n\t0, /*IFP later*/\n\t0, /*OFP later*/\n\t{0}, /*dirp_u later*/\n\t%d, /*PAGE*/\n\t%d, /*PAGE_LEN*/\n\t%d, /*LINES_LEFT*/\n\t%s, /*TOP_NAME*/\n\tNullgv, /*top_gv later*/\n\t%s, /*fmt_name*/\n\tNullgv, /*fmt_gv later*/\n\t%s, /*bottom_name*/\n\tNullgv, /*bottom_gv later*/\n\t%s, /*type*/\n\t0x%x /*flags*/"; |
6142
|
0
|
0
|
|
|
|
0
|
$tmpl =~ s{ /\*.+?\*/\n\t}{}g unless $verbose; |
6143
|
0
|
0
|
|
|
|
0
|
$tmpl =~ s{ /\*flags\*/$}{} unless $verbose; |
6144
|
0
|
|
|
|
|
0
|
$xpviosect->add( |
6145
|
|
|
|
|
|
|
sprintf($tmpl, |
6146
|
|
|
|
|
|
|
$cur, $len, |
6147
|
|
|
|
|
|
|
$io->LINES, # moved to IVX with 5.11.1 |
6148
|
|
|
|
|
|
|
$io->PAGE, $io->PAGE_LEN, |
6149
|
|
|
|
|
|
|
$io->LINES_LEFT, "NULL", |
6150
|
|
|
|
|
|
|
"NULL", "NULL", |
6151
|
|
|
|
|
|
|
cchar( $io->IoTYPE ), $io->IoFLAGS |
6152
|
|
|
|
|
|
|
) |
6153
|
|
|
|
|
|
|
); |
6154
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}", |
6155
|
|
|
|
|
|
|
$xpviosect->index, $io->REFCNT, $io->FLAGS, |
6156
|
|
|
|
|
|
|
$B::C::pv_copy_on_grow ? $pvsym : 0)); |
6157
|
|
|
|
|
|
|
} |
6158
|
|
|
|
|
|
|
elsif ($PERL510) { |
6159
|
0
|
|
|
|
|
0
|
$xpviosect->comment("xnv_u, cur, len, xiv_u, xmg_u, xmg_stash, xio_ifp, xio_ofp, xio_dirpu, lines, ..., type, flags"); |
6160
|
0
|
|
|
|
|
0
|
my $tmpl = "{0}, /*xnv_u*/\n\t%u, /*cur*/\n\t%u, /*len*/\n\t{%ld}, /*IVX*/\n\t{0}, /*MAGIC later*/\n\t(HV*)NULL, /*STASH later*/\n\t0, /*IFP later*/\n\t0, /*OFP later*/\n\t{0}, /*dirp_u later*/\n\t%d, /*LINES*/\n\t%d, /*PAGE*/\n\t%d, /*PAGE_LEN*/\n\t%d, /*LINES_LEFT*/\n\t%s, /*TOP_NAME*/\n\tNullgv, /*top_gv later*/\n\t%s, /*fmt_name*/\n\tNullgv, /*fmt_gv later*/\n\t%s, /*bottom_name*/\n\tNullgv, /*bottom_gv later*/\n\t%s, /*type*/\n\t0x%x /*flags*/"; |
6161
|
0
|
0
|
|
|
|
0
|
$tmpl =~ s{ /\*[^\*]+?\*/\n\t}{}g unless $verbose; |
6162
|
0
|
0
|
|
|
|
0
|
$tmpl =~ s{ /\*flags\*/$}{} unless $verbose; |
6163
|
0
|
|
|
|
|
0
|
$xpviosect->add( |
6164
|
|
|
|
|
|
|
sprintf($tmpl, |
6165
|
|
|
|
|
|
|
$cur, $len, |
6166
|
|
|
|
|
|
|
$io->IVX, |
6167
|
|
|
|
|
|
|
$io->LINES, |
6168
|
|
|
|
|
|
|
$io->PAGE, $io->PAGE_LEN, |
6169
|
|
|
|
|
|
|
$io->LINES_LEFT, "NULL", |
6170
|
|
|
|
|
|
|
"NULL", "NULL", |
6171
|
|
|
|
|
|
|
cchar( $io->IoTYPE ), $io->IoFLAGS |
6172
|
|
|
|
|
|
|
) |
6173
|
|
|
|
|
|
|
); |
6174
|
0
|
0
|
|
|
|
0
|
$svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x, {%s}", |
6175
|
|
|
|
|
|
|
$xpviosect->index, $io->REFCNT, $io->FLAGS, |
6176
|
|
|
|
|
|
|
$B::C::pv_copy_on_grow ? $pvsym : 0)); |
6177
|
|
|
|
|
|
|
} |
6178
|
|
|
|
|
|
|
else { # 5.6 and 5.8 |
6179
|
0
|
|
|
|
|
0
|
$xpviosect->comment("xpv_pv, cur, len, iv, nv, magic, stash, xio_ifp, xio_ofp, xio_dirpu, ..., subprocess, type, flags"); |
6180
|
0
|
|
|
|
|
0
|
$xpviosect->add( |
6181
|
|
|
|
|
|
|
sprintf("%s, %u, %u, %ld, %s, 0, 0, 0, 0, {0}, %d, %d, %d, %d, %s, Nullgv, %s, Nullgv, %s, Nullgv, %d, %s, 0x%x", |
6182
|
|
|
|
|
|
|
$pvsym, $cur, $len, |
6183
|
|
|
|
|
|
|
$io->IVX, $io->NVX, |
6184
|
|
|
|
|
|
|
$io->LINES, $io->PAGE, |
6185
|
|
|
|
|
|
|
$io->PAGE_LEN, $io->LINES_LEFT, |
6186
|
|
|
|
|
|
|
"NULL", "NULL", |
6187
|
|
|
|
|
|
|
"NULL", $io->SUBPROCESS, |
6188
|
|
|
|
|
|
|
cchar( $io->IoTYPE ), $io->IoFLAGS |
6189
|
|
|
|
|
|
|
) |
6190
|
|
|
|
|
|
|
); |
6191
|
0
|
|
|
|
|
0
|
$svsect->add(sprintf("&xpvio_list[%d], $u32fmt, 0x%x", |
6192
|
|
|
|
|
|
|
$xpviosect->index, $io->REFCNT, $io->FLAGS)); |
6193
|
|
|
|
|
|
|
} |
6194
|
0
|
0
|
|
|
|
0
|
$svsect->debug($fullname, $io->flagspv) if $debug{flags}; |
6195
|
0
|
|
|
|
|
0
|
$sym = savesym( $io, sprintf( "(IO*)&sv_list[%d]", $svsect->index ) ); |
6196
|
|
|
|
|
|
|
|
6197
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and !$B::C::pv_copy_on_grow and $cur) { |
|
|
|
0
|
|
|
|
|
6198
|
0
|
|
|
|
|
0
|
$init->add(sprintf("SvPVX(sv_list[%d]) = %s;", $svsect->index, $pvsym)); |
6199
|
|
|
|
|
|
|
} |
6200
|
0
|
|
|
|
|
0
|
my ( $field ); |
6201
|
0
|
|
|
|
|
0
|
foreach $field (qw(TOP_GV FMT_GV BOTTOM_GV)) { |
6202
|
0
|
|
|
|
|
0
|
my $fsym = $io->$field(); |
6203
|
0
|
0
|
|
|
|
0
|
if ($$fsym) { |
6204
|
0
|
|
|
|
|
0
|
$init->add( sprintf( "Io%s(%s) = (GV*)s\\_%x;", $field, $sym, $$fsym ) ); |
6205
|
0
|
|
|
|
|
0
|
$fsym->save; |
6206
|
|
|
|
|
|
|
} |
6207
|
|
|
|
|
|
|
} |
6208
|
0
|
|
|
|
|
0
|
foreach $field (qw(TOP_NAME FMT_NAME BOTTOM_NAME)) { |
6209
|
0
|
|
|
|
|
0
|
my $fsym = $io->$field; |
6210
|
0
|
0
|
|
|
|
0
|
$init->add(sprintf("Io%s(%s) = savepvn(%s, %u);", $field, $sym, |
6211
|
|
|
|
|
|
|
cstring( $fsym ), length $fsym)) if $fsym; |
6212
|
|
|
|
|
|
|
} |
6213
|
0
|
|
|
|
|
0
|
$io->save_magic($fullname); # This handle the stash also (we need to inc the refcnt) |
6214
|
0
|
0
|
0
|
|
|
0
|
if (!$PERL56 and !$is_DATA) { # PerlIO |
6215
|
|
|
|
|
|
|
# deal with $x = *STDIN/STDOUT/STDERR{IO} and aliases |
6216
|
0
|
|
|
|
|
0
|
my $perlio_func; |
6217
|
|
|
|
|
|
|
# Note: all single-direction fp use IFP, just bi-directional pipes and |
6218
|
|
|
|
|
|
|
# sockets use OFP also. But we need to set both, pp_print checks OFP. |
6219
|
0
|
|
|
|
|
0
|
my $o = $io->object_2svref(); |
6220
|
0
|
|
|
|
|
0
|
eval "require ".ref($o).";"; |
6221
|
0
|
|
|
|
|
0
|
my $fd = $o->fileno(); |
6222
|
|
|
|
|
|
|
# use IO::Handle (); |
6223
|
|
|
|
|
|
|
# my $fd = IO::Handle::fileno($o); |
6224
|
0
|
|
|
|
|
0
|
my $i = 0; |
6225
|
0
|
|
|
|
|
0
|
foreach (qw(stdin stdout stderr)) { |
6226
|
0
|
0
|
0
|
|
|
0
|
if ($io->IsSTD($_) or (defined($fd) and $fd == -$i)) { |
|
|
|
0
|
|
|
|
|
6227
|
0
|
|
|
|
|
0
|
$perlio_func = $_; |
6228
|
|
|
|
|
|
|
} |
6229
|
0
|
|
|
|
|
0
|
$i++; |
6230
|
|
|
|
|
|
|
} |
6231
|
0
|
0
|
|
|
|
0
|
if ($perlio_func) { |
6232
|
0
|
|
|
|
|
0
|
$init->add("IoIFP(${sym}) = IoOFP(${sym}) = PerlIO_${perlio_func}();"); |
6233
|
|
|
|
|
|
|
#if ($fd < 0) { # fd=-1 signals an error |
6234
|
|
|
|
|
|
|
# XXX print may fail at flush == EOF, wrong init-time? |
6235
|
|
|
|
|
|
|
#} |
6236
|
|
|
|
|
|
|
} else { |
6237
|
0
|
|
|
|
|
0
|
my $iotype = $io->IoTYPE; |
6238
|
0
|
|
|
|
|
0
|
my $ioflags = $io->IoFLAGS; |
6239
|
|
|
|
|
|
|
# If an IO handle was opened at BEGIN, we try to re-init it, based on fd and IoTYPE. |
6240
|
|
|
|
|
|
|
# IOTYPE: |
6241
|
|
|
|
|
|
|
# - STDIN/OUT HANDLE IoIOFP alias |
6242
|
|
|
|
|
|
|
# I STDIN/OUT/ERR HANDLE IoIOFP alias |
6243
|
|
|
|
|
|
|
# < read-only HANDLE fdopen |
6244
|
|
|
|
|
|
|
# > write-only HANDLE if fd<3 or IGNORE warn and comment |
6245
|
|
|
|
|
|
|
# a append HANDLE -"- |
6246
|
|
|
|
|
|
|
# + read and write HANDLE fdopen |
6247
|
|
|
|
|
|
|
# s socket DIE |
6248
|
|
|
|
|
|
|
# | pipe DIE |
6249
|
|
|
|
|
|
|
# # NUMERIC HANDLE fdopen |
6250
|
|
|
|
|
|
|
# space closed IGNORE |
6251
|
|
|
|
|
|
|
# \0 ex/closed? IGNORE |
6252
|
0
|
0
|
0
|
|
|
0
|
if ($iotype eq "\c@" or $iotype eq " ") { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
6253
|
|
|
|
|
|
|
warn sprintf("Ignore closed IO Handle %s %s (%d)\n", |
6254
|
|
|
|
|
|
|
cstring($iotype), $fullname, $ioflags) |
6255
|
0
|
0
|
|
|
|
0
|
if $debug{gv}; |
6256
|
|
|
|
|
|
|
} |
6257
|
|
|
|
|
|
|
elsif ($iotype =~ /[a>]/) { # write-only |
6258
|
0
|
0
|
0
|
|
|
0
|
warn "Warning: Write BEGIN-block $fullname to FileHandle $iotype \&$fd\n" |
6259
|
|
|
|
|
|
|
if $fd >= 3 or $verbose; |
6260
|
0
|
0
|
|
|
|
0
|
my $mode = $iotype eq '>' ? 'w' : 'a'; |
6261
|
|
|
|
|
|
|
#$init->add( sprintf("IoIFP($sym) = IoOFP($sym) = PerlIO_openn(aTHX_ NULL,%s,%d,0,0,NULL,0,NULL);", |
6262
|
|
|
|
|
|
|
# cstring($mode), $fd)); |
6263
|
0
|
0
|
|
|
|
0
|
$init->add(sprintf( "%sIoIFP(%s) = IoOFP(%s) = PerlIO_fdopen(%d, %s);%s", |
|
|
0
|
|
|
|
|
|
6264
|
|
|
|
|
|
|
$fd<3?'':'/*', $sym, $sym, $fd, cstring($mode), $fd<3?'':'*/')); |
6265
|
|
|
|
|
|
|
} |
6266
|
|
|
|
|
|
|
elsif ($iotype =~ /[<#\+]/) { |
6267
|
|
|
|
|
|
|
# skips warning if it's one of our PerlIO::scalar __DATA__ handles |
6268
|
0
|
0
|
0
|
|
|
0
|
warn "Warning: Read BEGIN-block $fullname from FileHandle $iotype \&$fd\n" |
6269
|
|
|
|
|
|
|
if $fd >= 3 or $verbose; # need to setup it up before |
6270
|
0
|
|
|
|
|
0
|
$init->add("/* XXX WARNING: Read BEGIN-block $fullname from FileHandle */", |
6271
|
|
|
|
|
|
|
"IoIFP($sym) = IoOFP($sym) = PerlIO_fdopen($fd, \"r\");"); |
6272
|
0
|
|
|
|
|
0
|
my $tell; |
6273
|
0
|
0
|
0
|
|
|
0
|
if ($io->can("tell") and $tell = $io->tell()) { |
6274
|
0
|
|
|
|
|
0
|
$init->add("PerlIO_seek(IoIFP($sym), $tell, SEEK_SET);") |
6275
|
|
|
|
|
|
|
} |
6276
|
|
|
|
|
|
|
} else { |
6277
|
|
|
|
|
|
|
# XXX We should really die here |
6278
|
0
|
|
|
|
|
0
|
warn sprintf("ERROR: Unhandled BEGIN-block IO Handle %s\&%d (%d) from %s\n", |
6279
|
|
|
|
|
|
|
cstring($iotype), $fd, $ioflags, $fullname); |
6280
|
0
|
|
|
|
|
0
|
$init->add("/* XXX WARNING: Unhandled BEGIN-block IO Handle ", |
6281
|
|
|
|
|
|
|
"IoTYPE=$iotype SYMBOL=$fullname, IoFLAGS=$ioflags */", |
6282
|
|
|
|
|
|
|
"IoIFP($sym) = IoOFP($sym) = PerlIO_fdopen($fd, \"$iotype\");"); |
6283
|
|
|
|
|
|
|
} |
6284
|
|
|
|
|
|
|
} |
6285
|
|
|
|
|
|
|
} |
6286
|
|
|
|
|
|
|
|
6287
|
0
|
0
|
|
|
|
0
|
if ( $PERL518 ) { |
6288
|
0
|
|
|
|
|
0
|
my $stash = $io->SvSTASH; |
6289
|
0
|
0
|
0
|
|
|
0
|
if ($stash and $$stash) { |
6290
|
0
|
|
|
|
|
0
|
my $stsym = $stash->save("%".$stash->NAME); |
6291
|
0
|
|
|
|
|
0
|
$init->add( |
6292
|
|
|
|
|
|
|
sprintf( "SvREFCNT(%s) += 1;", $stsym ), |
6293
|
|
|
|
|
|
|
sprintf( "SvSTASH_set(%s, %s);", $sym, $stsym ) |
6294
|
|
|
|
|
|
|
); |
6295
|
|
|
|
|
|
|
warn sprintf( "done saving STASH %s %s for IO %s\n", $stash->NAME, $stsym, $sym ) |
6296
|
0
|
0
|
|
|
|
0
|
if $debug{gv}; |
6297
|
|
|
|
|
|
|
} |
6298
|
|
|
|
|
|
|
} |
6299
|
|
|
|
|
|
|
|
6300
|
0
|
|
|
|
|
0
|
return $sym; |
6301
|
|
|
|
|
|
|
} |
6302
|
|
|
|
|
|
|
|
6303
|
|
|
|
|
|
|
sub B::SV::save { |
6304
|
0
|
|
|
0
|
|
0
|
my $sv = shift; |
6305
|
|
|
|
|
|
|
|
6306
|
|
|
|
|
|
|
# This is where we catch an honest-to-goodness Nullsv (which gets |
6307
|
|
|
|
|
|
|
# blessed into B::SV explicitly) and any stray erroneous SVs. |
6308
|
0
|
0
|
|
|
|
0
|
return 0 unless $$sv; |
6309
|
0
|
|
|
|
|
0
|
warn sprintf( "cannot save that type of SV: %s (0x%x)\n", B::class($sv), $$sv ); |
6310
|
|
|
|
|
|
|
} |
6311
|
|
|
|
|
|
|
|
6312
|
|
|
|
|
|
|
sub output_all { |
6313
|
0
|
|
|
0
|
0
|
0
|
my $init_name = shift; |
6314
|
0
|
|
|
|
|
0
|
my $section; |
6315
|
0
|
0
|
|
|
|
0
|
return if $check; |
6316
|
|
|
|
|
|
|
|
6317
|
0
|
|
|
|
|
0
|
my @sections = |
6318
|
|
|
|
|
|
|
( |
6319
|
|
|
|
|
|
|
$copsect, $opsect, $unopsect, $binopsect, $logopsect, $condopsect, |
6320
|
|
|
|
|
|
|
$listopsect, $pmopsect, $svopsect, $padopsect, $pvopsect, $loopsect, |
6321
|
|
|
|
|
|
|
$methopsect, $unopauxsect, |
6322
|
|
|
|
|
|
|
$xpvsect, $xpvavsect, $xpvhvsect, $xpvcvsect, $padlistsect, |
6323
|
|
|
|
|
|
|
$padnlsect, $xpvivsect, $xpvuvsect, $xpvnvsect, $xpvmgsect, $xpvlvsect, |
6324
|
|
|
|
|
|
|
$xrvsect, $xpvbmsect, $xpviosect, $svsect, $padnamesect, |
6325
|
|
|
|
|
|
|
); |
6326
|
0
|
0
|
|
|
|
0
|
if ($PERL522) { |
6327
|
0
|
|
|
|
|
0
|
pop @sections; |
6328
|
0
|
|
|
|
|
0
|
for my $n (sort keys %padnamesect) { |
6329
|
0
|
|
|
|
|
0
|
push @sections, $padnamesect{$n}; |
6330
|
|
|
|
|
|
|
} |
6331
|
|
|
|
|
|
|
} |
6332
|
0
|
0
|
|
|
|
0
|
if ($CPERL52) { |
6333
|
0
|
|
|
|
|
0
|
for my $n (sort keys %avcowsect) { |
6334
|
0
|
|
|
|
|
0
|
push @sections, $avcowsect{$n}; |
6335
|
|
|
|
|
|
|
} |
6336
|
0
|
|
|
|
|
0
|
for my $n (sort keys %avcogsect) { |
6337
|
0
|
|
|
|
|
0
|
push @sections, $avcogsect{$n}; |
6338
|
|
|
|
|
|
|
} |
6339
|
|
|
|
|
|
|
} |
6340
|
0
|
0
|
0
|
|
|
0
|
printf "\t/* %s */", $symsect->comment if $symsect->comment and $verbose; |
6341
|
0
|
|
|
|
|
0
|
$symsect->output( \*STDOUT, "#define %s\n" ); |
6342
|
0
|
|
|
|
|
0
|
print "\n"; |
6343
|
0
|
|
|
|
|
0
|
output_declarations(); |
6344
|
|
|
|
|
|
|
# XXX add debug versions with ix=opindex if $debug{flags} |
6345
|
0
|
|
|
|
|
0
|
foreach $section (@sections) { |
6346
|
0
|
|
|
|
|
0
|
my $lines = $section->index + 1; |
6347
|
0
|
0
|
|
|
|
0
|
if ($lines) { |
6348
|
0
|
|
|
|
|
0
|
my $name = $section->name; |
6349
|
0
|
|
|
|
|
0
|
my $typename = $section->typename; |
6350
|
|
|
|
|
|
|
# static SV** arrays for AvSTATIC, HvSTATIC, ... |
6351
|
0
|
0
|
0
|
|
|
0
|
if ($typename eq 'SV*' and $name =~ /^(?:avco[gw])_(\d+)$/) { |
6352
|
0
|
|
|
|
|
0
|
my $n = $1; |
6353
|
0
|
0
|
|
|
|
0
|
$typename = 'const SV*' if $name =~ /^avcow_/; |
6354
|
0
|
|
|
|
|
0
|
print "Static $typename ${name}_list[$lines][$n];\n"; |
6355
|
|
|
|
|
|
|
} else { |
6356
|
0
|
|
|
|
|
0
|
print "Static $typename ${name}_list[$lines];\n"; |
6357
|
|
|
|
|
|
|
} |
6358
|
|
|
|
|
|
|
} |
6359
|
|
|
|
|
|
|
} |
6360
|
|
|
|
|
|
|
|
6361
|
|
|
|
|
|
|
# hack for when Perl accesses PVX of GVs |
6362
|
0
|
|
|
|
|
0
|
print 'Static const char emptystring[] = "\0";',"\n"; |
6363
|
|
|
|
|
|
|
# newXS for core XS needs a filename |
6364
|
0
|
|
|
|
|
0
|
print 'Static const char xsfile[] = "universal.c";',"\n"; |
6365
|
0
|
0
|
|
|
|
0
|
if ($MULTI) { |
6366
|
0
|
|
|
|
|
0
|
print "#define ptr_undef 0\n"; |
6367
|
|
|
|
|
|
|
} else { |
6368
|
0
|
0
|
|
|
|
0
|
if ($] > 5.01903) { |
6369
|
0
|
|
|
|
|
0
|
print "#define ptr_undef NULL\n"; |
6370
|
|
|
|
|
|
|
} else { |
6371
|
0
|
|
|
|
|
0
|
print "#define ptr_undef &PL_sv_undef\n"; |
6372
|
|
|
|
|
|
|
} |
6373
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { # XXX const sv SIGSEGV |
6374
|
0
|
|
|
|
|
0
|
print "#undef CopFILE_set\n"; |
6375
|
0
|
|
|
|
|
0
|
print "#define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv))\n"; |
6376
|
|
|
|
|
|
|
} |
6377
|
|
|
|
|
|
|
} |
6378
|
|
|
|
|
|
|
# print "#define MyPVX(sv) ".($] < 5.010 ? "SvPVX(sv)" : "((sv)->sv_u.svu_pv)")."\n"; |
6379
|
0
|
0
|
|
|
|
0
|
if ($] < 5.008008 ) { |
6380
|
0
|
|
|
|
|
0
|
print <<'EOT'; |
6381
|
|
|
|
|
|
|
#ifndef SvSTASH_set |
6382
|
|
|
|
|
|
|
# define SvSTASH_set(sv,hv) SvSTASH((sv)) = (hv) |
6383
|
|
|
|
|
|
|
#endif |
6384
|
|
|
|
|
|
|
#ifndef Newxz |
6385
|
|
|
|
|
|
|
# define Newxz(v,n,t) Newz(0,v,n,t) |
6386
|
|
|
|
|
|
|
#endif |
6387
|
|
|
|
|
|
|
EOT |
6388
|
|
|
|
|
|
|
} |
6389
|
0
|
0
|
|
|
|
0
|
if ($] < 5.008009 ) { |
6390
|
0
|
|
|
|
|
0
|
print <<'EOT'; |
6391
|
|
|
|
|
|
|
#ifndef SvREFCNT_inc_simple_NN |
6392
|
|
|
|
|
|
|
# define SvREFCNT_inc_simple_NN(sv) (++SvREFCNT(sv), (SV*)(sv)) |
6393
|
|
|
|
|
|
|
#endif |
6394
|
|
|
|
|
|
|
#ifndef STR_WITH_LEN |
6395
|
|
|
|
|
|
|
#define STR_WITH_LEN(s) ("" s ""), (sizeof(s)-1) |
6396
|
|
|
|
|
|
|
#endif |
6397
|
|
|
|
|
|
|
EOT |
6398
|
|
|
|
|
|
|
} |
6399
|
0
|
0
|
|
|
|
0
|
if ($] < 5.013007 ) { |
6400
|
0
|
|
|
|
|
0
|
print <<'EOT'; |
6401
|
|
|
|
|
|
|
#ifndef CvSTASH_set |
6402
|
|
|
|
|
|
|
# define CvSTASH_set(cv,hv) CvSTASH((cv)) = (hv) |
6403
|
|
|
|
|
|
|
#endif |
6404
|
|
|
|
|
|
|
EOT |
6405
|
|
|
|
|
|
|
} |
6406
|
0
|
0
|
|
|
|
0
|
if ($] < 5.013010 ) { # added with c43ae56ff9cd before 5.13.10 at 2011-01-21 |
6407
|
0
|
|
|
|
|
0
|
print <<'EOT'; |
6408
|
|
|
|
|
|
|
#ifndef GvCV_set |
6409
|
|
|
|
|
|
|
# define GvCV_set(gv,cv) (GvCV(gv) = (cv)) |
6410
|
|
|
|
|
|
|
#endif |
6411
|
|
|
|
|
|
|
#ifndef GvGP_set |
6412
|
|
|
|
|
|
|
# define GvGP_set(gv,gp) (GvGP(gv) = (gp)) |
6413
|
|
|
|
|
|
|
#endif |
6414
|
|
|
|
|
|
|
EOT |
6415
|
|
|
|
|
|
|
} |
6416
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.021005 and $] < 5.023) { |
6417
|
0
|
|
|
|
|
0
|
print <<'EOT'; |
6418
|
|
|
|
|
|
|
/* PadlistNAMES broken as lvalue with v5.21.6-197-g0f94cb1, |
6419
|
|
|
|
|
|
|
fixed with 5.22.1 and 5.23.0 */ |
6420
|
|
|
|
|
|
|
#if (PERL_VERSION == 22) || ( PERL_VERSION == 21 && PERL_SUBVERSION > 5) |
6421
|
|
|
|
|
|
|
# undef PadlistNAMES |
6422
|
|
|
|
|
|
|
# define PadlistNAMES(pl) *((PADNAMELIST **)PadlistARRAY(pl)) |
6423
|
|
|
|
|
|
|
#endif |
6424
|
|
|
|
|
|
|
EOT |
6425
|
|
|
|
|
|
|
} |
6426
|
|
|
|
|
|
|
# handy accessors only in cperl for now: |
6427
|
0
|
|
|
|
|
0
|
print <<'EOT'; |
6428
|
|
|
|
|
|
|
#ifndef get_svs |
6429
|
|
|
|
|
|
|
# define get_svs(str, flags) get_sv((str), (flags)) |
6430
|
|
|
|
|
|
|
# define get_avs(str, flags) get_av((str), (flags)) |
6431
|
|
|
|
|
|
|
# define get_hvs(str, flags) get_hv((str), (flags)) |
6432
|
|
|
|
|
|
|
#endif |
6433
|
|
|
|
|
|
|
EOT |
6434
|
0
|
0
|
0
|
|
|
0
|
if (%init2_remap and !$HAVE_DLFCN_DLOPEN) { |
6435
|
0
|
|
|
|
|
0
|
print <<'EOT'; |
6436
|
|
|
|
|
|
|
XS(XS_DynaLoader_dl_load_file); |
6437
|
|
|
|
|
|
|
XS(XS_DynaLoader_dl_find_symbol); |
6438
|
|
|
|
|
|
|
EOT |
6439
|
|
|
|
|
|
|
} |
6440
|
0
|
0
|
0
|
|
|
0
|
printf "\t/* %s */\n", $decl->comment if $decl->comment and $verbose; |
6441
|
0
|
|
|
|
|
0
|
$decl->output( \*STDOUT, "%s\n" ); |
6442
|
0
|
|
|
|
|
0
|
print "\n"; |
6443
|
|
|
|
|
|
|
|
6444
|
0
|
|
|
|
|
0
|
foreach $section (@sections) { |
6445
|
0
|
|
|
|
|
0
|
my $lines = $section->index + 1; |
6446
|
0
|
0
|
|
|
|
0
|
if ($lines) { |
6447
|
0
|
|
|
|
|
0
|
my $name = $section->name; |
6448
|
0
|
|
|
|
|
0
|
my $typename = $section->typename; |
6449
|
|
|
|
|
|
|
# static SV** arrays for AvSTATIC, HvSTATIC, ... |
6450
|
0
|
0
|
0
|
|
|
0
|
if ($typename eq 'SV*' and $name =~ /^(?:avco[wg])_(\d+)$/) { |
6451
|
0
|
|
|
|
|
0
|
my $n = $1; |
6452
|
0
|
0
|
|
|
|
0
|
$typename = 'const SV*' if $name =~ /^avcow_/; |
6453
|
0
|
|
|
|
|
0
|
printf "Static %s %s_list[%u][%u] = {\n", $typename, $name, $lines, $n; |
6454
|
|
|
|
|
|
|
} else { |
6455
|
0
|
|
|
|
|
0
|
printf "Static %s %s_list[%u] = {\n", $typename, $name, $lines; |
6456
|
|
|
|
|
|
|
} |
6457
|
0
|
0
|
0
|
|
|
0
|
printf "\t/* %s */\n", $section->comment |
6458
|
|
|
|
|
|
|
if $section->comment and $verbose; |
6459
|
0
|
|
|
|
|
0
|
$section->output( \*STDOUT, "\t{ %s }, /* %s_list[%d] %s */%s\n" ); |
6460
|
0
|
|
|
|
|
0
|
print "};\n\n"; |
6461
|
|
|
|
|
|
|
} |
6462
|
|
|
|
|
|
|
} |
6463
|
|
|
|
|
|
|
|
6464
|
0
|
|
|
|
|
0
|
fixup_ppaddr(); |
6465
|
0
|
|
|
|
|
0
|
print "static void perl_init0(pTHX) /* fixup_ppaddr */\n{\n\t"; |
6466
|
0
|
0
|
|
|
|
0
|
print "register int i;\n" if @{ $init0->[-1]{values} }; |
|
0
|
|
|
|
|
0
|
|
6467
|
0
|
|
|
|
|
0
|
$init0->output( \*STDOUT, "\t%s\n" ); |
6468
|
0
|
|
|
|
|
0
|
print "};\n\n"; |
6469
|
|
|
|
|
|
|
|
6470
|
0
|
0
|
0
|
|
|
0
|
printf "\t/* %s */\n", $init->comment if $init->comment and $verbose; |
6471
|
0
|
|
|
|
|
0
|
$init->output( \*STDOUT, "\t%s\n", $init_name ); |
6472
|
0
|
0
|
|
|
|
0
|
printf "/* deferred init1 of regexp */\n" if $verbose; |
6473
|
0
|
0
|
0
|
|
|
0
|
printf "/* %s */\n", $init1->comment if $init1->comment and $verbose; |
6474
|
0
|
|
|
|
|
0
|
$init1->output( \*STDOUT, "\t%s\n", 'perl_init1' ); |
6475
|
0
|
|
|
|
|
0
|
my $init2_name = 'perl_init2'; |
6476
|
0
|
0
|
|
|
|
0
|
printf "/* deferred init of XS/Dyna loaded modules */\n" if $verbose; |
6477
|
0
|
0
|
0
|
|
|
0
|
printf "/* %s */\n", $init2->comment if $init2->comment and $verbose; |
6478
|
0
|
|
|
|
|
0
|
my $remap = 0; |
6479
|
0
|
|
|
|
|
0
|
for my $pkg (sort keys %init2_remap) { |
6480
|
0
|
0
|
|
|
|
0
|
if (exists $xsub{$pkg}) { # check if not removed in between |
6481
|
0
|
|
|
|
|
0
|
my ($stashfile) = $xsub{$pkg} =~ /^Dynamic-(.+)$/; |
6482
|
|
|
|
|
|
|
# get so file from pm. Note: could switch prefix from vendor/site// |
6483
|
0
|
|
|
|
|
0
|
$init2_remap{$pkg}{FILE} = dl_module_to_sofile($pkg, $stashfile); |
6484
|
0
|
|
|
|
|
0
|
$remap++; |
6485
|
|
|
|
|
|
|
} |
6486
|
|
|
|
|
|
|
} |
6487
|
0
|
0
|
|
|
|
0
|
if ($remap) { |
6488
|
|
|
|
|
|
|
# XXX now emit arch-specific dlsym code |
6489
|
0
|
|
|
|
|
0
|
$init2->no_split; |
6490
|
0
|
|
|
|
|
0
|
$init2->add("{"); |
6491
|
0
|
0
|
|
|
|
0
|
if ($HAVE_DLFCN_DLOPEN) { |
6492
|
0
|
|
|
|
|
0
|
$init2->add(" #include "); |
6493
|
0
|
|
|
|
|
0
|
$init2->add(" void *handle;"); |
6494
|
|
|
|
|
|
|
} else { |
6495
|
0
|
|
|
|
|
0
|
$init2->add(" void *handle;"); |
6496
|
0
|
|
|
|
|
0
|
$init2->add(" dTARG; dSP;", |
6497
|
|
|
|
|
|
|
" targ=sv_newmortal();"); |
6498
|
|
|
|
|
|
|
} |
6499
|
0
|
|
|
|
|
0
|
for my $pkg (sort keys %init2_remap) { |
6500
|
0
|
0
|
|
|
|
0
|
if (exists $xsub{$pkg}) { |
6501
|
0
|
0
|
|
|
|
0
|
if ($HAVE_DLFCN_DLOPEN) { |
6502
|
0
|
|
|
|
|
0
|
my $ldopt = 'RTLD_NOW|RTLD_NOLOAD'; |
6503
|
0
|
0
|
|
|
|
0
|
$ldopt = 'RTLD_NOW' if $^O =~ /bsd/i; # 351 (only on solaris and linux, not any bsd) |
6504
|
0
|
|
|
|
|
0
|
$init2->add( "", sprintf(" handle = dlopen(%s, %s);", cstring($init2_remap{$pkg}{FILE}), $ldopt)); |
6505
|
|
|
|
|
|
|
} |
6506
|
|
|
|
|
|
|
else { |
6507
|
|
|
|
|
|
|
$init2->add(" PUSHMARK(SP);", |
6508
|
0
|
|
|
|
|
0
|
sprintf(" XPUSHs(newSVpvs(%s));", cstring($init2_remap{$pkg}{FILE})), |
6509
|
|
|
|
|
|
|
" PUTBACK;", |
6510
|
|
|
|
|
|
|
" XS_DynaLoader_dl_load_file(aTHX_ NULL);", |
6511
|
|
|
|
|
|
|
" SPAGAIN;", |
6512
|
|
|
|
|
|
|
" handle = INT2PTR(void*,POPi);", |
6513
|
|
|
|
|
|
|
" PUTBACK;", |
6514
|
|
|
|
|
|
|
); |
6515
|
|
|
|
|
|
|
} |
6516
|
0
|
|
|
|
|
0
|
for my $mg (@{$init2_remap{$pkg}{MG}}) { |
|
0
|
|
|
|
|
0
|
|
6517
|
0
|
0
|
|
|
|
0
|
warn "init2 remap xpvmg_list[$mg->{ID}].xiv_iv to dlsym of $pkg\: $mg->{NAME}\n" |
6518
|
|
|
|
|
|
|
if $verbose; |
6519
|
0
|
0
|
|
|
|
0
|
if ($HAVE_DLFCN_DLOPEN) { |
6520
|
|
|
|
|
|
|
$init2->add(sprintf(" xpvmg_list[%d].xiv_iv = PTR2IV( dlsym(handle, %s) );", |
6521
|
0
|
|
|
|
|
0
|
$mg->{ID}, cstring($mg->{NAME}))); |
6522
|
|
|
|
|
|
|
} else { |
6523
|
|
|
|
|
|
|
$init2->add(" PUSHMARK(SP);", |
6524
|
|
|
|
|
|
|
" XPUSHi(PTR2IV(handle));", |
6525
|
|
|
|
|
|
|
sprintf(" XPUSHs(newSVpvs(%s));", cstring($mg->{NAME})), |
6526
|
|
|
|
|
|
|
" PUTBACK;", |
6527
|
|
|
|
|
|
|
" XS_DynaLoader_dl_find_symbol(aTHX_ NULL);", |
6528
|
|
|
|
|
|
|
" SPAGAIN;", |
6529
|
0
|
|
|
|
|
0
|
sprintf(" xpvmg_list[%d].xiv_iv = POPi;", $mg->{ID}), |
6530
|
|
|
|
|
|
|
" PUTBACK;", |
6531
|
|
|
|
|
|
|
); |
6532
|
|
|
|
|
|
|
} |
6533
|
|
|
|
|
|
|
} |
6534
|
|
|
|
|
|
|
} |
6535
|
|
|
|
|
|
|
} |
6536
|
0
|
|
|
|
|
0
|
$init2->add("}"); |
6537
|
0
|
|
|
|
|
0
|
$init2->split; |
6538
|
|
|
|
|
|
|
} |
6539
|
0
|
|
|
|
|
0
|
$init2->output( \*STDOUT, "\t%s\n", $init2_name ); |
6540
|
0
|
0
|
|
|
|
0
|
if ($verbose) { |
6541
|
0
|
|
|
|
|
0
|
my $caller = caller; |
6542
|
0
|
0
|
|
|
|
0
|
warn $caller eq 'B::CC' ? B::CC::compile_stats() : compile_stats(); |
6543
|
0
|
|
|
|
|
0
|
warn "NULLOP count: $nullop_count\n"; |
6544
|
|
|
|
|
|
|
} |
6545
|
|
|
|
|
|
|
} |
6546
|
|
|
|
|
|
|
|
6547
|
|
|
|
|
|
|
sub output_declarations { |
6548
|
0
|
|
|
0
|
0
|
0
|
print <<'EOT'; |
6549
|
|
|
|
|
|
|
#define UNUSED 0 |
6550
|
|
|
|
|
|
|
#define sym_0 0 |
6551
|
|
|
|
|
|
|
|
6552
|
|
|
|
|
|
|
static void |
6553
|
|
|
|
|
|
|
my_mg_RC_off(pTHX_ SV* sv, int type) { |
6554
|
|
|
|
|
|
|
MAGIC *mg; |
6555
|
|
|
|
|
|
|
for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) { |
6556
|
|
|
|
|
|
|
if (mg->mg_type == type && (mg->mg_flags | MGf_REFCOUNTED)) |
6557
|
|
|
|
|
|
|
mg->mg_flags &= ~MGf_REFCOUNTED; |
6558
|
|
|
|
|
|
|
} |
6559
|
|
|
|
|
|
|
} |
6560
|
|
|
|
|
|
|
|
6561
|
|
|
|
|
|
|
EOT |
6562
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and IS_MSVC) { |
6563
|
|
|
|
|
|
|
# initializing char * differs in levels of indirection from int |
6564
|
0
|
|
|
|
|
0
|
print "#pragma warning( disable : 4047 )\n"; |
6565
|
|
|
|
|
|
|
# targ: unreferenced local variable |
6566
|
0
|
|
|
|
|
0
|
print "#pragma warning( disable : 4101 )\n"; |
6567
|
|
|
|
|
|
|
} |
6568
|
|
|
|
|
|
|
|
6569
|
|
|
|
|
|
|
# Need fresh re-hash of strtab. share_hek does not allow hash = 0 |
6570
|
0
|
0
|
|
|
|
0
|
if ( $PERL510 ) { |
6571
|
0
|
|
|
|
|
0
|
print <<'_EOT0'; |
6572
|
|
|
|
|
|
|
PERL_STATIC_INLINE HEK * |
6573
|
|
|
|
|
|
|
my_share_hek( pTHX_ const char *str, I32 len ); |
6574
|
|
|
|
|
|
|
#undef share_hek |
6575
|
|
|
|
|
|
|
#define share_hek(str, len) my_share_hek( aTHX_ str, len ); |
6576
|
|
|
|
|
|
|
|
6577
|
|
|
|
|
|
|
PERL_STATIC_INLINE HEK * |
6578
|
|
|
|
|
|
|
my_share_hek_0( pTHX_ const char *str, I32 len); |
6579
|
|
|
|
|
|
|
|
6580
|
|
|
|
|
|
|
#define HEK_HE(hek) \ |
6581
|
|
|
|
|
|
|
((struct shared_he *)(((char *)(hek)) \ |
6582
|
|
|
|
|
|
|
- STRUCT_OFFSET(struct shared_he, \ |
6583
|
|
|
|
|
|
|
shared_he_hek))) |
6584
|
|
|
|
|
|
|
#define HEK_shared_he(hek) \ |
6585
|
|
|
|
|
|
|
((struct shared_he *)(((char *)(hek)) \ |
6586
|
|
|
|
|
|
|
- STRUCT_OFFSET(struct shared_he, \ |
6587
|
|
|
|
|
|
|
shared_he_hek))) \ |
6588
|
|
|
|
|
|
|
->shared_he_he |
6589
|
|
|
|
|
|
|
|
6590
|
|
|
|
|
|
|
#define hek_hek_refcount(hek) \ |
6591
|
|
|
|
|
|
|
HEK_shared_he(hek).he_valu.hent_refcount |
6592
|
|
|
|
|
|
|
|
6593
|
|
|
|
|
|
|
#define unshare_hek_hek(hek) --(hek_hek_refcount(hek)) |
6594
|
|
|
|
|
|
|
|
6595
|
|
|
|
|
|
|
_EOT0 |
6596
|
|
|
|
|
|
|
|
6597
|
|
|
|
|
|
|
} |
6598
|
0
|
0
|
|
|
|
0
|
if ($PERL522) { |
6599
|
0
|
|
|
|
|
0
|
print <<'EOF'; |
6600
|
|
|
|
|
|
|
/* unfortunately we have to override this perl5.22 struct. |
6601
|
|
|
|
|
|
|
The Padname string buffer in xpadn_str is pointed by xpadn_pv. |
6602
|
|
|
|
|
|
|
*/ |
6603
|
|
|
|
|
|
|
#define _PADNAME_BASE \ |
6604
|
|
|
|
|
|
|
char * xpadn_pv; \ |
6605
|
|
|
|
|
|
|
HV * xpadn_ourstash; \ |
6606
|
|
|
|
|
|
|
union { \ |
6607
|
|
|
|
|
|
|
HV * xpadn_typestash; \ |
6608
|
|
|
|
|
|
|
CV * xpadn_protocv; \ |
6609
|
|
|
|
|
|
|
} xpadn_type_u; \ |
6610
|
|
|
|
|
|
|
U32 xpadn_low; \ |
6611
|
|
|
|
|
|
|
U32 xpadn_high; \ |
6612
|
|
|
|
|
|
|
U32 xpadn_refcnt; \ |
6613
|
|
|
|
|
|
|
int xpadn_gen; \ |
6614
|
|
|
|
|
|
|
U8 xpadn_len; \ |
6615
|
|
|
|
|
|
|
U8 xpadn_flags |
6616
|
|
|
|
|
|
|
|
6617
|
|
|
|
|
|
|
#ifdef PERL_PADNAME_MINIMAL |
6618
|
|
|
|
|
|
|
#define MY_PADNAME_BASE _PADNAME_BASE |
6619
|
|
|
|
|
|
|
#else |
6620
|
|
|
|
|
|
|
#define MY_PADNAME_BASE struct padname xpadn_padname |
6621
|
|
|
|
|
|
|
#endif |
6622
|
|
|
|
|
|
|
|
6623
|
|
|
|
|
|
|
EOF |
6624
|
|
|
|
|
|
|
|
6625
|
0
|
|
|
|
|
0
|
for my $s (sort keys %padnamesect) { |
6626
|
0
|
0
|
|
|
|
0
|
if ($padnamesect{$s}->index >= 0) { |
6627
|
0
|
|
|
|
|
0
|
print <<"EOF"; |
6628
|
|
|
|
|
|
|
struct my_padname_with_str_$s { |
6629
|
|
|
|
|
|
|
MY_PADNAME_BASE; |
6630
|
|
|
|
|
|
|
char xpadn_str[$s]; |
6631
|
|
|
|
|
|
|
}; |
6632
|
|
|
|
|
|
|
typedef struct my_padname_with_str_$s PADNAME_$s; |
6633
|
|
|
|
|
|
|
EOF |
6634
|
|
|
|
|
|
|
} |
6635
|
|
|
|
|
|
|
} |
6636
|
|
|
|
|
|
|
#} elsif ($PERL518) { |
6637
|
|
|
|
|
|
|
# print "typedef PADNAME MyPADNAME;\n"; |
6638
|
|
|
|
|
|
|
} |
6639
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and !$PERL514) { |
6640
|
0
|
|
|
|
|
0
|
print "typedef struct refcounted_he COPHH;\n"; |
6641
|
0
|
|
|
|
|
0
|
print <<'EOF'; |
6642
|
|
|
|
|
|
|
#define cophh_store_pvn(cophh, keypv, keylen, hash, value, flags) \ |
6643
|
|
|
|
|
|
|
Perl_refcounted_he_new(aTHX_ cophh, newSVpvn_flags(keypv, keylen, flags), value) |
6644
|
|
|
|
|
|
|
#define cophh_store_pvs(cophh, key, value, flags) \ |
6645
|
|
|
|
|
|
|
Perl_refcounted_he_new(aTHX_ cophh, Perl_newSVpvn_flags(aTHX_ STR_WITH_LEN(key), SVs_TEMP), value) |
6646
|
|
|
|
|
|
|
#define CopHINTHASH_set(c,h) ((c)->cop_hints_hash = (h)) |
6647
|
|
|
|
|
|
|
EOF |
6648
|
|
|
|
|
|
|
} |
6649
|
0
|
0
|
|
|
|
0
|
if ($B::C::Config::have_HEK_STATIC) { |
6650
|
0
|
|
|
|
|
0
|
print "/* store full char[] to avoid excess elements in array\n"; |
6651
|
0
|
|
|
|
|
0
|
print " (HEK only declared as char[1]) */\n"; |
6652
|
0
|
|
|
|
|
0
|
print "struct hek_ptr { U32 hek_hash; I32 hek_len; char hek_key[]; };\n"; |
6653
|
|
|
|
|
|
|
} |
6654
|
|
|
|
|
|
|
# Tricky hack for -fcog since 5.10 on !c99 compilers required. We need a char* as |
6655
|
|
|
|
|
|
|
# *first* sv_u element to be able to statically initialize it. A int does not allow it. |
6656
|
|
|
|
|
|
|
# gcc error: initializer element is not computable at load time |
6657
|
|
|
|
|
|
|
# We introduce a SVPV as SV. |
6658
|
|
|
|
|
|
|
# In core since 5.12 |
6659
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and $] < 5.012 and !$C99) { |
|
|
|
0
|
|
|
|
|
6660
|
0
|
|
|
|
|
0
|
print <<'EOT0'; |
6661
|
|
|
|
|
|
|
typedef struct svpv { |
6662
|
|
|
|
|
|
|
void * sv_any; |
6663
|
|
|
|
|
|
|
U32 sv_refcnt; |
6664
|
|
|
|
|
|
|
U32 sv_flags; |
6665
|
|
|
|
|
|
|
union { |
6666
|
|
|
|
|
|
|
char* svu_pv; |
6667
|
|
|
|
|
|
|
IV svu_iv; |
6668
|
|
|
|
|
|
|
UV svu_uv; |
6669
|
|
|
|
|
|
|
SV* svu_rv; |
6670
|
|
|
|
|
|
|
SV** svu_array; |
6671
|
|
|
|
|
|
|
HE** svu_hash; |
6672
|
|
|
|
|
|
|
GP* svu_gp; |
6673
|
|
|
|
|
|
|
} sv_u; |
6674
|
|
|
|
|
|
|
#ifdef DEBUG_LEAKING_SCALARS |
6675
|
|
|
|
|
|
|
PERL_BITFIELD32 sv_debug_optype:9; |
6676
|
|
|
|
|
|
|
PERL_BITFIELD32 sv_debug_inpad:1; |
6677
|
|
|
|
|
|
|
PERL_BITFIELD32 sv_debug_cloned:1; |
6678
|
|
|
|
|
|
|
PERL_BITFIELD32 sv_debug_line:16; |
6679
|
|
|
|
|
|
|
# if PERL_VERSION < 11 |
6680
|
|
|
|
|
|
|
U32 sv_debug_serial; /* 5.10 only */ |
6681
|
|
|
|
|
|
|
# endif |
6682
|
|
|
|
|
|
|
# if PERL_VERSION > 8 |
6683
|
|
|
|
|
|
|
char * sv_debug_file; |
6684
|
|
|
|
|
|
|
# endif |
6685
|
|
|
|
|
|
|
#endif |
6686
|
|
|
|
|
|
|
} SVPV; |
6687
|
|
|
|
|
|
|
EOT0 |
6688
|
|
|
|
|
|
|
|
6689
|
|
|
|
|
|
|
} |
6690
|
0
|
0
|
|
|
|
0
|
if ($PERL512) { |
|
|
0
|
|
|
|
|
|
6691
|
0
|
|
|
|
|
0
|
print "typedef struct p5rx RE;\n"; |
6692
|
|
|
|
|
|
|
} |
6693
|
|
|
|
|
|
|
elsif ($PERL510) { |
6694
|
0
|
|
|
|
|
0
|
print "typedef SV * RE;\n"; |
6695
|
|
|
|
|
|
|
} |
6696
|
|
|
|
|
|
|
else { |
6697
|
0
|
|
|
|
|
0
|
print "typedef char * RE;\n"; |
6698
|
|
|
|
|
|
|
} |
6699
|
0
|
0
|
|
|
|
0
|
if ($] == 5.010000) { |
6700
|
0
|
|
|
|
|
0
|
print "#ifndef RX_EXTFLAGS\n"; |
6701
|
0
|
|
|
|
|
0
|
print "# define RX_EXTFLAGS(rx) ((rx)->extflags)\n"; |
6702
|
0
|
|
|
|
|
0
|
print "#endif\n"; |
6703
|
|
|
|
|
|
|
} |
6704
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.021001 and !$CPERL52) { |
6705
|
0
|
|
|
|
|
0
|
print "Static IV PL_sv_objcount = 0; /* deprecated with 5.21.1 but still needed and used */\n"; |
6706
|
|
|
|
|
|
|
} |
6707
|
0
|
|
|
|
|
0
|
print "SV* sv;\n"; |
6708
|
0
|
0
|
|
|
|
0
|
print "Static GV *gv_list[$gv_index];\n" if $gv_index; |
6709
|
|
|
|
|
|
|
} |
6710
|
|
|
|
|
|
|
|
6711
|
|
|
|
|
|
|
sub output_boilerplate { |
6712
|
0
|
|
|
0
|
0
|
0
|
my $creator = "created at ".scalar localtime()." with B::C $B::C::VERSION "; |
6713
|
0
|
0
|
|
|
|
0
|
$creator .= $B::C::REVISION if $B::C::REVISION; |
6714
|
0
|
|
|
|
|
0
|
$creator .= " for $^X"; |
6715
|
0
|
|
|
|
|
0
|
print "/* $creator */\n"; |
6716
|
|
|
|
|
|
|
# Store the sv_list index in sv_debug_file when debugging |
6717
|
0
|
0
|
0
|
|
|
0
|
print "#define DEBUG_LEAKING_SCALARS 1\n" if $debug{flags} and $DEBUG_LEAKING_SCALARS; |
6718
|
0
|
0
|
|
|
|
0
|
if ($B::C::Config::have_independent_comalloc) { |
6719
|
0
|
|
|
|
|
0
|
print <<'_EOT1'; |
6720
|
|
|
|
|
|
|
#ifdef NEED_MALLOC_283 |
6721
|
|
|
|
|
|
|
# include "malloc-2.8.3.h" |
6722
|
|
|
|
|
|
|
#endif |
6723
|
|
|
|
|
|
|
_EOT1 |
6724
|
|
|
|
|
|
|
|
6725
|
|
|
|
|
|
|
} |
6726
|
0
|
|
|
|
|
0
|
print <<'_EOT2'; |
6727
|
|
|
|
|
|
|
#define PERL_CORE |
6728
|
|
|
|
|
|
|
#include "EXTERN.h" |
6729
|
|
|
|
|
|
|
#include "perl.h" |
6730
|
|
|
|
|
|
|
#include "XSUB.h" |
6731
|
|
|
|
|
|
|
|
6732
|
|
|
|
|
|
|
/* Workaround for mapstart: the only op which needs a different ppaddr */ |
6733
|
|
|
|
|
|
|
#undef Perl_pp_mapstart |
6734
|
|
|
|
|
|
|
#define Perl_pp_mapstart Perl_pp_grepstart |
6735
|
|
|
|
|
|
|
#undef OP_MAPSTART |
6736
|
|
|
|
|
|
|
#define OP_MAPSTART OP_GREPSTART |
6737
|
|
|
|
|
|
|
|
6738
|
|
|
|
|
|
|
#ifdef BROKEN_STATIC_REDECL |
6739
|
|
|
|
|
|
|
#define Static extern |
6740
|
|
|
|
|
|
|
#else |
6741
|
|
|
|
|
|
|
#define Static static |
6742
|
|
|
|
|
|
|
#endif /* BROKEN_STATIC_REDECL */ |
6743
|
|
|
|
|
|
|
|
6744
|
|
|
|
|
|
|
#ifdef BROKEN_UNION_INIT |
6745
|
|
|
|
|
|
|
#error BROKEN_UNION_INIT no longer needed, as Perl requires an ANSI compiler |
6746
|
|
|
|
|
|
|
#endif |
6747
|
|
|
|
|
|
|
|
6748
|
|
|
|
|
|
|
/* No longer available when C is defined. */ |
6749
|
|
|
|
|
|
|
#ifndef Nullsv |
6750
|
|
|
|
|
|
|
# define Null(type) ((type)NULL) |
6751
|
|
|
|
|
|
|
# define Nullsv Null(SV*) |
6752
|
|
|
|
|
|
|
# define Nullhv Null(HV*) |
6753
|
|
|
|
|
|
|
# define Nullgv Null(GV*) |
6754
|
|
|
|
|
|
|
# define Nullop Null(OP*) |
6755
|
|
|
|
|
|
|
#endif |
6756
|
|
|
|
|
|
|
#ifndef GV_NOTQUAL |
6757
|
|
|
|
|
|
|
# define GV_NOTQUAL 0 |
6758
|
|
|
|
|
|
|
#endif |
6759
|
|
|
|
|
|
|
/* Since 5.8.8 */ |
6760
|
|
|
|
|
|
|
#ifndef Newx |
6761
|
|
|
|
|
|
|
# define Newx(v,n,t) New(0,v,n,t) |
6762
|
|
|
|
|
|
|
#endif |
6763
|
|
|
|
|
|
|
/* Since 5.14 */ |
6764
|
|
|
|
|
|
|
#if !defined(PERL_STATIC_INLINE) |
6765
|
|
|
|
|
|
|
# ifdef HAS_STATIC_INLINE |
6766
|
|
|
|
|
|
|
# define PERL_STATIC_INLINE static inline |
6767
|
|
|
|
|
|
|
# else |
6768
|
|
|
|
|
|
|
# define PERL_STATIC_INLINE static |
6769
|
|
|
|
|
|
|
# endif |
6770
|
|
|
|
|
|
|
#endif |
6771
|
|
|
|
|
|
|
/* cperl compat */ |
6772
|
|
|
|
|
|
|
#ifndef HEK_STATIC |
6773
|
|
|
|
|
|
|
# define HEK_STATIC(hek) 0 |
6774
|
|
|
|
|
|
|
#endif |
6775
|
|
|
|
|
|
|
|
6776
|
|
|
|
|
|
|
_EOT2 |
6777
|
|
|
|
|
|
|
|
6778
|
0
|
0
|
|
|
|
0
|
if ($] < 5.008008) { |
6779
|
0
|
|
|
|
|
0
|
print "#define GvSVn(s) GvSV(s)\n"; |
6780
|
|
|
|
|
|
|
} |
6781
|
|
|
|
|
|
|
|
6782
|
|
|
|
|
|
|
# XXX boot_DynaLoader is exported only >=5.8.9 |
6783
|
|
|
|
|
|
|
# does not compile on darwin with EXTERN_C declaration |
6784
|
|
|
|
|
|
|
# See branch `boot_DynaLoader` |
6785
|
0
|
|
|
|
|
0
|
print <<'_EOT4'; |
6786
|
|
|
|
|
|
|
|
6787
|
|
|
|
|
|
|
#define XS_DynaLoader_boot_DynaLoader boot_DynaLoader |
6788
|
|
|
|
|
|
|
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); |
6789
|
|
|
|
|
|
|
|
6790
|
|
|
|
|
|
|
static void xs_init (pTHX); |
6791
|
|
|
|
|
|
|
static void dl_init (pTHX); |
6792
|
|
|
|
|
|
|
_EOT4 |
6793
|
|
|
|
|
|
|
|
6794
|
0
|
0
|
0
|
|
|
0
|
print <<'_EOT' if $CPERL51 and $^O ne 'MSWin32'; |
6795
|
|
|
|
|
|
|
EXTERN_C void dl_boot (pTHX); |
6796
|
|
|
|
|
|
|
_EOT |
6797
|
|
|
|
|
|
|
|
6798
|
0
|
0
|
0
|
|
|
0
|
if ($B::C::av_init2 and $B::C::Config::use_declare_independent_comalloc) { |
6799
|
0
|
|
|
|
|
0
|
print "void** dlindependent_comalloc(size_t, size_t*, void**);\n"; |
6800
|
|
|
|
|
|
|
} |
6801
|
0
|
0
|
|
|
|
0
|
if ($B::C::av_init2) { |
6802
|
0
|
|
|
|
|
0
|
my $last = $xpvavsect->index; |
6803
|
0
|
|
|
|
|
0
|
my $size = $last + 1; |
6804
|
0
|
0
|
|
|
|
0
|
if ($last) { |
6805
|
0
|
|
|
|
|
0
|
$decl->add("Static void* avchunks[$size];"); |
6806
|
0
|
|
|
|
|
0
|
$decl->add("Static size_t avsizes[$size] = "); |
6807
|
0
|
|
|
|
|
0
|
my $ptrsize = $Config{ptrsize}; |
6808
|
0
|
|
|
|
|
0
|
my $acc = ""; |
6809
|
0
|
|
|
|
|
0
|
for (0..$last) { |
6810
|
0
|
0
|
|
|
|
0
|
if ($xpvav_sizes[$_] > 0) { |
6811
|
0
|
|
|
|
|
0
|
$acc .= $xpvav_sizes[$_] * $ptrsize; |
6812
|
|
|
|
|
|
|
} else { |
6813
|
0
|
|
|
|
|
0
|
$acc .= 3 * $ptrsize; |
6814
|
|
|
|
|
|
|
} |
6815
|
0
|
0
|
|
|
|
0
|
$acc .= "," if $_ != $last; |
6816
|
0
|
0
|
|
|
|
0
|
$acc .= "\n\t" unless ($_+1) % 30; |
6817
|
|
|
|
|
|
|
} |
6818
|
0
|
|
|
|
|
0
|
$decl->add("\t{$acc};"); |
6819
|
0
|
|
|
|
|
0
|
$init->add_initav("if (!independent_comalloc( $size, avsizes, avchunks ))"); |
6820
|
0
|
|
|
|
|
0
|
$init->add_initav(" Perl_die(aTHX_ \"panic: AV alloc failed\");"); |
6821
|
|
|
|
|
|
|
} |
6822
|
|
|
|
|
|
|
} |
6823
|
0
|
0
|
|
|
|
0
|
if ( !$B::C::destruct ) { |
6824
|
0
|
|
|
|
|
0
|
print <<'_EOT4'; |
6825
|
|
|
|
|
|
|
static int fast_perl_destruct( PerlInterpreter *my_perl ); |
6826
|
|
|
|
|
|
|
static void my_curse( pTHX_ SV* const sv ); |
6827
|
|
|
|
|
|
|
|
6828
|
|
|
|
|
|
|
#ifndef dVAR |
6829
|
|
|
|
|
|
|
# ifdef PERL_GLOBAL_STRUCT |
6830
|
|
|
|
|
|
|
# define dVAR pVAR = (struct perl_vars*)PERL_GET_VARS() |
6831
|
|
|
|
|
|
|
# else |
6832
|
|
|
|
|
|
|
# define dVAR dNOOP |
6833
|
|
|
|
|
|
|
# endif |
6834
|
|
|
|
|
|
|
#endif |
6835
|
|
|
|
|
|
|
_EOT4 |
6836
|
|
|
|
|
|
|
|
6837
|
|
|
|
|
|
|
} else { |
6838
|
0
|
|
|
|
|
0
|
print <<'_EOT5'; |
6839
|
|
|
|
|
|
|
int my_perl_destruct( PerlInterpreter *my_perl ); |
6840
|
|
|
|
|
|
|
_EOT5 |
6841
|
|
|
|
|
|
|
|
6842
|
|
|
|
|
|
|
} |
6843
|
0
|
0
|
|
|
|
0
|
if ($] < 5.008009) { |
6844
|
0
|
|
|
|
|
0
|
print <<'_EOT3'; |
6845
|
|
|
|
|
|
|
#ifndef savesharedpvn |
6846
|
|
|
|
|
|
|
char *savesharedpvn(const char *const s, const STRLEN len); |
6847
|
|
|
|
|
|
|
#endif |
6848
|
|
|
|
|
|
|
_EOT3 |
6849
|
|
|
|
|
|
|
|
6850
|
|
|
|
|
|
|
} |
6851
|
|
|
|
|
|
|
} |
6852
|
|
|
|
|
|
|
|
6853
|
|
|
|
|
|
|
sub init_op_addr { |
6854
|
0
|
|
|
0
|
0
|
0
|
my ( $op_type, $num ) = @_; |
6855
|
0
|
|
|
|
|
0
|
my $op_list = $op_type . "_list"; |
6856
|
|
|
|
|
|
|
|
6857
|
0
|
|
|
|
|
0
|
$init0->add( split /\n/, <<_EOT6 ); |
6858
|
|
|
|
|
|
|
for (i = 0; i < ${num}; ++i) { |
6859
|
|
|
|
|
|
|
${op_list}\[i].op_ppaddr = PL_ppaddr[PTR2IV(${op_list}\[i].op_ppaddr)]; |
6860
|
|
|
|
|
|
|
} |
6861
|
|
|
|
|
|
|
_EOT6 |
6862
|
|
|
|
|
|
|
|
6863
|
|
|
|
|
|
|
} |
6864
|
|
|
|
|
|
|
|
6865
|
|
|
|
|
|
|
sub output_main_rest { |
6866
|
|
|
|
|
|
|
|
6867
|
0
|
0
|
|
0
|
0
|
0
|
if ( $PERL510 ) { |
6868
|
0
|
|
|
|
|
0
|
print <<'_EOT7'; |
6869
|
|
|
|
|
|
|
/* The first assignment got already refcount bumped */ |
6870
|
|
|
|
|
|
|
PERL_STATIC_INLINE HEK * |
6871
|
|
|
|
|
|
|
my_share_hek( pTHX_ const char *str, I32 len) { |
6872
|
|
|
|
|
|
|
U32 hash; |
6873
|
|
|
|
|
|
|
PERL_HASH(hash, str, abs(len)); |
6874
|
|
|
|
|
|
|
return share_hek_hek(Perl_share_hek(aTHX_ str, len, hash)); |
6875
|
|
|
|
|
|
|
} |
6876
|
|
|
|
|
|
|
|
6877
|
|
|
|
|
|
|
_EOT7 |
6878
|
|
|
|
|
|
|
} |
6879
|
0
|
0
|
|
|
|
0
|
if ( $PERL510 ) { |
6880
|
0
|
|
|
|
|
0
|
print <<'_EOT7'; |
6881
|
|
|
|
|
|
|
PERL_STATIC_INLINE HEK * |
6882
|
|
|
|
|
|
|
my_share_hek_0( pTHX_ const char *str, I32 len) { |
6883
|
|
|
|
|
|
|
U32 hash; |
6884
|
|
|
|
|
|
|
PERL_HASH(hash, str, abs(len)); |
6885
|
|
|
|
|
|
|
return Perl_share_hek(aTHX_ str, len, hash); |
6886
|
|
|
|
|
|
|
} |
6887
|
|
|
|
|
|
|
|
6888
|
|
|
|
|
|
|
_EOT7 |
6889
|
|
|
|
|
|
|
} |
6890
|
|
|
|
|
|
|
|
6891
|
0
|
0
|
|
|
|
0
|
if ($] < 5.008009) { |
6892
|
0
|
|
|
|
|
0
|
print <<'_EOT7a'; |
6893
|
|
|
|
|
|
|
#ifndef savesharedpvn |
6894
|
|
|
|
|
|
|
char *savesharedpvn(const char *const s, const STRLEN len) { |
6895
|
|
|
|
|
|
|
char *const d = (char*)PerlMemShared_malloc(len + 1); |
6896
|
|
|
|
|
|
|
if (!d) { exit(1); } |
6897
|
|
|
|
|
|
|
d[len] = '\0'; |
6898
|
|
|
|
|
|
|
return (char *)memcpy(d, s, len); |
6899
|
|
|
|
|
|
|
} |
6900
|
|
|
|
|
|
|
#endif |
6901
|
|
|
|
|
|
|
_EOT7a |
6902
|
|
|
|
|
|
|
|
6903
|
|
|
|
|
|
|
} |
6904
|
|
|
|
|
|
|
# -fno-destruct only >=5.8 |
6905
|
0
|
0
|
|
|
|
0
|
if ( !$B::C::destruct ) { |
6906
|
0
|
|
|
|
|
0
|
print <<'_EOT8'; |
6907
|
|
|
|
|
|
|
|
6908
|
|
|
|
|
|
|
#ifndef SvDESTROYABLE |
6909
|
|
|
|
|
|
|
#define SvDESTROYABLE(sv) 1 |
6910
|
|
|
|
|
|
|
#endif |
6911
|
|
|
|
|
|
|
/* 5.8 */ |
6912
|
|
|
|
|
|
|
#ifndef CvISXSUB |
6913
|
|
|
|
|
|
|
#define CvISXSUB(sv) CvXSUB(sv) |
6914
|
|
|
|
|
|
|
#endif |
6915
|
|
|
|
|
|
|
#ifndef SvRV_set |
6916
|
|
|
|
|
|
|
#define SvRV_set(a,b) SvRV(a) = (b) |
6917
|
|
|
|
|
|
|
#endif |
6918
|
|
|
|
|
|
|
/* 5.6 */ |
6919
|
|
|
|
|
|
|
#ifndef PERL_EXIT_DESTRUCT_END |
6920
|
|
|
|
|
|
|
#define PERL_EXIT_DESTRUCT_END 2 |
6921
|
|
|
|
|
|
|
#endif |
6922
|
|
|
|
|
|
|
|
6923
|
|
|
|
|
|
|
static void |
6924
|
|
|
|
|
|
|
my_curse( pTHX_ SV* const sv ) { |
6925
|
|
|
|
|
|
|
dSP; |
6926
|
|
|
|
|
|
|
dVAR; |
6927
|
|
|
|
|
|
|
HV* stash; |
6928
|
|
|
|
|
|
|
|
6929
|
|
|
|
|
|
|
#if PERL_VERSION > 7 |
6930
|
|
|
|
|
|
|
assert(SvOBJECT(sv)); |
6931
|
|
|
|
|
|
|
do { |
6932
|
|
|
|
|
|
|
stash = SvSTASH(sv); |
6933
|
|
|
|
|
|
|
assert(SvTYPE(stash) == SVt_PVHV); |
6934
|
|
|
|
|
|
|
if (HvNAME(stash)) { |
6935
|
|
|
|
|
|
|
CV* destructor = NULL; |
6936
|
|
|
|
|
|
|
if (!SvOBJECT(stash)) destructor = (CV *)SvSTASH(stash); |
6937
|
|
|
|
|
|
|
if (!destructor |
6938
|
|
|
|
|
|
|
#if (PERL_VERSION > 18) || (PERL_VERSION == 18 && PERL_SUBVERSION > 1) |
6939
|
|
|
|
|
|
|
|| HvMROMETA(stash)->destroy_gen != PL_sub_generation |
6940
|
|
|
|
|
|
|
#endif |
6941
|
|
|
|
|
|
|
) { |
6942
|
|
|
|
|
|
|
GV * const gv = gv_fetchmeth_autoload(stash, "DESTROY", 7, 0); |
6943
|
|
|
|
|
|
|
if (gv) { |
6944
|
|
|
|
|
|
|
destructor = GvCV(gv); |
6945
|
|
|
|
|
|
|
if (!SvOBJECT(stash)) { |
6946
|
|
|
|
|
|
|
SvSTASH(stash) = |
6947
|
|
|
|
|
|
|
destructor ? (HV *)destructor : ((HV *)0)+1; |
6948
|
|
|
|
|
|
|
#if (PERL_VERSION > 18) || (PERL_VERSION == 18 && PERL_SUBVERSION > 1) |
6949
|
|
|
|
|
|
|
HvAUX(stash)->xhv_mro_meta->destroy_gen = PL_sub_generation; |
6950
|
|
|
|
|
|
|
#endif |
6951
|
|
|
|
|
|
|
} |
6952
|
|
|
|
|
|
|
} |
6953
|
|
|
|
|
|
|
} |
6954
|
|
|
|
|
|
|
assert(!destructor || destructor == ((CV *)0)+1 |
6955
|
|
|
|
|
|
|
|| SvTYPE(destructor) == SVt_PVCV); |
6956
|
|
|
|
|
|
|
if (destructor && destructor != ((CV *)0)+1 |
6957
|
|
|
|
|
|
|
/* A constant subroutine can have no side effects, so |
6958
|
|
|
|
|
|
|
don't bother calling it. */ |
6959
|
|
|
|
|
|
|
&& !CvCONST(destructor) |
6960
|
|
|
|
|
|
|
/* Don't bother calling an empty destructor or one that |
6961
|
|
|
|
|
|
|
returns immediately. */ |
6962
|
|
|
|
|
|
|
&& (CvISXSUB(destructor) |
6963
|
|
|
|
|
|
|
|| (CvSTART(destructor) |
6964
|
|
|
|
|
|
|
&& (CvSTART(destructor)->op_next->op_type != OP_LEAVESUB) |
6965
|
|
|
|
|
|
|
&& (CvSTART(destructor)->op_next->op_type != OP_PUSHMARK |
6966
|
|
|
|
|
|
|
|| CvSTART(destructor)->op_next->op_next->op_type != OP_RETURN |
6967
|
|
|
|
|
|
|
) |
6968
|
|
|
|
|
|
|
)) |
6969
|
|
|
|
|
|
|
) |
6970
|
|
|
|
|
|
|
{ |
6971
|
|
|
|
|
|
|
SV* const tmpref = newRV(sv); |
6972
|
|
|
|
|
|
|
DEBUG_D(PerlIO_printf(Perl_debug_log, "Calling %s::DESTROY\n", HvNAME(stash))); |
6973
|
|
|
|
|
|
|
SvREADONLY_on(tmpref); /* DESTROY() could be naughty */ |
6974
|
|
|
|
|
|
|
ENTER; |
6975
|
|
|
|
|
|
|
PUSHSTACKi(PERLSI_DESTROY); |
6976
|
|
|
|
|
|
|
EXTEND(SP, 2); |
6977
|
|
|
|
|
|
|
PUSHMARK(SP); |
6978
|
|
|
|
|
|
|
PUSHs(tmpref); |
6979
|
|
|
|
|
|
|
PUTBACK; |
6980
|
|
|
|
|
|
|
call_sv((SV*)destructor, G_DISCARD|G_EVAL|G_KEEPERR|G_VOID); |
6981
|
|
|
|
|
|
|
POPSTACK; |
6982
|
|
|
|
|
|
|
SPAGAIN; |
6983
|
|
|
|
|
|
|
LEAVE; |
6984
|
|
|
|
|
|
|
if(SvREFCNT(tmpref) < 2) { |
6985
|
|
|
|
|
|
|
/* tmpref is not kept alive! */ |
6986
|
|
|
|
|
|
|
SvREFCNT(sv)--; |
6987
|
|
|
|
|
|
|
SvRV_set(tmpref, NULL); |
6988
|
|
|
|
|
|
|
SvROK_off(tmpref); |
6989
|
|
|
|
|
|
|
} |
6990
|
|
|
|
|
|
|
SvREFCNT_dec(tmpref); |
6991
|
|
|
|
|
|
|
} |
6992
|
|
|
|
|
|
|
} |
6993
|
|
|
|
|
|
|
} while (SvOBJECT(sv) && SvSTASH(sv) != stash); |
6994
|
|
|
|
|
|
|
|
6995
|
|
|
|
|
|
|
if (SvOBJECT(sv)) { |
6996
|
|
|
|
|
|
|
/* Curse before freeing the stash, as freeing the stash could cause |
6997
|
|
|
|
|
|
|
a recursive call into S_curse. */ |
6998
|
|
|
|
|
|
|
SvOBJECT_off(sv); /* Curse the object. */ |
6999
|
|
|
|
|
|
|
SvSTASH_set(sv,0); /* SvREFCNT_dec may try to read this */ |
7000
|
|
|
|
|
|
|
} |
7001
|
|
|
|
|
|
|
#endif |
7002
|
|
|
|
|
|
|
} |
7003
|
|
|
|
|
|
|
|
7004
|
|
|
|
|
|
|
static int fast_perl_destruct( PerlInterpreter *my_perl ) { |
7005
|
|
|
|
|
|
|
dVAR; |
7006
|
|
|
|
|
|
|
VOL signed char destruct_level; /* see possible values in intrpvar.h */ |
7007
|
|
|
|
|
|
|
HV *hv; |
7008
|
|
|
|
|
|
|
#ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP |
7009
|
|
|
|
|
|
|
pid_t child; |
7010
|
|
|
|
|
|
|
#endif |
7011
|
|
|
|
|
|
|
|
7012
|
|
|
|
|
|
|
#ifndef MULTIPLICITY |
7013
|
|
|
|
|
|
|
# ifndef PERL_UNUSED_ARG |
7014
|
|
|
|
|
|
|
# define PERL_UNUSED_ARG(x) ((void)x) |
7015
|
|
|
|
|
|
|
# endif |
7016
|
|
|
|
|
|
|
PERL_UNUSED_ARG(my_perl); |
7017
|
|
|
|
|
|
|
#endif |
7018
|
|
|
|
|
|
|
|
7019
|
|
|
|
|
|
|
assert(PL_scopestack_ix == 1); |
7020
|
|
|
|
|
|
|
|
7021
|
|
|
|
|
|
|
/* wait for all pseudo-forked children to finish */ |
7022
|
|
|
|
|
|
|
#if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24) |
7023
|
|
|
|
|
|
|
PERL_WAIT_FOR_CHILDREN; |
7024
|
|
|
|
|
|
|
#endif |
7025
|
|
|
|
|
|
|
|
7026
|
|
|
|
|
|
|
destruct_level = PL_perl_destruct_level; |
7027
|
|
|
|
|
|
|
#ifdef DEBUGGING |
7028
|
|
|
|
|
|
|
{ |
7029
|
|
|
|
|
|
|
const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL"); |
7030
|
|
|
|
|
|
|
if (s) { |
7031
|
|
|
|
|
|
|
const int i = atoi(s); |
7032
|
|
|
|
|
|
|
#ifdef DEBUGGING |
7033
|
|
|
|
|
|
|
if (destruct_level < i) destruct_level = i; |
7034
|
|
|
|
|
|
|
#endif |
7035
|
|
|
|
|
|
|
#ifdef PERL_TRACK_MEMPOOL |
7036
|
|
|
|
|
|
|
/* RT #114496, for perl_free */ |
7037
|
|
|
|
|
|
|
PL_perl_destruct_level = i; |
7038
|
|
|
|
|
|
|
#endif |
7039
|
|
|
|
|
|
|
} |
7040
|
|
|
|
|
|
|
} |
7041
|
|
|
|
|
|
|
#endif |
7042
|
|
|
|
|
|
|
|
7043
|
|
|
|
|
|
|
if (PL_exit_flags & PERL_EXIT_DESTRUCT_END) { |
7044
|
|
|
|
|
|
|
dJMPENV; |
7045
|
|
|
|
|
|
|
int x = 0; |
7046
|
|
|
|
|
|
|
|
7047
|
|
|
|
|
|
|
JMPENV_PUSH(x); |
7048
|
|
|
|
|
|
|
if (PL_endav && !PL_minus_c) { |
7049
|
|
|
|
|
|
|
#if PERL_VERSION > 13 |
7050
|
|
|
|
|
|
|
PL_phase = PERL_PHASE_END; |
7051
|
|
|
|
|
|
|
#endif |
7052
|
|
|
|
|
|
|
call_list(PL_scopestack_ix, PL_endav); |
7053
|
|
|
|
|
|
|
} |
7054
|
|
|
|
|
|
|
JMPENV_POP; |
7055
|
|
|
|
|
|
|
} |
7056
|
|
|
|
|
|
|
_EOT8 |
7057
|
|
|
|
|
|
|
|
7058
|
0
|
|
|
|
|
0
|
for (0 .. $#B::C::static_free) { |
7059
|
|
|
|
|
|
|
# set static op members to NULL |
7060
|
0
|
|
|
|
|
0
|
my $s = $B::C::static_free[$_]; |
7061
|
0
|
0
|
|
|
|
0
|
if ($s =~ /\(OP\*\)&unopaux_list/) { |
7062
|
0
|
|
|
|
|
0
|
print " ($s)->op_type = OP_NULL;\n"; |
7063
|
|
|
|
|
|
|
} |
7064
|
|
|
|
|
|
|
} |
7065
|
|
|
|
|
|
|
|
7066
|
0
|
|
|
|
|
0
|
print <<'_EOT9'; |
7067
|
|
|
|
|
|
|
LEAVE; |
7068
|
|
|
|
|
|
|
FREETMPS; |
7069
|
|
|
|
|
|
|
assert(PL_scopestack_ix == 0); |
7070
|
|
|
|
|
|
|
|
7071
|
|
|
|
|
|
|
/* Need to flush since END blocks can produce output */ |
7072
|
|
|
|
|
|
|
my_fflush_all(); |
7073
|
|
|
|
|
|
|
|
7074
|
|
|
|
|
|
|
PL_main_start = NULL; |
7075
|
|
|
|
|
|
|
PL_main_cv = NULL; |
7076
|
|
|
|
|
|
|
PL_curcop = &PL_compiling; |
7077
|
|
|
|
|
|
|
#if PERL_VERSION >= 13 |
7078
|
|
|
|
|
|
|
PL_phase = PERL_PHASE_DESTRUCT; |
7079
|
|
|
|
|
|
|
#endif |
7080
|
|
|
|
|
|
|
|
7081
|
|
|
|
|
|
|
#if PERL_VERSION > 7 |
7082
|
|
|
|
|
|
|
if (PL_threadhook(aTHX)) { |
7083
|
|
|
|
|
|
|
/* Threads hook has vetoed further cleanup */ |
7084
|
|
|
|
|
|
|
#if (PERL_VERSION > 8) || ((PERL_VERSION == 8) && (PERL_SUBVERSION > 8)) |
7085
|
|
|
|
|
|
|
PL_veto_cleanup = TRUE; |
7086
|
|
|
|
|
|
|
return STATUS_EXIT; |
7087
|
|
|
|
|
|
|
#else |
7088
|
|
|
|
|
|
|
return STATUS_NATIVE_EXPORT; |
7089
|
|
|
|
|
|
|
#endif |
7090
|
|
|
|
|
|
|
} |
7091
|
|
|
|
|
|
|
#if defined(PERLIO_LAYERS) |
7092
|
|
|
|
|
|
|
# if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24) |
7093
|
|
|
|
|
|
|
PerlIO_destruct(aTHX); |
7094
|
|
|
|
|
|
|
# endif |
7095
|
|
|
|
|
|
|
#endif |
7096
|
|
|
|
|
|
|
|
7097
|
|
|
|
|
|
|
/* B::C -O3 specific: first curse (i.e. call DESTROY) all our static SVs */ |
7098
|
|
|
|
|
|
|
if (PL_sv_objcount) { |
7099
|
|
|
|
|
|
|
int i = 1; |
7100
|
|
|
|
|
|
|
DEBUG_D(PerlIO_printf(Perl_debug_log, "\nCursing named global static sv_arena:\n")); |
7101
|
|
|
|
|
|
|
PL_in_clean_all = 1; |
7102
|
|
|
|
|
|
|
for (; i < SvREFCNT(&sv_list[0]); i++) { |
7103
|
|
|
|
|
|
|
SV *sv = &sv_list[i]; |
7104
|
|
|
|
|
|
|
if (SvREFCNT(sv)) { |
7105
|
|
|
|
|
|
|
#if PERL_VERSION > 11 |
7106
|
|
|
|
|
|
|
if (SvTYPE(sv) == SVt_IV && SvROK(sv)) |
7107
|
|
|
|
|
|
|
#else |
7108
|
|
|
|
|
|
|
if (SvTYPE(sv) == SVt_RV) |
7109
|
|
|
|
|
|
|
#endif |
7110
|
|
|
|
|
|
|
sv = SvRV(sv); |
7111
|
|
|
|
|
|
|
if (sv && SvOBJECT(sv) && SvTYPE(sv) >= SVt_PVMG && SvSTASH(sv) |
7112
|
|
|
|
|
|
|
&& SvTYPE(sv) != SVt_PVCV && SvTYPE(sv) != SVt_PVIO |
7113
|
|
|
|
|
|
|
&& PL_defstash /* Still have a symbol table? */ |
7114
|
|
|
|
|
|
|
&& SvDESTROYABLE(sv)) |
7115
|
|
|
|
|
|
|
{ |
7116
|
|
|
|
|
|
|
SvREFCNT(sv) = 0; |
7117
|
|
|
|
|
|
|
my_curse(aTHX_ sv); |
7118
|
|
|
|
|
|
|
} |
7119
|
|
|
|
|
|
|
} |
7120
|
|
|
|
|
|
|
} |
7121
|
|
|
|
|
|
|
} |
7122
|
|
|
|
|
|
|
if (DEBUG_D_TEST) { |
7123
|
|
|
|
|
|
|
SV* sva; |
7124
|
|
|
|
|
|
|
PerlIO_printf(Perl_debug_log, "\n"); |
7125
|
|
|
|
|
|
|
for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) { |
7126
|
|
|
|
|
|
|
PerlIO_printf(Perl_debug_log, "sv_arena: 0x%p - 0x%p (%lu)\n", |
7127
|
|
|
|
|
|
|
sva, sva+SvREFCNT(sva), (long)SvREFCNT(sva)); |
7128
|
|
|
|
|
|
|
} |
7129
|
|
|
|
|
|
|
} |
7130
|
|
|
|
|
|
|
#endif |
7131
|
|
|
|
|
|
|
|
7132
|
|
|
|
|
|
|
#if PERL_VERSION > 7 |
7133
|
|
|
|
|
|
|
PL_stashcache = (HV*)&PL_sv_undef; /* sometimes corrupted */ |
7134
|
|
|
|
|
|
|
#endif |
7135
|
|
|
|
|
|
|
#if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24) |
7136
|
|
|
|
|
|
|
if (PL_sv_objcount) { |
7137
|
|
|
|
|
|
|
# if PERL_VERSION > 7 |
7138
|
|
|
|
|
|
|
PL_stashcache = newHV(); /* Hack: sometimes corrupted, holding a GV */ |
7139
|
|
|
|
|
|
|
# endif |
7140
|
|
|
|
|
|
|
PL_in_clean_all = 1; |
7141
|
|
|
|
|
|
|
sv_clean_objs(); /* and now curse the rest */ |
7142
|
|
|
|
|
|
|
PL_sv_objcount = 0; |
7143
|
|
|
|
|
|
|
} |
7144
|
|
|
|
|
|
|
#endif |
7145
|
|
|
|
|
|
|
|
7146
|
|
|
|
|
|
|
PL_warnhook = NULL; |
7147
|
|
|
|
|
|
|
PL_diehook = NULL; |
7148
|
|
|
|
|
|
|
/* call exit list functions */ |
7149
|
|
|
|
|
|
|
while (PL_exitlistlen-- > 0) |
7150
|
|
|
|
|
|
|
PL_exitlist[PL_exitlistlen].fn(aTHX_ PL_exitlist[PL_exitlistlen].ptr); |
7151
|
|
|
|
|
|
|
PL_exitlist = NULL; |
7152
|
|
|
|
|
|
|
|
7153
|
|
|
|
|
|
|
#if defined(PERLIO_LAYERS) |
7154
|
|
|
|
|
|
|
# if !defined(WIN32) || (defined(USE_CPERL) && PERL_VERSION >= 24) |
7155
|
|
|
|
|
|
|
PerlIO_cleanup(aTHX); |
7156
|
|
|
|
|
|
|
# endif |
7157
|
|
|
|
|
|
|
#endif |
7158
|
|
|
|
|
|
|
|
7159
|
|
|
|
|
|
|
#if PERL_VERSION > 7 |
7160
|
|
|
|
|
|
|
PL_stashcache = (HV*)&PL_sv_undef; |
7161
|
|
|
|
|
|
|
#endif |
7162
|
|
|
|
|
|
|
/* Silence strtab refcnt warnings during global destruction */ |
7163
|
|
|
|
|
|
|
Zero(HvARRAY(PL_strtab), HvMAX(PL_strtab), HE*); |
7164
|
|
|
|
|
|
|
/* NULL the HEK "dfs" */ |
7165
|
|
|
|
|
|
|
#if PERL_VERSION > 10 |
7166
|
|
|
|
|
|
|
PL_registered_mros = (HV*)&PL_sv_undef; |
7167
|
|
|
|
|
|
|
CopHINTHASH_set(&PL_compiling, NULL); |
7168
|
|
|
|
|
|
|
#endif |
7169
|
|
|
|
|
|
|
|
7170
|
|
|
|
|
|
|
return 0; |
7171
|
|
|
|
|
|
|
} |
7172
|
|
|
|
|
|
|
_EOT9 |
7173
|
|
|
|
|
|
|
|
7174
|
|
|
|
|
|
|
} |
7175
|
|
|
|
|
|
|
# special COW handling for 5.10 because of S_unshare_hek_or_pvn limitations |
7176
|
|
|
|
|
|
|
# XXX This fails in S_doeval SAVEFREEOP(PL_eval_root): test 15 |
7177
|
|
|
|
|
|
|
# if ( $PERL510 and (@B::C::static_free or $free->index > -1)) |
7178
|
|
|
|
|
|
|
else { |
7179
|
0
|
|
|
|
|
0
|
print <<'_EOT7'; |
7180
|
|
|
|
|
|
|
int my_perl_destruct( PerlInterpreter *my_perl ) { |
7181
|
|
|
|
|
|
|
VOL signed char destruct_level = PL_perl_destruct_level; |
7182
|
|
|
|
|
|
|
const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL"); |
7183
|
|
|
|
|
|
|
|
7184
|
|
|
|
|
|
|
/* set all our static pv and hek to &PL_sv_undef for perl_destruct() */ |
7185
|
|
|
|
|
|
|
_EOT7 |
7186
|
|
|
|
|
|
|
|
7187
|
|
|
|
|
|
|
#for (0 .. $hek_index-1) { |
7188
|
|
|
|
|
|
|
# # TODO: non-static only, seperate data structures please |
7189
|
|
|
|
|
|
|
# printf " memset(HEK_HE(hek%d), 0, sizeof(struct shared_he));\n", $_; |
7190
|
|
|
|
|
|
|
#} |
7191
|
0
|
|
|
|
|
0
|
for (0 .. $#B::C::static_free) { |
7192
|
|
|
|
|
|
|
# set the sv/xpv to &PL_sv_undef, not the pv itself. |
7193
|
|
|
|
|
|
|
# If set to NULL pad_undef will fail in SvPVX_const(namesv) == '&' |
7194
|
|
|
|
|
|
|
# XXX Another idea >5.10 is SvFLAGS(pv) = SVTYPEMASK |
7195
|
0
|
|
|
|
|
0
|
my $s = $B::C::static_free[$_]; |
7196
|
0
|
0
|
|
|
|
0
|
if ($s =~ /^sv_list\[\d+\]\./) { # pv directly (unused) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
7197
|
0
|
|
|
|
|
0
|
print " $s = NULL;\n"; |
7198
|
|
|
|
|
|
|
} elsif ($s =~ /^sv_list/) { |
7199
|
0
|
|
|
|
|
0
|
print " SvLEN(&$s) = 0;\n"; |
7200
|
0
|
|
|
|
|
0
|
print " SvPV_set(&$s, (char*)&PL_sv_undef);\n"; |
7201
|
|
|
|
|
|
|
} elsif ($s =~ /^&sv_list/) { |
7202
|
0
|
|
|
|
|
0
|
print " SvLEN($s) = 0;\n"; |
7203
|
0
|
|
|
|
|
0
|
print " SvPV_set($s, (char*)&PL_sv_undef);\n"; |
7204
|
|
|
|
|
|
|
} elsif ($s =~ /^\(HV\*\)&sv_list/) { |
7205
|
0
|
|
|
|
|
0
|
print " SvREADONLY_on((SV*)$s);\n"; |
7206
|
0
|
|
|
|
|
0
|
print " SvREFCNT($s) = SvREFCNT_IMMORTAL;\n"; |
7207
|
|
|
|
|
|
|
} elsif ($s =~ /^\(AV\*\)&sv_list/) { # SVs_OBJECT flag, as the HV |
7208
|
|
|
|
|
|
|
#print " SvREADONLY_on((SV*)$s);\n"; |
7209
|
|
|
|
|
|
|
#print " SvREFCNT($s) = SvREFCNT_IMMORTAL;\n"; |
7210
|
|
|
|
|
|
|
} elsif ($s =~ /^&padnamelist_list/) { |
7211
|
0
|
|
|
|
|
0
|
print " Safefree(PadnamelistARRAY($s));\n"; |
7212
|
0
|
|
|
|
|
0
|
print " PadnamelistMAX($s) = 0;\n"; |
7213
|
0
|
|
|
|
|
0
|
print " PadnamelistREFCNT($s) = 0;\n"; |
7214
|
|
|
|
|
|
|
} elsif ($s =~ /^&padname(_\d+)?_list/) { |
7215
|
0
|
|
|
|
|
0
|
print " PadnameREFCNT($s) = 0;\n"; |
7216
|
|
|
|
|
|
|
# dead code --- |
7217
|
|
|
|
|
|
|
} elsif ($s =~ /^cop_list/) { |
7218
|
0
|
0
|
0
|
|
|
0
|
if ($ITHREADS or !$MULTI) { |
7219
|
0
|
|
|
|
|
0
|
print " CopFILE_set(&$s, NULL);"; |
7220
|
|
|
|
|
|
|
} |
7221
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.017) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
7222
|
0
|
|
|
|
|
0
|
print " CopSTASH_set(&$s, NULL);\n"; |
7223
|
|
|
|
|
|
|
} elsif ($] < 5.016 and $ITHREADS) { |
7224
|
0
|
|
|
|
|
0
|
print " CopSTASHPV(&$s) = NULL;\n"; |
7225
|
|
|
|
|
|
|
} elsif ($] < 5.016 and !$ITHREADS) { |
7226
|
0
|
|
|
|
|
0
|
print " CopSTASH(&$s) = NULL;\n"; |
7227
|
|
|
|
|
|
|
} else { # 5.16 experiment |
7228
|
0
|
|
|
|
|
0
|
print " CopSTASHPV_set(&$s, NULL, 0);\n"; |
7229
|
|
|
|
|
|
|
} |
7230
|
|
|
|
|
|
|
} elsif ($s =~ /\(OP\*\)&unopaux_list/) { |
7231
|
0
|
|
|
|
|
0
|
print " ($s)->op_type = OP_NULL;\n"; |
7232
|
|
|
|
|
|
|
# end dead code --- |
7233
|
|
|
|
|
|
|
#} elsif ($s =~ /^pv\d/) { |
7234
|
|
|
|
|
|
|
# print " $s = \"\";\n"; |
7235
|
|
|
|
|
|
|
} elsif ($s ne 'ptr_undef') { |
7236
|
0
|
|
|
|
|
0
|
warn("unknown $s at \@static_free[$_]"); |
7237
|
|
|
|
|
|
|
} |
7238
|
|
|
|
|
|
|
} |
7239
|
0
|
|
|
|
|
0
|
$free->output( \*STDOUT, "%s\n" ); |
7240
|
|
|
|
|
|
|
|
7241
|
0
|
|
|
|
|
0
|
my $riter_type = "I32"; |
7242
|
0
|
0
|
|
|
|
0
|
if ($CPERL51) { |
7243
|
0
|
0
|
|
|
|
0
|
$riter_type = $CPERL55 ? "U32" : "SSize_t"; |
7244
|
|
|
|
|
|
|
} |
7245
|
0
|
|
|
|
|
0
|
my $hvmax_type = "STRLEN"; |
7246
|
0
|
0
|
|
|
|
0
|
if ($CPERL51) { |
7247
|
0
|
0
|
|
|
|
0
|
$hvmax_type = $CPERL55 ? "U32" : "SSize_t"; |
7248
|
|
|
|
|
|
|
} |
7249
|
0
|
|
|
|
|
0
|
print "#define RITER_T $riter_type\n"; |
7250
|
0
|
|
|
|
|
0
|
print "#define HVMAX_T $hvmax_type\n"; |
7251
|
|
|
|
|
|
|
|
7252
|
0
|
|
|
|
|
0
|
print <<'_EOT7a'; |
7253
|
|
|
|
|
|
|
|
7254
|
|
|
|
|
|
|
/* Avoid Unbalanced string table refcount warning with PERL_DESTRUCT_LEVEL=2 */ |
7255
|
|
|
|
|
|
|
if (s) { |
7256
|
|
|
|
|
|
|
const int i = atoi(s); |
7257
|
|
|
|
|
|
|
if (destruct_level < i) destruct_level = i; |
7258
|
|
|
|
|
|
|
} |
7259
|
|
|
|
|
|
|
if (destruct_level >= 1) { |
7260
|
|
|
|
|
|
|
const HVMAX_T max = HvMAX(PL_strtab); |
7261
|
|
|
|
|
|
|
HE * const * const array = HvARRAY(PL_strtab); |
7262
|
|
|
|
|
|
|
RITER_T riter = 0; |
7263
|
|
|
|
|
|
|
HE *hent = array[0]; |
7264
|
|
|
|
|
|
|
for (;;) { |
7265
|
|
|
|
|
|
|
if (hent) { |
7266
|
|
|
|
|
|
|
HE * const next = HeNEXT(hent); |
7267
|
|
|
|
|
|
|
if (!HEK_STATIC(&((struct shared_he*)hent)->shared_he_hek)) |
7268
|
|
|
|
|
|
|
Safefree(hent); |
7269
|
|
|
|
|
|
|
hent = next; |
7270
|
|
|
|
|
|
|
} |
7271
|
|
|
|
|
|
|
if (!hent) { |
7272
|
|
|
|
|
|
|
if (++riter > max) |
7273
|
|
|
|
|
|
|
break; |
7274
|
|
|
|
|
|
|
hent = array[riter]; |
7275
|
|
|
|
|
|
|
} |
7276
|
|
|
|
|
|
|
} |
7277
|
|
|
|
|
|
|
/* Silence strtab refcnt warnings during global destruction */ |
7278
|
|
|
|
|
|
|
Zero(HvARRAY(PL_strtab), max, HE*); |
7279
|
|
|
|
|
|
|
/* NULL the HEK "dfs" */ |
7280
|
|
|
|
|
|
|
#if PERL_VERSION > 10 |
7281
|
|
|
|
|
|
|
PL_registered_mros = (HV*)&PL_sv_undef; |
7282
|
|
|
|
|
|
|
CopHINTHASH_set(&PL_compiling, NULL); |
7283
|
|
|
|
|
|
|
#endif |
7284
|
|
|
|
|
|
|
} |
7285
|
|
|
|
|
|
|
|
7286
|
|
|
|
|
|
|
/* B::C specific: prepend static svs to arena for sv_clean_objs */ |
7287
|
|
|
|
|
|
|
SvANY(&sv_list[0]) = (void *)PL_sv_arenaroot; |
7288
|
|
|
|
|
|
|
PL_sv_arenaroot = &sv_list[0]; |
7289
|
|
|
|
|
|
|
#if PERL_VERSION > 7 |
7290
|
|
|
|
|
|
|
if (DEBUG_D_TEST) { |
7291
|
|
|
|
|
|
|
SV* sva; |
7292
|
|
|
|
|
|
|
PerlIO_printf(Perl_debug_log, "\n"); |
7293
|
|
|
|
|
|
|
for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) { |
7294
|
|
|
|
|
|
|
PerlIO_printf(Perl_debug_log, "sv_arena: 0x%p - 0x%p (%lu)\n", |
7295
|
|
|
|
|
|
|
sva, sva+SvREFCNT(sva), (long)SvREFCNT(sva)); |
7296
|
|
|
|
|
|
|
} |
7297
|
|
|
|
|
|
|
} |
7298
|
|
|
|
|
|
|
|
7299
|
|
|
|
|
|
|
return perl_destruct( my_perl ); |
7300
|
|
|
|
|
|
|
#else |
7301
|
|
|
|
|
|
|
perl_destruct( my_perl ); |
7302
|
|
|
|
|
|
|
return 0; |
7303
|
|
|
|
|
|
|
#endif |
7304
|
|
|
|
|
|
|
} |
7305
|
|
|
|
|
|
|
_EOT7a |
7306
|
|
|
|
|
|
|
} |
7307
|
|
|
|
|
|
|
|
7308
|
0
|
|
|
|
|
0
|
print <<'_EOT8'; |
7309
|
|
|
|
|
|
|
|
7310
|
|
|
|
|
|
|
/* yanked from perl.c */ |
7311
|
|
|
|
|
|
|
static void |
7312
|
|
|
|
|
|
|
xs_init(pTHX) |
7313
|
|
|
|
|
|
|
{ |
7314
|
|
|
|
|
|
|
char *file = __FILE__; |
7315
|
|
|
|
|
|
|
dTARG; dSP; CV * cv; |
7316
|
|
|
|
|
|
|
_EOT8 |
7317
|
0
|
0
|
0
|
|
|
0
|
if ($CPERL51 and $debug{cv}) { |
7318
|
0
|
|
|
|
|
0
|
print q{ |
7319
|
|
|
|
|
|
|
/* -DC set dl_debug to 3 */ |
7320
|
|
|
|
|
|
|
SV* sv = get_svs("DynaLoader::dl_debug", GV_ADD); |
7321
|
|
|
|
|
|
|
sv_upgrade(sv, SVt_IV); |
7322
|
|
|
|
|
|
|
SvIV_set(sv, 3);}; |
7323
|
|
|
|
|
|
|
} |
7324
|
|
|
|
|
|
|
#if ($staticxs) { #FIXME! |
7325
|
|
|
|
|
|
|
# print "\n#undef USE_DYNAMIC_LOADING |
7326
|
|
|
|
|
|
|
#} |
7327
|
|
|
|
|
|
|
|
7328
|
0
|
|
|
|
|
0
|
delete $xsub{'DynaLoader'}; |
7329
|
0
|
|
|
|
|
0
|
delete $xsub{'UNIVERSAL'}; |
7330
|
0
|
|
|
|
|
0
|
print("/* XS bootstrapping code*/\n"); |
7331
|
0
|
|
|
|
|
0
|
print("\tSAVETMPS;\n"); |
7332
|
0
|
|
|
|
|
0
|
print("\ttarg=sv_newmortal();\n"); |
7333
|
0
|
|
|
|
|
0
|
foreach my $stashname ( sort keys %static_ext ) { |
7334
|
0
|
|
|
|
|
0
|
my $stashxsub = $stashname; |
7335
|
0
|
|
|
|
|
0
|
$stashxsub =~ s/::/__/g; |
7336
|
|
|
|
|
|
|
#if ($stashxsub =~ m/\/(\w+)\.\w+$/ {$stashxsub = $1;} |
7337
|
|
|
|
|
|
|
# cygwin has Win32CORE in static_ext |
7338
|
0
|
0
|
|
|
|
0
|
warn "bootstrapping static $stashname added to xs_init\n" if $verbose; |
7339
|
0
|
|
|
|
|
0
|
print "\tnewXS(\"$stashname\::bootstrap\", boot_$stashxsub, file);\n"; |
7340
|
|
|
|
|
|
|
} |
7341
|
0
|
|
|
|
|
0
|
print "#ifdef USE_DYNAMIC_LOADING\n"; |
7342
|
0
|
|
|
|
|
0
|
print "\tPUSHMARK(sp);\n"; |
7343
|
0
|
|
|
|
|
0
|
printf "\tXPUSHp(\"DynaLoader\", %d);\n", length("DynaLoader"); |
7344
|
0
|
|
|
|
|
0
|
print "\tPUTBACK;\n"; |
7345
|
0
|
0
|
|
|
|
0
|
warn "bootstrapping DynaLoader added to xs_init\n" if $verbose; |
7346
|
0
|
|
|
|
|
0
|
print "\tcv = newXS(\"DynaLoader::boot_DynaLoader\", boot_DynaLoader, file);\n"; |
7347
|
0
|
|
|
|
|
0
|
print "\tboot_DynaLoader(aTHX_ cv);\n"; |
7348
|
0
|
|
|
|
|
0
|
print "\tSPAGAIN;\n"; |
7349
|
0
|
0
|
0
|
|
|
0
|
if ($CPERL51 and $^O ne 'MSWin32') { |
7350
|
0
|
|
|
|
|
0
|
print "\tdl_boot(aTHX);\n"; |
7351
|
|
|
|
|
|
|
} |
7352
|
0
|
|
|
|
|
0
|
print "#endif\n"; |
7353
|
|
|
|
|
|
|
|
7354
|
|
|
|
|
|
|
# my %core = map{$_ => 1} core_packages(); |
7355
|
0
|
|
|
|
|
0
|
foreach my $stashname ( sort keys %xsub ) { |
7356
|
0
|
|
|
|
|
0
|
my $incpack = inc_packname($stashname); |
7357
|
0
|
0
|
|
|
|
0
|
unless (exists $curINC{$incpack}) { # skip deleted packages |
7358
|
0
|
0
|
|
|
|
0
|
warn "skip xs_init for $stashname !\$INC{$incpack}\n" if $debug{pkg}; |
7359
|
0
|
|
|
|
|
0
|
delete $include_package{$stashname}; |
7360
|
0
|
0
|
|
|
|
0
|
delete $xsub{$stashname} unless $static_ext{$stashname}; |
7361
|
0
|
|
|
|
|
0
|
next; |
7362
|
|
|
|
|
|
|
} |
7363
|
0
|
0
|
0
|
|
|
0
|
if ( $xsub{$stashname} !~ m/^Dynamic/ and !$static_ext{$stashname}) { |
7364
|
0
|
|
|
|
|
0
|
my $stashxsub = $stashname; |
7365
|
0
|
0
|
|
|
|
0
|
warn "bootstrapping $stashname added to xs_init\n" if $verbose; |
7366
|
0
|
|
|
|
|
0
|
$stashxsub =~ s/::/__/g; |
7367
|
0
|
|
|
|
|
0
|
print "\tPUSHMARK(sp);\n"; |
7368
|
0
|
|
|
|
|
0
|
printf "\tXPUSHp(\"%s\", %d);\n", # "::bootstrap" gets appended, TODO |
7369
|
|
|
|
|
|
|
0 ? "strdup($stashname)" : $stashname, length($stashname); |
7370
|
0
|
|
|
|
|
0
|
print "\tPUTBACK;\n"; |
7371
|
0
|
|
|
|
|
0
|
print "\tboot_$stashxsub(aTHX_ NULL);\n"; |
7372
|
0
|
|
|
|
|
0
|
print "\tSPAGAIN;\n"; |
7373
|
|
|
|
|
|
|
} |
7374
|
|
|
|
|
|
|
} |
7375
|
0
|
|
|
|
|
0
|
print "\tFREETMPS;\n/* end XS bootstrapping code */\n"; |
7376
|
0
|
|
|
|
|
0
|
print "}\n\n"; |
7377
|
|
|
|
|
|
|
|
7378
|
0
|
|
|
|
|
0
|
my ($dl, $xs); |
7379
|
0
|
|
|
|
|
0
|
my @dl_modules = @DynaLoader::dl_modules; |
7380
|
0
|
0
|
|
|
|
0
|
my @PERLMODS = split(/\,/, $ENV{'PERLMODS'}) if $ENV{'PERLMODS'}; # from cpanel |
7381
|
0
|
|
|
|
|
0
|
foreach my $perlmod (@PERLMODS) { |
7382
|
0
|
|
|
|
|
0
|
warn "Extra module ${perlmod}\n"; |
7383
|
0
|
0
|
|
|
|
0
|
push @dl_modules, $perlmod unless grep { $_ ne $perlmod } @dl_modules; |
|
0
|
|
|
|
|
0
|
|
7384
|
|
|
|
|
|
|
} |
7385
|
|
|
|
|
|
|
# filter out unused dynaloaded B modules, used within the compiler only. |
7386
|
0
|
|
|
|
|
0
|
for my $c (qw(B B::C)) { |
7387
|
0
|
0
|
0
|
|
|
0
|
if (!$xsub{$c} and !$include_package{$c}) { |
7388
|
|
|
|
|
|
|
# (hopefully, see test 103) |
7389
|
0
|
0
|
0
|
|
|
0
|
warn "no dl_init for $c, not marked\n" if $verbose and !$skip_package{$c}; |
7390
|
|
|
|
|
|
|
# RT81332 pollute |
7391
|
0
|
|
|
|
|
0
|
@dl_modules = grep { $_ ne $c } @dl_modules; |
|
0
|
|
|
|
|
0
|
|
7392
|
|
|
|
|
|
|
# XXX Be sure to store the new @dl_modules |
7393
|
|
|
|
|
|
|
} |
7394
|
|
|
|
|
|
|
} |
7395
|
0
|
|
|
|
|
0
|
for my $c (sort keys %skip_package) { |
7396
|
0
|
0
|
0
|
|
|
0
|
warn "no dl_init for $c, skipped\n" if $verbose and $xsub{$c}; |
7397
|
0
|
|
|
|
|
0
|
delete $xsub{$c}; |
7398
|
0
|
|
|
|
|
0
|
$include_package{$c} = undef; |
7399
|
0
|
|
|
|
|
0
|
@dl_modules = grep { $_ ne $c } @dl_modules; |
|
0
|
|
|
|
|
0
|
|
7400
|
|
|
|
|
|
|
} |
7401
|
0
|
|
|
|
|
0
|
@DynaLoader::dl_modules = @dl_modules; |
7402
|
0
|
0
|
|
|
|
0
|
warn "\@dl_modules: ",join(" ",@dl_modules),"\n" if $verbose; |
7403
|
0
|
|
|
|
|
0
|
foreach my $stashname (@dl_modules) { |
7404
|
0
|
|
|
|
|
0
|
my $incpack = inc_packname($stashname); |
7405
|
|
|
|
|
|
|
#unless (exists $INC{$incpack}) { # skip deleted packages |
7406
|
|
|
|
|
|
|
# warn "XXX skip dl_init for $stashname !\$INC{$incpack}\n" if $debug{pkg}; |
7407
|
|
|
|
|
|
|
# delete $xsub{$stashname}; |
7408
|
|
|
|
|
|
|
# @dl_modules = grep { $_ ne $stashname } @dl_modules; |
7409
|
|
|
|
|
|
|
#} |
7410
|
0
|
0
|
0
|
|
|
0
|
if ($stashname eq 'attributes' and $] > 5.011) { |
7411
|
0
|
|
|
|
|
0
|
$xsub{$stashname} = 'Dynamic-' . $INC{'attributes.pm'}; |
7412
|
|
|
|
|
|
|
} |
7413
|
|
|
|
|
|
|
# actually boot all non-b-c dependent modules here. we assume XSLoader (Moose, List::MoreUtils) |
7414
|
0
|
0
|
0
|
|
|
0
|
if (!exists( $xsub{$stashname} ) and $include_package{$stashname}) { |
7415
|
0
|
|
|
|
|
0
|
$xsub{$stashname} = 'Dynamic-' . $INC{$incpack}; |
7416
|
|
|
|
|
|
|
# Class::MOP without Moose: find Moose.pm |
7417
|
0
|
0
|
|
|
|
0
|
$xsub{$stashname} = 'Dynamic-' . $savINC{$incpack} unless $INC{$incpack}; |
7418
|
0
|
0
|
|
|
|
0
|
if (!$savINC{$incpack}) { |
7419
|
0
|
|
|
|
|
0
|
eval "require $stashname;"; |
7420
|
0
|
|
|
|
|
0
|
$xsub{$stashname} = 'Dynamic-' . $INC{$incpack}; |
7421
|
|
|
|
|
|
|
} |
7422
|
0
|
0
|
|
|
|
0
|
warn "Assuming xs loaded $stashname with $xsub{$stashname}\n" if $verbose; |
7423
|
|
|
|
|
|
|
} |
7424
|
0
|
0
|
0
|
|
|
0
|
if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic/ ) { |
7425
|
|
|
|
|
|
|
# XSLoader.pm: $modlibname = (caller())[1]; needs a path at caller[1] to find auto, |
7426
|
|
|
|
|
|
|
# otherwise we only have -e |
7427
|
0
|
0
|
|
|
|
0
|
$xs++ if $xsub{$stashname} ne 'Dynamic'; |
7428
|
0
|
|
|
|
|
0
|
$dl++; |
7429
|
|
|
|
|
|
|
} |
7430
|
0
|
|
|
|
|
0
|
my $stashxsub = $stashname; |
7431
|
0
|
|
|
|
|
0
|
$stashxsub =~ s/::/__/g; |
7432
|
0
|
0
|
0
|
|
|
0
|
if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic-/ |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
7433
|
|
|
|
|
|
|
and ($PERL522 or $staticxs)) { |
7434
|
0
|
|
|
|
|
0
|
print "EXTERN_C void boot_$stashxsub(pTHX_ CV* cv);\n"; |
7435
|
|
|
|
|
|
|
} |
7436
|
|
|
|
|
|
|
} |
7437
|
0
|
0
|
0
|
|
|
0
|
warn "\%xsub: ",join(" ",sort keys %xsub),"\n" if $verbose and $debug{cv}; |
7438
|
|
|
|
|
|
|
# XXX Adding DynaLoader is too late here! The sections like $init are already dumped (#125) |
7439
|
0
|
0
|
0
|
|
|
0
|
if ($dl and ! $curINC{'DynaLoader.pm'}) { |
|
|
0
|
0
|
|
|
|
|
7440
|
0
|
|
|
|
|
0
|
die "Error: DynaLoader required but not dumped. Too late to add it.\n"; |
7441
|
|
|
|
|
|
|
} elsif ($xs and ! $curINC{'XSLoader.pm'}) { |
7442
|
0
|
|
|
|
|
0
|
die "Error: XSLoader required but not dumped. Too late to add it.\n"; |
7443
|
|
|
|
|
|
|
} |
7444
|
0
|
|
|
|
|
0
|
print <<'_EOT9'; |
7445
|
|
|
|
|
|
|
|
7446
|
|
|
|
|
|
|
static void |
7447
|
|
|
|
|
|
|
dl_init(pTHX) |
7448
|
|
|
|
|
|
|
{ |
7449
|
|
|
|
|
|
|
char *file = __FILE__; |
7450
|
|
|
|
|
|
|
_EOT9 |
7451
|
|
|
|
|
|
|
|
7452
|
0
|
0
|
|
|
|
0
|
if ($dl) { |
7453
|
|
|
|
|
|
|
# enforce attributes at the front of dl_init, #259 |
7454
|
|
|
|
|
|
|
# also Encode should be booted before PerlIO::encoding |
7455
|
0
|
|
|
|
|
0
|
for my $front (qw(Encode attributes)) { |
7456
|
0
|
0
|
|
|
|
0
|
if (grep { $_ eq $front } @dl_modules) { |
|
0
|
|
|
|
|
0
|
|
7457
|
0
|
|
|
|
|
0
|
@dl_modules = grep { $_ ne $front } @dl_modules; |
|
0
|
|
|
|
|
0
|
|
7458
|
0
|
|
|
|
|
0
|
unshift @dl_modules, $front; |
7459
|
|
|
|
|
|
|
} |
7460
|
|
|
|
|
|
|
} |
7461
|
0
|
0
|
|
|
|
0
|
if ($staticxs) {open( XS, ">", $outfile.".lst" ) or return "$outfile.lst: $!\n"} |
|
0
|
0
|
|
|
|
0
|
|
7462
|
0
|
|
|
|
|
0
|
print "\tdTARG; dSP;\n"; |
7463
|
0
|
|
|
|
|
0
|
print "/* DynaLoader bootstrapping */\n"; |
7464
|
0
|
|
|
|
|
0
|
print "\tENTER;\n"; |
7465
|
0
|
0
|
|
|
|
0
|
print "\t++cxstack_ix; cxstack[cxstack_ix].blk_oldcop = PL_curcop;\n" if $xs; |
7466
|
0
|
0
|
|
|
|
0
|
print "\t/* assert(cxstack_ix == 0); */\n" if $xs; |
7467
|
0
|
|
|
|
|
0
|
print "\tSAVETMPS;\n"; |
7468
|
0
|
0
|
|
|
|
0
|
print "\ttarg = sv_newmortal();\n" if $] < 5.008008; |
7469
|
|
|
|
|
|
|
|
7470
|
0
|
0
|
0
|
|
|
0
|
if (exists $xsub{"Coro::State"} and grep { $_ eq "Coro::State" } @dl_modules) { |
|
0
|
|
|
|
|
0
|
|
7471
|
|
|
|
|
|
|
# Coro readonly symbols in BOOT (#293) |
7472
|
|
|
|
|
|
|
# needed before dl_init, and after init |
7473
|
0
|
|
|
|
|
0
|
print "\t{\n\t GV *sym;\n"; |
7474
|
0
|
|
|
|
|
0
|
for my $s (qw(Coro Coro::API Coro::current)) { |
7475
|
0
|
|
|
|
|
0
|
print "\t sym = gv_fetchpv(\"$s\",0,SVt_PV);\n"; |
7476
|
0
|
|
|
|
|
0
|
print "\t if (sym && GvSVn(sym)) SvREADONLY_off(GvSVn(sym));\n"; |
7477
|
|
|
|
|
|
|
} |
7478
|
0
|
|
|
|
|
0
|
print "\t sym = gv_fetchpv(\"Coro::pool_handler)\",0,SVt_PVCV);\n"; |
7479
|
0
|
|
|
|
|
0
|
print "\t if (sym && GvCV(sym)) SvREADONLY_off(GvCV(sym));\n"; |
7480
|
0
|
|
|
|
|
0
|
print "\t}\n"; |
7481
|
|
|
|
|
|
|
} |
7482
|
0
|
0
|
0
|
|
|
0
|
if (exists $xsub{"EV"} and grep { $_ eq "EV" } @dl_modules) { |
|
0
|
|
|
|
|
0
|
|
7483
|
|
|
|
|
|
|
# EV readonly symbols in BOOT (#368) |
7484
|
0
|
|
|
|
|
0
|
print "\t{\n\t GV *sym;\n"; |
7485
|
0
|
|
|
|
|
0
|
for my $s (qw(EV::API)) { |
7486
|
0
|
|
|
|
|
0
|
print "\t sym = gv_fetchpv(\"$s\",0,SVt_PV);\n"; |
7487
|
0
|
|
|
|
|
0
|
print "\t if (sym && GvSVn(sym)) SvREADONLY_off(GvSVn(sym));\n"; |
7488
|
|
|
|
|
|
|
} |
7489
|
0
|
|
|
|
|
0
|
print "\t}\n"; |
7490
|
|
|
|
|
|
|
} |
7491
|
0
|
|
|
|
|
0
|
foreach my $stashname (@dl_modules) { |
7492
|
0
|
0
|
0
|
|
|
0
|
if ( exists( $xsub{$stashname} ) && $xsub{$stashname} =~ m/^Dynamic/ ) { |
7493
|
0
|
|
|
|
|
0
|
$use_xsloader = 1; |
7494
|
0
|
|
|
|
|
0
|
print "\n\tPUSHMARK(sp);\n"; |
7495
|
|
|
|
|
|
|
# XXX -O1 or -O2 needs XPUSHs with dynamic pv |
7496
|
0
|
0
|
|
|
|
0
|
printf "\t%s(%s, %d);\n", # "::bootstrap" gets appended |
7497
|
|
|
|
|
|
|
$] < 5.008008 ? "XPUSHp" : "mXPUSHp", "\"$stashname\"", length($stashname); |
7498
|
0
|
0
|
|
|
|
0
|
if ( $xsub{$stashname} eq 'Dynamic' ) { |
7499
|
55
|
|
|
55
|
|
408
|
no strict 'refs'; |
|
55
|
|
|
|
|
84
|
|
|
55
|
|
|
|
|
20154
|
|
7500
|
0
|
0
|
|
|
|
0
|
warn "dl_init $stashname\n" if $verbose; |
7501
|
|
|
|
|
|
|
# just in case we missed it. DynaLoader really needs the @ISA (#308) |
7502
|
0
|
|
|
|
|
0
|
B::svref_2object( \@{$stashname."::ISA"} ) ->save; |
|
0
|
|
|
|
|
0
|
|
7503
|
0
|
|
|
|
|
0
|
print "#ifndef STATICXS\n"; |
7504
|
0
|
|
|
|
|
0
|
print "\tPUTBACK;\n"; |
7505
|
0
|
|
|
|
|
0
|
print qq/\tcall_method("DynaLoader::bootstrap_inherit", G_VOID|G_DISCARD);\n/; |
7506
|
|
|
|
|
|
|
} |
7507
|
|
|
|
|
|
|
else { # XS: need to fix cx for caller[1] to find auto/... |
7508
|
0
|
|
|
|
|
0
|
my ($stashfile) = $xsub{$stashname} =~ /^Dynamic-(.+)$/; |
7509
|
0
|
|
|
|
|
0
|
print "#ifndef STATICXS\n"; |
7510
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.015003 and $stashfile) { |
7511
|
0
|
0
|
|
|
|
0
|
if ($CPERL51) { |
7512
|
0
|
|
|
|
|
0
|
my $sofile; |
7513
|
|
|
|
|
|
|
# search stashname in loaded sofiles |
7514
|
0
|
|
|
|
|
0
|
my @modparts = split(/::/,$stashname); |
7515
|
0
|
|
|
|
|
0
|
my $modfname = $modparts[-1]; |
7516
|
0
|
|
|
|
|
0
|
my $modpname = join('/',@modparts); |
7517
|
0
|
|
|
|
|
0
|
my $needle = "auto/$modpname/$modfname\\.".$Config{dlext}; |
7518
|
|
|
|
|
|
|
#warn " load_file: @DynaLoader::dl_shared_objects"; |
7519
|
|
|
|
|
|
|
#warn " sofile?: $needle"; |
7520
|
0
|
|
|
|
|
0
|
for (@DynaLoader::dl_shared_objects) { |
7521
|
0
|
0
|
|
|
|
0
|
if (m{$needle}) { |
7522
|
|
|
|
|
|
|
#warn " load_file: found $_"; |
7523
|
0
|
|
|
|
|
0
|
$sofile = $_; last; |
|
0
|
|
|
|
|
0
|
|
7524
|
|
|
|
|
|
|
} |
7525
|
|
|
|
|
|
|
} |
7526
|
0
|
0
|
|
|
|
0
|
unless ($sofile) { |
7527
|
0
|
|
|
|
|
0
|
my $modlibname = $stashfile; |
7528
|
0
|
|
|
|
|
0
|
my $c = scalar @modparts; |
7529
|
0
|
0
|
0
|
|
|
0
|
if ($stashname eq 'Cwd' and $stashfile !~ /Cwd/) { |
7530
|
0
|
|
|
|
|
0
|
warn "load_file: fixup Cwd vs $stashfile"; |
7531
|
0
|
|
|
|
|
0
|
$c = 3; |
7532
|
|
|
|
|
|
|
} |
7533
|
0
|
|
|
|
|
0
|
$modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename |
7534
|
0
|
|
|
|
|
0
|
$sofile = "$modlibname/auto/$modpname/$modfname.".$Config{dlext}; |
7535
|
|
|
|
|
|
|
} |
7536
|
|
|
|
|
|
|
#warn "load_file: $stashname, $stashfile, $sofile"; |
7537
|
0
|
|
|
|
|
0
|
$stashfile = $sofile; |
7538
|
|
|
|
|
|
|
} |
7539
|
0
|
|
|
|
|
0
|
my $stashfile_len = length($stashfile); |
7540
|
0
|
|
|
|
|
0
|
$stashfile =~ s/(\\[^nrftacx"' ])/\\$1/g; # windows paths: \\ => \\\\ |
7541
|
0
|
|
|
|
|
0
|
printf "\tmXPUSHp(\"%s\", %d);\n", $stashfile, $stashfile_len; |
7542
|
|
|
|
|
|
|
} |
7543
|
0
|
|
|
|
|
0
|
print "\tPUTBACK;\n"; |
7544
|
0
|
0
|
|
|
|
0
|
warn "bootstrapping $stashname added to XSLoader dl_init\n" if $verbose; |
7545
|
|
|
|
|
|
|
# XSLoader has the 2nd insanest API in whole Perl, right after make_warnings_object() |
7546
|
|
|
|
|
|
|
# 5.15.3 workaround for [perl #101336] |
7547
|
0
|
0
|
|
|
|
0
|
if ($] >= 5.015003) { |
7548
|
55
|
|
|
55
|
|
258
|
no strict 'refs'; |
|
55
|
|
|
|
|
81
|
|
|
55
|
|
|
|
|
64685
|
|
7549
|
0
|
0
|
|
|
|
0
|
unless (grep /^DynaLoader$/, get_isa($stashname)) { |
7550
|
0
|
|
|
|
|
0
|
push @{$stashname."::ISA"}, 'DynaLoader'; |
|
0
|
|
|
|
|
0
|
|
7551
|
0
|
|
|
|
|
0
|
svref_2object( \@{$stashname."::ISA"} ) ->save; |
|
0
|
|
|
|
|
0
|
|
7552
|
|
|
|
|
|
|
} |
7553
|
0
|
0
|
|
|
|
0
|
warn '@',$stashname,"::ISA=(",join(",",@{$stashname."::ISA"}),")\n" if $debug{gv}; |
|
0
|
|
|
|
|
0
|
|
7554
|
|
|
|
|
|
|
# TODO #364: if a VERSION was provided need to add it here |
7555
|
0
|
|
|
|
|
0
|
print qq/\tcall_pv("XSLoader::load_file", G_VOID|G_DISCARD);\n/; |
7556
|
|
|
|
|
|
|
} else { |
7557
|
0
|
0
|
|
|
|
0
|
printf qq/\tCopFILE_set(cxstack[cxstack_ix].blk_oldcop, "%s");\n/, |
7558
|
|
|
|
|
|
|
$stashfile if $stashfile; |
7559
|
|
|
|
|
|
|
# TODO #364: if a VERSION was provided need to add it here |
7560
|
0
|
|
|
|
|
0
|
print qq/\tcall_pv("XSLoader::load", G_VOID|G_DISCARD);\n/; |
7561
|
|
|
|
|
|
|
} |
7562
|
|
|
|
|
|
|
} |
7563
|
0
|
0
|
|
|
|
0
|
if ($staticxs) { |
7564
|
0
|
|
|
|
|
0
|
my ($laststash) = $stashname =~ /::([^:]+)$/; |
7565
|
0
|
|
|
|
|
0
|
my $path = $stashname; |
7566
|
0
|
|
|
|
|
0
|
$path =~ s/::/\//g; |
7567
|
0
|
0
|
|
|
|
0
|
$path .= "/" if $path; # can be empty |
7568
|
0
|
0
|
|
|
|
0
|
$laststash = $stashname unless $laststash; # without :: |
7569
|
0
|
|
|
|
|
0
|
my $sofile = "auto/" . $path . $laststash . '\.' . $Config{dlext}; |
7570
|
|
|
|
|
|
|
#warn "staticxs search $sofile in @DynaLoader::dl_shared_objects\n" |
7571
|
|
|
|
|
|
|
# if $verbose and $debug{pkg}; |
7572
|
0
|
|
|
|
|
0
|
for (@DynaLoader::dl_shared_objects) { |
7573
|
0
|
0
|
|
|
|
0
|
if (m{^(.+/)$sofile$}) { |
7574
|
0
|
|
|
|
|
0
|
print XS $stashname,"\t",$_,"\n"; |
7575
|
0
|
0
|
|
|
|
0
|
warn "staticxs $stashname\t$_\n" if $verbose; |
7576
|
0
|
|
|
|
|
0
|
$sofile = ''; |
7577
|
0
|
|
|
|
|
0
|
last; |
7578
|
|
|
|
|
|
|
} |
7579
|
|
|
|
|
|
|
} |
7580
|
0
|
0
|
|
|
|
0
|
print XS $stashname,"\n" if $sofile; # error case |
7581
|
0
|
0
|
0
|
|
|
0
|
warn "staticxs $stashname\t - $sofile not loaded\n" if $sofile and $verbose; |
7582
|
|
|
|
|
|
|
} |
7583
|
0
|
|
|
|
|
0
|
print "#else\n"; |
7584
|
0
|
|
|
|
|
0
|
print "\tPUTBACK;\n"; |
7585
|
0
|
|
|
|
|
0
|
my $stashxsub = $stashname; |
7586
|
0
|
|
|
|
|
0
|
$stashxsub =~ s/::/__/g; |
7587
|
0
|
0
|
0
|
|
|
0
|
if ($PERL522 or $staticxs) { |
7588
|
|
|
|
|
|
|
# CvSTASH(CvGV(cv)) is invalid without (issue 86) |
7589
|
|
|
|
|
|
|
# TODO: utf8 stashname (does make sense when loading from the fs?) |
7590
|
0
|
0
|
0
|
|
|
0
|
if ($PERL522 and $staticxs) { # GH 333 |
7591
|
0
|
|
|
|
|
0
|
print "\t{ |
7592
|
|
|
|
|
|
|
CV* cv = (CV*)SvREFCNT_inc_simple_NN(get_cv(\"$stashname\::bootstrap\", GV_ADD)); |
7593
|
|
|
|
|
|
|
CvISXSUB_on(cv); /* otherwise a perl assertion fails. */ |
7594
|
|
|
|
|
|
|
cv->sv_any->xcv_padlist_u.xcv_hscxt = &PL_stack_sp; /* xs_handshake */ |
7595
|
|
|
|
|
|
|
boot_$stashxsub(aTHX_ cv); |
7596
|
|
|
|
|
|
|
}\n"; |
7597
|
|
|
|
|
|
|
} else { |
7598
|
0
|
|
|
|
|
0
|
print "\tboot_$stashxsub(aTHX_ get_cv(\"$stashname\::bootstrap\", GV_ADD));\n"; |
7599
|
|
|
|
|
|
|
} |
7600
|
|
|
|
|
|
|
} else { |
7601
|
0
|
|
|
|
|
0
|
print "\tboot_$stashxsub(aTHX_ NULL);\n"; |
7602
|
|
|
|
|
|
|
} |
7603
|
0
|
|
|
|
|
0
|
print "#endif\n"; |
7604
|
0
|
|
|
|
|
0
|
print "\tSPAGAIN;\n"; |
7605
|
|
|
|
|
|
|
#print "\tPUTBACK;\n"; |
7606
|
|
|
|
|
|
|
} else { |
7607
|
|
|
|
|
|
|
warn "no dl_init for $stashname, ". |
7608
|
0
|
0
|
|
|
|
0
|
(!$xsub{$stashname} ? "not bootstrapped\n" : "bootstrapped as $xsub{$stashname}\n") |
|
|
0
|
|
|
|
|
|
7609
|
|
|
|
|
|
|
if $verbose; |
7610
|
|
|
|
|
|
|
# XXX Too late. This might fool run-time DynaLoading. |
7611
|
|
|
|
|
|
|
# We really should remove this via init from @DynaLoader::dl_modules |
7612
|
0
|
|
|
|
|
0
|
@DynaLoader::dl_modules = grep { $_ ne $stashname } @DynaLoader::dl_modules; |
|
0
|
|
|
|
|
0
|
|
7613
|
|
|
|
|
|
|
|
7614
|
|
|
|
|
|
|
} |
7615
|
|
|
|
|
|
|
} |
7616
|
0
|
|
|
|
|
0
|
print "\tFREETMPS;\n"; |
7617
|
0
|
0
|
|
|
|
0
|
print "\tcxstack_ix--;\n" if $xs; # i.e. POPBLOCK |
7618
|
0
|
|
|
|
|
0
|
print "\tLEAVE;\n"; |
7619
|
0
|
|
|
|
|
0
|
print "/* end DynaLoader bootstrapping */\n"; |
7620
|
0
|
0
|
|
|
|
0
|
close XS if $staticxs; |
7621
|
|
|
|
|
|
|
} |
7622
|
0
|
|
|
|
|
0
|
print "}\n"; |
7623
|
|
|
|
|
|
|
} |
7624
|
|
|
|
|
|
|
|
7625
|
|
|
|
|
|
|
sub output_main { |
7626
|
0
|
0
|
|
0
|
0
|
0
|
if (!defined($module)) { |
7627
|
0
|
|
|
|
|
0
|
print <<'_EOT10'; |
7628
|
|
|
|
|
|
|
|
7629
|
|
|
|
|
|
|
/* if USE_IMPLICIT_SYS, we need a 'real' exit */ |
7630
|
|
|
|
|
|
|
#if defined(exit) |
7631
|
|
|
|
|
|
|
#undef exit |
7632
|
|
|
|
|
|
|
#endif |
7633
|
|
|
|
|
|
|
|
7634
|
|
|
|
|
|
|
int |
7635
|
|
|
|
|
|
|
main(int argc, char **argv, char **env) |
7636
|
|
|
|
|
|
|
{ |
7637
|
|
|
|
|
|
|
int exitstatus; |
7638
|
|
|
|
|
|
|
int i; |
7639
|
|
|
|
|
|
|
char **fakeargv; |
7640
|
|
|
|
|
|
|
int options_count; |
7641
|
|
|
|
|
|
|
PerlInterpreter *my_perl; |
7642
|
|
|
|
|
|
|
|
7643
|
|
|
|
|
|
|
PERL_SYS_INIT3(&argc,&argv,&env); |
7644
|
|
|
|
|
|
|
|
7645
|
|
|
|
|
|
|
#ifdef WIN32 |
7646
|
|
|
|
|
|
|
#define PL_do_undump 0 |
7647
|
|
|
|
|
|
|
#endif |
7648
|
|
|
|
|
|
|
if (!PL_do_undump) { |
7649
|
|
|
|
|
|
|
my_perl = perl_alloc(); |
7650
|
|
|
|
|
|
|
if (!my_perl) |
7651
|
|
|
|
|
|
|
exit(1); |
7652
|
|
|
|
|
|
|
perl_construct( my_perl ); |
7653
|
|
|
|
|
|
|
PL_perl_destruct_level = 0; |
7654
|
|
|
|
|
|
|
} |
7655
|
|
|
|
|
|
|
_EOT10 |
7656
|
0
|
0
|
0
|
|
|
0
|
if ($ITHREADS and $] > 5.007) { |
7657
|
|
|
|
|
|
|
# XXX init free elems! |
7658
|
0
|
|
|
|
|
0
|
my $pad_len = regex_padav->FILL; # first is an empty avref |
7659
|
0
|
|
|
|
|
0
|
print <<_EOT11; |
7660
|
|
|
|
|
|
|
#ifdef USE_ITHREADS |
7661
|
|
|
|
|
|
|
if (!*PL_regex_pad) { |
7662
|
|
|
|
|
|
|
/* Someone is overwriting regex_pad since 5.15, but not on -fno-warnings */ |
7663
|
|
|
|
|
|
|
PL_regex_padav = newAV(); |
7664
|
|
|
|
|
|
|
#if PERL_VERSION > 10 |
7665
|
|
|
|
|
|
|
av_push(PL_regex_padav, newSVpvs("")); /* First entry is empty */ |
7666
|
|
|
|
|
|
|
#else |
7667
|
|
|
|
|
|
|
av_push(PL_regex_padav, newSViv(0)); |
7668
|
|
|
|
|
|
|
#endif |
7669
|
|
|
|
|
|
|
PL_regex_pad = AvARRAY(PL_regex_padav); |
7670
|
|
|
|
|
|
|
} |
7671
|
|
|
|
|
|
|
for( i = 0; i < $pad_len; ++i ) { |
7672
|
|
|
|
|
|
|
av_push( PL_regex_padav, newSViv(0) ); |
7673
|
|
|
|
|
|
|
} |
7674
|
|
|
|
|
|
|
PL_regex_pad = AvARRAY( PL_regex_padav ); |
7675
|
|
|
|
|
|
|
#endif |
7676
|
|
|
|
|
|
|
_EOT11 |
7677
|
|
|
|
|
|
|
|
7678
|
|
|
|
|
|
|
} |
7679
|
0
|
0
|
|
|
|
0
|
print " PL_exit_flags |= PERL_EXIT_DESTRUCT_END;\n" unless $PERL56; |
7680
|
0
|
0
|
|
|
|
0
|
if ($] >= 5.008009) { |
7681
|
0
|
|
|
|
|
0
|
print <<'_SAFE_PUTENV'; |
7682
|
|
|
|
|
|
|
#ifndef PERL_USE_SAFE_PUTENV |
7683
|
|
|
|
|
|
|
PL_use_safe_putenv = 0; |
7684
|
|
|
|
|
|
|
#endif |
7685
|
|
|
|
|
|
|
_SAFE_PUTENV |
7686
|
|
|
|
|
|
|
} |
7687
|
0
|
0
|
|
|
|
0
|
if (!$PERL510) { |
7688
|
0
|
|
|
|
|
0
|
print <<'_EOT12'; |
7689
|
|
|
|
|
|
|
#if defined(CSH) |
7690
|
|
|
|
|
|
|
if (!PL_cshlen) |
7691
|
|
|
|
|
|
|
PL_cshlen = strlen(PL_cshname); |
7692
|
|
|
|
|
|
|
#endif |
7693
|
|
|
|
|
|
|
_EOT12 |
7694
|
|
|
|
|
|
|
} |
7695
|
|
|
|
|
|
|
|
7696
|
|
|
|
|
|
|
# XXX With -e "" we need to fake parse_body() scriptname = BIT_BUCKET |
7697
|
0
|
|
|
|
|
0
|
print <<'_EOT13'; |
7698
|
|
|
|
|
|
|
#ifdef ALLOW_PERL_OPTIONS |
7699
|
|
|
|
|
|
|
#define EXTRA_OPTIONS 3 |
7700
|
|
|
|
|
|
|
#else |
7701
|
|
|
|
|
|
|
#define EXTRA_OPTIONS 4 |
7702
|
|
|
|
|
|
|
#endif /* ALLOW_PERL_OPTIONS */ |
7703
|
|
|
|
|
|
|
Newx(fakeargv, argc + EXTRA_OPTIONS + 1, char *); |
7704
|
|
|
|
|
|
|
fakeargv[0] = argv[0]; |
7705
|
|
|
|
|
|
|
fakeargv[1] = "-e"; |
7706
|
|
|
|
|
|
|
fakeargv[2] = ""; |
7707
|
|
|
|
|
|
|
options_count = 3; |
7708
|
|
|
|
|
|
|
_EOT13 |
7709
|
|
|
|
|
|
|
|
7710
|
|
|
|
|
|
|
# honour -T |
7711
|
0
|
0
|
0
|
|
|
0
|
if (!$PERL56 and ${^TAINT}) { |
7712
|
0
|
|
|
|
|
0
|
print <<'_EOT14'; |
7713
|
|
|
|
|
|
|
fakeargv[options_count] = "-T"; |
7714
|
|
|
|
|
|
|
++options_count; |
7715
|
|
|
|
|
|
|
_EOT14 |
7716
|
|
|
|
|
|
|
|
7717
|
|
|
|
|
|
|
} |
7718
|
0
|
|
|
|
|
0
|
print <<'_EOT15'; |
7719
|
|
|
|
|
|
|
#ifndef ALLOW_PERL_OPTIONS |
7720
|
|
|
|
|
|
|
fakeargv[options_count] = "--"; |
7721
|
|
|
|
|
|
|
++options_count; |
7722
|
|
|
|
|
|
|
#endif /* ALLOW_PERL_OPTIONS */ |
7723
|
|
|
|
|
|
|
for (i = 1; i < argc; i++) |
7724
|
|
|
|
|
|
|
fakeargv[i + options_count - 1] = argv[i]; |
7725
|
|
|
|
|
|
|
fakeargv[argc + options_count - 1] = 0; |
7726
|
|
|
|
|
|
|
|
7727
|
|
|
|
|
|
|
exitstatus = perl_parse(my_perl, xs_init, argc + options_count - 1, |
7728
|
|
|
|
|
|
|
fakeargv, env); |
7729
|
|
|
|
|
|
|
if (exitstatus) |
7730
|
|
|
|
|
|
|
exit( exitstatus ); |
7731
|
|
|
|
|
|
|
|
7732
|
|
|
|
|
|
|
TAINT; |
7733
|
|
|
|
|
|
|
_EOT15 |
7734
|
|
|
|
|
|
|
|
7735
|
0
|
0
|
|
|
|
0
|
if ($use_perl_script_name) { |
7736
|
0
|
|
|
|
|
0
|
my $dollar_0 = cstring($0); |
7737
|
0
|
|
|
|
|
0
|
print sprintf(qq{ sv_setpv_mg(get_svs("0", GV_ADD|GV_NOTQUAL), %s);\n}, $dollar_0); |
7738
|
0
|
|
|
|
|
0
|
print sprintf(qq{ CopFILE_set(&PL_compiling, %s);\n}, $dollar_0); |
7739
|
|
|
|
|
|
|
} |
7740
|
|
|
|
|
|
|
else { |
7741
|
|
|
|
|
|
|
#print q{ warn("PL_origalen=%d\n", PL_origalen);},"\n"; |
7742
|
0
|
|
|
|
|
0
|
print qq{ sv_setpv_mg(get_svs("0", GV_ADD|GV_NOTQUAL), argv[0]);\n}; |
7743
|
0
|
|
|
|
|
0
|
print qq{ CopFILE_set(&PL_compiling, argv[0]);\n}; |
7744
|
|
|
|
|
|
|
} |
7745
|
|
|
|
|
|
|
# more global vars |
7746
|
0
|
0
|
|
|
|
0
|
print " PL_hints = $^H;\n" if $^H; |
7747
|
0
|
0
|
|
|
|
0
|
print " PL_unicode = ${^UNICODE};\n" if ${^UNICODE}; |
7748
|
|
|
|
|
|
|
# system-specific needs to be skipped: is set during init_i18nl10n if PerlIO |
7749
|
|
|
|
|
|
|
# is compiled in and on a utf8 locale. |
7750
|
|
|
|
|
|
|
#print " PL_utf8locale = ${^UTF8LOCALE};\n" if ${^UTF8LOCALE}; |
7751
|
|
|
|
|
|
|
#print " PL_utf8cache = ${^UTF8CACHE};\n" if ${^UTF8CACHE}; |
7752
|
|
|
|
|
|
|
# nomg |
7753
|
0
|
0
|
|
|
|
0
|
print sprintf(qq{ sv_setpv(get_svs(";", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($;)) if $; ne "\34"; |
7754
|
0
|
0
|
|
|
|
0
|
print sprintf(qq{ sv_setpv(get_svs("\\"", GV_NOTQUAL), %s); /* \$" */\n}, cstring($")) if $" ne " "; |
7755
|
|
|
|
|
|
|
# global IO vars |
7756
|
0
|
0
|
|
|
|
0
|
if ($PERL56) { |
7757
|
0
|
0
|
|
|
|
0
|
print sprintf(qq{ PL_ofs = %s; PL_ofslen = %u; /* \$, */\n}, cstring($,), length $,) if $,; |
7758
|
0
|
0
|
|
|
|
0
|
print sprintf(qq{ PL_ors = %s; PL_orslen = %u; /* \$\\ */\n}, cstring($\), length $\) if $\; |
7759
|
|
|
|
|
|
|
} else { |
7760
|
0
|
0
|
|
|
|
0
|
print sprintf(qq{ sv_setpv_mg(GvSVn(PL_ofsgv), %s); /* \$, */\n}, cstring($,)) if $,; |
7761
|
0
|
0
|
|
|
|
0
|
print sprintf(qq{ sv_setpv_mg(get_svs("\\\\", GV_ADD|GV_NOTQUAL), %s); /* \$\\ */\n}, cstring($\)) if $\; #ORS |
7762
|
|
|
|
|
|
|
} |
7763
|
0
|
0
|
|
|
|
0
|
print sprintf(qq{ sv_setpv_mg(get_svs("/", GV_NOTQUAL), %s);\n}, cstring($/)) if $/ ne "\n"; #RS |
7764
|
0
|
0
|
|
|
|
0
|
print qq{ sv_setiv_mg(get_svs("|", GV_ADD|GV_NOTQUAL), $|);\n} if $|; #OUTPUT_AUTOFLUSH |
7765
|
|
|
|
|
|
|
# global format vars |
7766
|
0
|
0
|
|
|
|
0
|
print sprintf(qq{ sv_setpv_mg(get_svs("^A", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($^A)) if $^A; #ACCUMULATOR |
7767
|
0
|
0
|
|
|
|
0
|
print sprintf(qq{ sv_setpv_mg(get_svs("^L", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($^L)) if $^L ne "\f"; #FORMFEED |
7768
|
0
|
0
|
|
|
|
0
|
print sprintf(qq{ sv_setpv_mg(get_svs(":", GV_ADD|GV_NOTQUAL), %s);\n}, cstring($:)) if $: ne " \n-"; #LINE_BREAK_CHARACTERS |
7769
|
0
|
0
|
|
|
|
0
|
print sprintf(qq/ sv_setpv_mg(get_svs("^", GV_ADD|GV_NOTQUAL), savepvn(%s, %u));\n/, cstring($^), length($^)) |
7770
|
|
|
|
|
|
|
if $^ ne "STDOUT_TOP"; |
7771
|
0
|
0
|
|
|
|
0
|
print sprintf(qq/ sv_setpv_mg(get_svs("~", GV_ADD|GV_NOTQUAL), savepvn(%s, %u));\n/, cstring($~), length($~)) |
7772
|
|
|
|
|
|
|
if $~ ne "STDOUT"; |
7773
|
0
|
0
|
|
|
|
0
|
print qq{ sv_setiv_mg(get_svs("%", GV_ADD|GV_NOTQUAL), $%);\n} if $%; #PAGE_NUMBER |
7774
|
0
|
0
|
0
|
|
|
0
|
print qq{ sv_setiv_mg(get_svs("-", GV_ADD|GV_NOTQUAL), $-);\n} unless ($- == 0 or $- == 60); #LINES_LEFT |
7775
|
0
|
0
|
|
|
|
0
|
print qq{ sv_setiv_mg(get_svs("=", GV_ADD|GV_NOTQUAL), $=);\n} if $= != 60; #LINES_PER_PAGE |
7776
|
|
|
|
|
|
|
|
7777
|
|
|
|
|
|
|
# deprecated global vars |
7778
|
55
|
0
|
|
55
|
|
33310
|
print qq{ {SV* s = get_svs("[",GV_NOTQUAL); sv_setiv(s, $[); mg_set(s);}\n} if $[; #ARRAY_BASE |
|
55
|
|
|
|
|
16111
|
|
|
55
|
|
|
|
|
48857
|
|
|
0
|
|
|
|
|
0
|
|
7779
|
0
|
0
|
|
|
|
0
|
if ($] < 5.010) { # OFMT and multiline matching |
7780
|
0
|
|
|
|
|
0
|
eval q[ |
7781
|
|
|
|
|
|
|
print sprintf(qq{ sv_setpv(GvSVn(gv_fetchpv("\$#", GV_ADD|GV_NOTQUAL, SVt_PV)), %s);\n}, |
7782
|
|
|
|
|
|
|
cstring($#)) if $#; |
7783
|
|
|
|
|
|
|
print sprintf(qq{ sv_setiv(GvSVn(gv_fetchpv("\$*", GV_ADD|GV_NOTQUAL, SVt_IV)), %d);\n}, $*) if $*; |
7784
|
|
|
|
|
|
|
]; |
7785
|
|
|
|
|
|
|
} |
7786
|
|
|
|
|
|
|
|
7787
|
0
|
|
|
|
|
0
|
print sprintf(qq{ sv_setpv_mg(get_svs("\030", GV_ADD|GV_NOTQUAL), %s); /* \$^X */\n}, cstring($^X)); |
7788
|
0
|
|
|
|
|
0
|
print <<"EOT"; |
7789
|
|
|
|
|
|
|
TAINT_NOT; |
7790
|
|
|
|
|
|
|
|
7791
|
|
|
|
|
|
|
#if PERL_VERSION < 10 || ((PERL_VERSION == 10) && (PERL_SUBVERSION < 1)) |
7792
|
|
|
|
|
|
|
PL_compcv = 0; |
7793
|
|
|
|
|
|
|
#else |
7794
|
|
|
|
|
|
|
PL_compcv = MUTABLE_CV(newSV_type(SVt_PVCV)); |
7795
|
|
|
|
|
|
|
CvUNIQUE_on(PL_compcv); |
7796
|
|
|
|
|
|
|
CvPADLIST(PL_compcv) = pad_new(0); |
7797
|
|
|
|
|
|
|
#endif |
7798
|
|
|
|
|
|
|
|
7799
|
|
|
|
|
|
|
/* our special compiled init */ |
7800
|
|
|
|
|
|
|
perl_init(aTHX); |
7801
|
|
|
|
|
|
|
EOT |
7802
|
0
|
0
|
|
|
|
0
|
print " perl_init1(aTHX);\n" if $init1->index >= 0; |
7803
|
0
|
0
|
|
|
|
0
|
print " dl_init(aTHX);\n" unless defined $module; |
7804
|
0
|
0
|
|
|
|
0
|
print " perl_init2(aTHX);\n" if $init2->index >= 0; |
7805
|
0
|
|
|
|
|
0
|
print "\n exitstatus = perl_run( my_perl );\n"; |
7806
|
0
|
|
|
|
|
0
|
foreach my $s ( @{ $init->[-1]{pre_destruct} } ) { |
|
0
|
|
|
|
|
0
|
|
7807
|
0
|
|
|
|
|
0
|
print " ".$s."\n"; |
7808
|
|
|
|
|
|
|
} |
7809
|
|
|
|
|
|
|
|
7810
|
0
|
0
|
|
|
|
0
|
if ( !$B::C::destruct ) { |
7811
|
0
|
0
|
|
|
|
0
|
warn "fast_perl_destruct (-fno-destruct)\n" if $verbose; |
7812
|
0
|
|
|
|
|
0
|
print " fast_perl_destruct( my_perl );\n"; |
7813
|
|
|
|
|
|
|
#} elsif ( $PERL510 and (@B::C::static_free or $free->index > -1) ) { |
7814
|
|
|
|
|
|
|
# warn "my_perl_destruct static strings\n" if $verbose; |
7815
|
|
|
|
|
|
|
# print " my_perl_destruct( my_perl );\n"; |
7816
|
|
|
|
|
|
|
#} elsif ( $] >= 5.007003 ) { |
7817
|
|
|
|
|
|
|
# print " perl_destruct( my_perl );\n"; |
7818
|
|
|
|
|
|
|
} |
7819
|
|
|
|
|
|
|
else { |
7820
|
0
|
|
|
|
|
0
|
print " my_perl_destruct( my_perl );\n"; |
7821
|
|
|
|
|
|
|
} |
7822
|
|
|
|
|
|
|
# XXX endav is called via call_list and so it is freed right after usage. Setting dirty here is useless |
7823
|
|
|
|
|
|
|
#print " PL_dirty = 1;\n" unless $B::C::pv_copy_on_grow; # protect against pad undef in END block |
7824
|
0
|
|
|
|
|
0
|
print <<'EOT1'; |
7825
|
|
|
|
|
|
|
perl_free( my_perl ); |
7826
|
|
|
|
|
|
|
|
7827
|
|
|
|
|
|
|
PERL_SYS_TERM(); |
7828
|
|
|
|
|
|
|
|
7829
|
|
|
|
|
|
|
exit( exitstatus ); |
7830
|
|
|
|
|
|
|
} |
7831
|
|
|
|
|
|
|
EOT1 |
7832
|
|
|
|
|
|
|
|
7833
|
|
|
|
|
|
|
} # module |
7834
|
|
|
|
|
|
|
} |
7835
|
|
|
|
|
|
|
|
7836
|
|
|
|
|
|
|
sub dump_symtable { |
7837
|
|
|
|
|
|
|
# For debugging |
7838
|
0
|
|
|
0
|
0
|
0
|
my ( $sym, $val ); |
7839
|
0
|
|
|
|
|
0
|
warn "----Symbol table:\n"; |
7840
|
|
|
|
|
|
|
#while ( ( $sym, $val ) = each %symtable ) |
7841
|
0
|
|
|
|
|
0
|
for $sym (sort keys %symtable) { |
7842
|
0
|
|
|
|
|
0
|
$val = $symtable{$sym}; |
7843
|
0
|
|
|
|
|
0
|
warn "$sym => $val\n"; |
7844
|
|
|
|
|
|
|
} |
7845
|
0
|
|
|
|
|
0
|
warn "---End of symbol table\n"; |
7846
|
|
|
|
|
|
|
} |
7847
|
|
|
|
|
|
|
|
7848
|
|
|
|
|
|
|
sub save_object { |
7849
|
0
|
|
|
0
|
0
|
0
|
my $sv; |
7850
|
0
|
|
|
|
|
0
|
foreach $sv (@_) { |
7851
|
0
|
|
|
|
|
0
|
svref_2object($sv)->save; |
7852
|
|
|
|
|
|
|
} |
7853
|
|
|
|
|
|
|
} |
7854
|
|
|
|
|
|
|
|
7855
|
|
|
|
0
|
0
|
|
sub Dummy_BootStrap { } |
7856
|
|
|
|
|
|
|
|
7857
|
|
|
|
|
|
|
#ignore nullified cv |
7858
|
|
|
|
0
|
|
|
sub B::SPECIAL::savecv {} |
7859
|
|
|
|
|
|
|
|
7860
|
|
|
|
|
|
|
sub B::GV::savecv { |
7861
|
0
|
|
|
0
|
|
0
|
my $gv = shift; |
7862
|
0
|
|
|
|
|
0
|
my $package = $gv->STASH->NAME; |
7863
|
0
|
|
|
|
|
0
|
my $name = $gv->NAME; |
7864
|
0
|
|
|
|
|
0
|
my $cv = $gv->CV; |
7865
|
0
|
|
|
|
|
0
|
my $sv = $gv->SV; |
7866
|
0
|
|
|
|
|
0
|
my $av = $gv->AV; |
7867
|
0
|
|
|
|
|
0
|
my $hv = $gv->HV; |
7868
|
|
|
|
|
|
|
|
7869
|
0
|
|
|
|
|
0
|
my $fullname = $package . "::" . $name; |
7870
|
|
|
|
|
|
|
warn sprintf( "Checking GV *%s 0x%x\n", cstring($fullname), $$gv ) |
7871
|
0
|
0
|
0
|
|
|
0
|
if $debug{gv} and $verbose; |
7872
|
|
|
|
|
|
|
# We may be looking at this package just because it is a branch in the |
7873
|
|
|
|
|
|
|
# symbol table which is on the path to a package which we need to save |
7874
|
|
|
|
|
|
|
# e.g. this is 'Getopt' and we need to save 'Getopt::Long' |
7875
|
|
|
|
|
|
|
# |
7876
|
0
|
0
|
0
|
|
|
0
|
return if ( $package ne 'main' and !$include_package{$package} ); |
7877
|
0
|
0
|
0
|
|
|
0
|
return if ( $package eq 'main' and |
7878
|
|
|
|
|
|
|
$name =~ /^([^\w].*|_\<.*|INC|ARGV|SIG|ENV|BEGIN|main::|!)$/ ); |
7879
|
|
|
|
|
|
|
|
7880
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Used GV \*$fullname 0x%x\n", $$gv ) if $debug{gv}; |
7881
|
0
|
0
|
0
|
|
|
0
|
return unless ( $$cv || $$av || $$sv || $$hv || $gv->IO || $gv->FORM ); |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
7882
|
0
|
0
|
0
|
|
|
0
|
if ($$cv and $name eq 'bootstrap' and $cv->XSUB) { |
|
|
|
0
|
|
|
|
|
7883
|
|
|
|
|
|
|
#return $cv->save($fullname); |
7884
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Skip XS \&$fullname 0x%x\n", $$cv ) if $debug{gv}; |
7885
|
0
|
|
|
|
|
0
|
return; |
7886
|
|
|
|
|
|
|
} |
7887
|
0
|
0
|
0
|
|
|
0
|
if ( $$cv and in_static_core($package, $name) and ref($cv) eq 'B::CV' # 5.8,4 issue32 |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
7888
|
|
|
|
|
|
|
and $cv->XSUB ) { |
7889
|
0
|
0
|
|
|
|
0
|
warn("Skip internal XS $fullname\n") if $debug{gv}; |
7890
|
|
|
|
|
|
|
# but prevent it from being deleted |
7891
|
0
|
0
|
|
|
|
0
|
unless ($dumped_package{$package}) { |
7892
|
|
|
|
|
|
|
#$dumped_package{$package} = 1; |
7893
|
0
|
|
|
|
|
0
|
mark_package($package, 1); |
7894
|
|
|
|
|
|
|
} |
7895
|
0
|
|
|
|
|
0
|
return; |
7896
|
|
|
|
|
|
|
} |
7897
|
0
|
0
|
|
|
|
0
|
if ($package eq 'B::C') { |
7898
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Skip XS \&$fullname 0x%x\n", $$cv ) if $debug{gv}; |
7899
|
0
|
|
|
|
|
0
|
return; |
7900
|
|
|
|
|
|
|
} |
7901
|
0
|
0
|
|
|
|
0
|
if ($fullname =~ /^(bytes|utf8)::AUTOLOAD$/) { |
7902
|
0
|
|
|
|
|
0
|
$gv = force_heavy($package); |
7903
|
|
|
|
|
|
|
} |
7904
|
|
|
|
|
|
|
# XXX fails and should not be needed. The B::C part should be skipped 9 lines above, but be defensive |
7905
|
0
|
0
|
0
|
|
|
0
|
return if $fullname eq 'B::walksymtable' or $fullname eq 'B::C::walksymtable'; |
7906
|
|
|
|
|
|
|
# Config is marked on any Config symbol. TIE and DESTROY are exceptions, |
7907
|
|
|
|
|
|
|
# used by the compiler itself |
7908
|
0
|
0
|
|
|
|
0
|
if ($name eq 'Config') { |
7909
|
0
|
0
|
|
|
|
0
|
mark_package('Config', 1) if !$include_package{'Config'}; |
7910
|
|
|
|
|
|
|
} |
7911
|
0
|
0
|
0
|
|
|
0
|
$dumped_package{$package} = 1 if !exists $dumped_package{$package} and $package !~ /::$/; |
7912
|
0
|
0
|
|
|
|
0
|
warn sprintf( "Saving GV \*$fullname 0x%x\n", $$gv ) if $debug{gv}; |
7913
|
0
|
|
|
|
|
0
|
$gv->save($fullname); |
7914
|
|
|
|
|
|
|
} |
7915
|
|
|
|
|
|
|
|
7916
|
|
|
|
|
|
|
# Fixes bug #307: use foreach, not each |
7917
|
|
|
|
|
|
|
# each is not safe to use (at all). walksymtable is called recursively which might add |
7918
|
|
|
|
|
|
|
# symbols to the stash, which might cause re-ordered rehashes, which will fool the hash |
7919
|
|
|
|
|
|
|
# iterator, leading to missing symbols in the binary. |
7920
|
|
|
|
|
|
|
# Old perl5 bug: The iterator should really be stored in the op, not the hash. |
7921
|
|
|
|
|
|
|
sub walksymtable { |
7922
|
0
|
|
|
0
|
0
|
0
|
my ($symref, $method, $recurse, $prefix) = @_; |
7923
|
0
|
|
|
|
|
0
|
my ($sym, $ref, $fullname); |
7924
|
0
|
0
|
|
|
|
0
|
$prefix = '' unless defined $prefix; |
7925
|
|
|
|
|
|
|
|
7926
|
|
|
|
|
|
|
# If load_utf8_heavy doesn't happen before we walk utf8:: |
7927
|
|
|
|
|
|
|
# (when utf8_heavy has already been called) then the stored CV for utf8::S |
7928
|
|
|
|
|
|
|
# WASHNEW could be wrong. |
7929
|
0
|
0
|
0
|
|
|
0
|
load_utf8_heavy() if ( $prefix eq 'utf8::' && defined $symref->{'SWASHNEW'} ); |
7930
|
|
|
|
|
|
|
|
7931
|
|
|
|
|
|
|
my @list = sort { |
7932
|
|
|
|
|
|
|
# we want these symbols to be saved last to avoid incomplete saves |
7933
|
|
|
|
|
|
|
# +/- reverse is to defer + - to fix Tie::Hash::NamedCapturespecial cases. GH #247 |
7934
|
|
|
|
|
|
|
# _loose_name redefined from utf8_heavy.pl GH #364 |
7935
|
0
|
|
|
|
|
0
|
foreach my $v (qw{- + utf8:: bytes::}) { |
|
0
|
|
|
|
|
0
|
|
7936
|
0
|
0
|
|
|
|
0
|
$a eq $v and return 1; |
7937
|
0
|
0
|
|
|
|
0
|
$b eq $v and return -1; |
7938
|
|
|
|
|
|
|
} |
7939
|
|
|
|
|
|
|
# reverse order for now to preserve original behavior before improved patch |
7940
|
0
|
|
|
|
|
0
|
$b cmp $a |
7941
|
|
|
|
|
|
|
} keys %$symref; |
7942
|
|
|
|
|
|
|
|
7943
|
0
|
|
|
|
|
0
|
foreach my $sym ( @list ) { |
7944
|
55
|
|
|
55
|
|
287
|
no strict 'refs'; |
|
55
|
|
|
|
|
82
|
|
|
55
|
|
|
|
|
8260
|
|
7945
|
0
|
|
|
|
|
0
|
$ref = $symref->{$sym}; |
7946
|
0
|
|
|
|
|
0
|
$fullname = "*main::".$prefix.$sym; |
7947
|
0
|
0
|
|
|
|
0
|
if ($sym =~ /::$/) { |
7948
|
0
|
|
|
|
|
0
|
$sym = $prefix . $sym; |
7949
|
0
|
0
|
0
|
|
|
0
|
if (svref_2object(\*$sym)->NAME ne "main::" && $sym ne "::" && &$recurse($sym)) { |
|
|
|
0
|
|
|
|
|
7950
|
0
|
|
|
|
|
0
|
walksymtable(\%$fullname, $method, $recurse, $sym); |
7951
|
|
|
|
|
|
|
} |
7952
|
|
|
|
|
|
|
} else { |
7953
|
0
|
|
|
|
|
0
|
svref_2object(\*$fullname)->$method(); |
7954
|
|
|
|
|
|
|
} |
7955
|
|
|
|
|
|
|
} |
7956
|
|
|
|
|
|
|
} |
7957
|
|
|
|
|
|
|
|
7958
|
|
|
|
|
|
|
sub walk_syms { |
7959
|
0
|
|
|
0
|
0
|
0
|
my $package = shift; |
7960
|
55
|
|
|
55
|
|
243
|
no strict 'refs'; |
|
55
|
|
|
|
|
84
|
|
|
55
|
|
|
|
|
6185
|
|
7961
|
0
|
0
|
|
|
|
0
|
return if $dumped_package{$package}; |
7962
|
0
|
0
|
0
|
|
|
0
|
warn "walk_syms $package\n" if $debug{pkg} and $verbose; |
7963
|
0
|
|
|
|
|
0
|
$dumped_package{$package} = 1; |
7964
|
0
|
|
|
0
|
|
0
|
walksymtable( \%{$package.'::'}, "savecv", sub { 1 }, $package.'::' ); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
7965
|
|
|
|
|
|
|
} |
7966
|
|
|
|
|
|
|
|
7967
|
|
|
|
|
|
|
# simplified walk_syms |
7968
|
|
|
|
|
|
|
# needed to populate @B::C::Config::deps from Makefile.PL from within this %INC context |
7969
|
|
|
|
|
|
|
sub walk_stashes { |
7970
|
0
|
|
|
0
|
0
|
0
|
my ($symref, $prefix) = @_; |
7971
|
55
|
|
|
55
|
|
239
|
no strict 'refs'; |
|
55
|
|
|
|
|
78
|
|
|
55
|
|
|
|
|
11595
|
|
7972
|
0
|
0
|
|
|
|
0
|
$prefix = '' unless defined $prefix; |
7973
|
0
|
|
|
|
|
0
|
foreach my $sym ( sort keys %$symref ) { |
7974
|
0
|
0
|
|
|
|
0
|
if ($sym =~ /::$/) { |
7975
|
0
|
|
|
|
|
0
|
$sym = $prefix . $sym; |
7976
|
0
|
|
|
|
|
0
|
$B::C::deps{ substr($sym,0,-2) }++; |
7977
|
0
|
0
|
0
|
|
|
0
|
if ($sym ne "main::" && $sym ne "::") { |
7978
|
0
|
|
|
|
|
0
|
walk_stashes(\%$sym, $sym); |
7979
|
|
|
|
|
|
|
} |
7980
|
|
|
|
|
|
|
} |
7981
|
|
|
|
|
|
|
} |
7982
|
|
|
|
|
|
|
} |
7983
|
|
|
|
|
|
|
|
7984
|
|
|
|
|
|
|
sub collect_deps { |
7985
|
0
|
|
|
0
|
0
|
0
|
%B::C::deps = (); |
7986
|
0
|
|
|
|
|
0
|
walk_stashes(\%main::); |
7987
|
0
|
|
|
|
|
0
|
print join " ",(sort keys %B::C::deps); |
7988
|
|
|
|
|
|
|
} |
7989
|
|
|
|
|
|
|
|
7990
|
|
|
|
|
|
|
sub mark_package { |
7991
|
0
|
|
|
0
|
0
|
0
|
my $package = shift; |
7992
|
0
|
|
|
|
|
0
|
my $force = shift; |
7993
|
0
|
0
|
|
|
|
0
|
$force = 0 if $] < 5.010; |
7994
|
0
|
0
|
|
|
|
0
|
return if skip_pkg($package); # or $package =~ /^B::C(C?)::/; |
7995
|
0
|
0
|
0
|
|
|
0
|
if ( !$include_package{$package} or $force ) { |
7996
|
55
|
|
|
55
|
|
237
|
no strict 'refs'; |
|
55
|
|
|
|
|
78
|
|
|
55
|
|
|
|
|
14367
|
|
7997
|
0
|
0
|
0
|
|
|
0
|
warn "mark_package($package, $force)\n" if $verbose and $debug{pkg}; |
7998
|
0
|
|
|
|
|
0
|
my @IO = qw(IO::File IO::Handle IO::Socket IO::Seekable IO::Poll); |
7999
|
0
|
0
|
|
|
|
0
|
mark_package('IO') if grep { $package eq $_ } @IO; |
|
0
|
|
|
|
|
0
|
|
8000
|
0
|
0
|
|
|
|
0
|
mark_package("DynaLoader") if $package eq 'XSLoader'; |
8001
|
0
|
0
|
|
|
|
0
|
$use_xsloader = 1 if $package =~ /^B|Carp$/; # to help CC a bit (49) |
8002
|
|
|
|
|
|
|
# i.e. if force |
8003
|
0
|
0
|
0
|
|
|
0
|
if (exists $include_package{$package} |
|
|
|
0
|
|
|
|
|
8004
|
|
|
|
|
|
|
and !$include_package{$package} |
8005
|
|
|
|
|
|
|
and $savINC{inc_packname($package)}) |
8006
|
|
|
|
|
|
|
{ |
8007
|
0
|
0
|
|
|
|
0
|
warn sprintf("$package previously deleted, save now%s\n", |
|
|
0
|
|
|
|
|
|
8008
|
|
|
|
|
|
|
$force?" (forced)":"") if $verbose; |
8009
|
|
|
|
|
|
|
# $include_package{$package} = 1; |
8010
|
0
|
|
|
|
|
0
|
add_hashINC( $package ); |
8011
|
0
|
|
|
|
|
0
|
walk_syms( $package ); |
8012
|
|
|
|
|
|
|
} else { |
8013
|
|
|
|
|
|
|
warn sprintf("mark $package%s\n", $force?" (forced)":"") |
8014
|
0
|
0
|
0
|
|
|
0
|
if !$include_package{$package} and $verbose and $debug{pkg}; |
|
|
0
|
0
|
|
|
|
|
8015
|
0
|
|
|
|
|
0
|
$include_package{$package} = 1; |
8016
|
0
|
0
|
|
|
|
0
|
push_package($package) if $] < 5.010; |
8017
|
0
|
0
|
|
|
|
0
|
walk_syms( $package ) if !$B::C::walkall; # fixes i27-1 |
8018
|
|
|
|
|
|
|
} |
8019
|
0
|
|
|
|
|
0
|
my @isa = get_isa($package); |
8020
|
0
|
0
|
|
|
|
0
|
if ( @isa ) { |
8021
|
|
|
|
|
|
|
# XXX walking the ISA is often not enough. |
8022
|
|
|
|
|
|
|
# we should really check all new packages since the last full scan. |
8023
|
0
|
|
|
|
|
0
|
foreach my $isa ( @isa ) { |
8024
|
0
|
0
|
|
|
|
0
|
next if $isa eq $package; |
8025
|
0
|
0
|
|
|
|
0
|
if ( $isa eq 'DynaLoader' ) { |
8026
|
0
|
0
|
|
|
|
0
|
unless ( defined( &{ $package . '::bootstrap' } ) ) { |
|
0
|
|
|
|
|
0
|
|
8027
|
0
|
0
|
|
|
|
0
|
warn "Forcing bootstrap of $package\n" if $verbose; |
8028
|
0
|
|
|
|
|
0
|
eval { $package->bootstrap }; |
|
0
|
|
|
|
|
0
|
|
8029
|
|
|
|
|
|
|
} |
8030
|
|
|
|
|
|
|
} |
8031
|
0
|
0
|
0
|
|
|
0
|
if ( !$include_package{$isa} and !$skip_package{$isa} ) { |
8032
|
55
|
|
|
55
|
|
237
|
no strict 'refs'; |
|
55
|
|
|
|
|
74
|
|
|
55
|
|
|
|
|
34930
|
|
8033
|
0
|
0
|
|
|
|
0
|
warn "$isa saved (it is in $package\'s \@ISA)\n" if $verbose; |
8034
|
0
|
|
|
|
|
0
|
B::svref_2object( \@{$isa."::ISA"} ) ->save; #308 |
|
0
|
|
|
|
|
0
|
|
8035
|
0
|
0
|
|
|
|
0
|
if (exists $include_package{$isa} ) { |
8036
|
0
|
0
|
|
|
|
0
|
warn "$isa previously deleted, save now\n" if $verbose; # e.g. Sub::Name |
8037
|
0
|
|
|
|
|
0
|
mark_package($isa); |
8038
|
0
|
|
|
|
|
0
|
walk_syms($isa); # avoid deep recursion |
8039
|
|
|
|
|
|
|
} else { |
8040
|
|
|
|
|
|
|
#warn "isa $isa save\n" if $verbose; |
8041
|
0
|
|
|
|
|
0
|
mark_package($isa); |
8042
|
|
|
|
|
|
|
} |
8043
|
|
|
|
|
|
|
} |
8044
|
|
|
|
|
|
|
} |
8045
|
|
|
|
|
|
|
} |
8046
|
|
|
|
|
|
|
} |
8047
|
0
|
|
|
|
|
0
|
return 1; |
8048
|
|
|
|
|
|
|
} |
8049
|
|
|
|
|
|
|
|
8050
|
|
|
|
|
|
|
# XS in CORE which do not need to be bootstrapped extra. |
8051
|
|
|
|
|
|
|
# There are some specials like mro,re,UNIVERSAL. |
8052
|
|
|
|
|
|
|
sub in_static_core { |
8053
|
0
|
|
|
0
|
0
|
0
|
my ($stashname, $cvname) = @_; |
8054
|
0
|
0
|
|
|
|
0
|
if ($stashname eq 'UNIVERSAL') { |
8055
|
0
|
|
|
|
|
0
|
return $cvname =~ /^(isa|can|DOES|VERSION)$/; |
8056
|
|
|
|
|
|
|
} |
8057
|
0
|
0
|
|
|
|
0
|
%static_core_pkg = map {$_ => 1} static_core_packages() |
|
0
|
|
|
|
|
0
|
|
8058
|
|
|
|
|
|
|
unless %static_core_pkg; |
8059
|
0
|
0
|
|
|
|
0
|
return 1 if $static_core_pkg{$stashname}; |
8060
|
0
|
0
|
|
|
|
0
|
if ($stashname eq 'mro') { |
8061
|
0
|
|
|
|
|
0
|
return $cvname eq 'method_changed_in'; |
8062
|
|
|
|
|
|
|
} |
8063
|
0
|
0
|
|
|
|
0
|
if ($stashname eq 're') { |
8064
|
0
|
|
|
|
|
0
|
return $cvname =~ /^(is_regexp|regname|regnames|regnames_count|regexp_pattern)$/;; |
8065
|
|
|
|
|
|
|
} |
8066
|
0
|
0
|
|
|
|
0
|
if ($stashname eq 'PerlIO') { |
8067
|
0
|
|
|
|
|
0
|
return $cvname eq 'get_layers'; |
8068
|
|
|
|
|
|
|
} |
8069
|
0
|
0
|
|
|
|
0
|
if ($stashname eq 'PerlIO::Layer') { |
8070
|
0
|
|
|
|
|
0
|
return $cvname =~ /^(find|NoWarnings)$/; |
8071
|
|
|
|
|
|
|
} |
8072
|
0
|
|
|
|
|
0
|
return 0; |
8073
|
|
|
|
|
|
|
} |
8074
|
|
|
|
|
|
|
|
8075
|
|
|
|
|
|
|
# XS modules in CORE. Reserved namespaces. |
8076
|
|
|
|
|
|
|
# Note: mro,re,UNIVERSAL have both, static core and dynamic/static XS |
8077
|
|
|
|
|
|
|
# version has an external ::vxs |
8078
|
|
|
|
|
|
|
sub static_core_packages { |
8079
|
0
|
|
|
0
|
0
|
0
|
my @pkg = qw(Internals utf8 UNIVERSAL); |
8080
|
0
|
0
|
|
|
|
0
|
push @pkg, qw(strict coretypes DynaLoader XSLoader) if $CPERL51; |
8081
|
0
|
0
|
|
|
|
0
|
push @pkg, 'attributes' if $] < 5.011; # partially static and dynamic |
8082
|
0
|
0
|
|
|
|
0
|
push @pkg, 'version' if $] >= 5.010; # partially static and dynamic |
8083
|
0
|
0
|
|
|
|
0
|
push @pkg, 'Tie::Hash::NamedCapture' if !$PERL514; # dynamic since 5.14 |
8084
|
|
|
|
|
|
|
#push @pkg, 'DynaLoader' if $Config{usedl}; |
8085
|
|
|
|
|
|
|
# Win32CORE only in official cygwin pkg. And it needs to be bootstrapped, |
8086
|
|
|
|
|
|
|
# handled by static_ext. |
8087
|
0
|
0
|
|
|
|
0
|
push @pkg, 'Cygwin' if $^O eq 'cygwin'; |
8088
|
0
|
0
|
|
|
|
0
|
push @pkg, 'NetWare' if $^O eq 'NetWare'; |
8089
|
0
|
0
|
|
|
|
0
|
push @pkg, 'OS2' if $^O eq 'os2'; |
8090
|
0
|
0
|
|
|
|
0
|
push @pkg, qw(VMS VMS::Filespec vmsish) if $^O eq 'VMS'; |
8091
|
|
|
|
|
|
|
#push @pkg, 'PerlIO' if $] >= 5.008006; # get_layers only |
8092
|
0
|
|
|
|
|
0
|
push @pkg, split(/ /,$Config{static_ext}); |
8093
|
0
|
|
|
|
|
0
|
return @pkg; |
8094
|
|
|
|
|
|
|
} |
8095
|
|
|
|
|
|
|
|
8096
|
|
|
|
|
|
|
sub skip_pkg { |
8097
|
0
|
|
|
0
|
0
|
0
|
my $package = shift; |
8098
|
0
|
0
|
0
|
|
|
0
|
if ( $package =~ /^(main::)?(Internals|O)::/ |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
8099
|
|
|
|
|
|
|
#or $package =~ /::::/ # CORE/base/lex.t 54 |
8100
|
|
|
|
|
|
|
or $package =~ /^B::C::/ |
8101
|
|
|
|
|
|
|
or $package eq '__ANON__' |
8102
|
|
|
|
|
|
|
or index($package, " ") != -1 # XXX skip invalid package names |
8103
|
|
|
|
|
|
|
or index($package, "(") != -1 # XXX this causes the compiler to abort |
8104
|
|
|
|
|
|
|
or index($package, ")") != -1 # XXX this causes the compiler to abort |
8105
|
|
|
|
|
|
|
or exists $skip_package{$package} |
8106
|
|
|
|
|
|
|
or ($DB::deep and $package =~ /^(DB|Term::ReadLine)/)) { |
8107
|
0
|
|
|
|
|
0
|
return 1; |
8108
|
|
|
|
|
|
|
} |
8109
|
0
|
|
|
|
|
0
|
return 0; |
8110
|
|
|
|
|
|
|
} |
8111
|
|
|
|
|
|
|
|
8112
|
|
|
|
|
|
|
# Do not delete/ignore packages which were brought in from the script, |
8113
|
|
|
|
|
|
|
# i.e. not defined in B::C or O. Just to be on the safe side. |
8114
|
|
|
|
|
|
|
sub can_delete { |
8115
|
0
|
|
|
0
|
0
|
0
|
my $pkg = shift; |
8116
|
0
|
0
|
0
|
|
|
0
|
if (exists $all_bc_deps{$pkg} and $B::C::can_delete_pkg) { return 1 }; |
|
0
|
|
|
|
|
0
|
|
8117
|
0
|
|
|
|
|
0
|
return undef; |
8118
|
|
|
|
|
|
|
} |
8119
|
|
|
|
|
|
|
|
8120
|
|
|
|
|
|
|
sub should_save { |
8121
|
55
|
|
|
55
|
|
244
|
no strict qw(vars refs); |
|
55
|
|
|
|
|
74
|
|
|
55
|
|
|
|
|
20214
|
|
8122
|
0
|
|
|
0
|
0
|
0
|
my $package = shift; |
8123
|
0
|
|
|
|
|
0
|
$package =~ s/::$//; |
8124
|
0
|
0
|
|
|
|
0
|
if ( skip_pkg($package) ) { |
8125
|
0
|
0
|
|
|
|
0
|
delete_unsaved_hashINC($package) if can_delete($package); |
8126
|
0
|
|
|
|
|
0
|
return 0; |
8127
|
|
|
|
|
|
|
} |
8128
|
0
|
0
|
|
|
|
0
|
return $include_package{$package} = 0 |
8129
|
|
|
|
|
|
|
if ( $package =~ /::::/ ); # skip ::::ISA::CACHE etc. |
8130
|
0
|
0
|
|
|
|
0
|
warn "Considering $package\n" if $debug{pkg}; #$include_package{$package} |
8131
|
0
|
0
|
|
|
|
0
|
return if index($package, " ") != -1; # XXX skip invalid package names |
8132
|
0
|
0
|
|
|
|
0
|
return if index($package, "(") != -1; # XXX this causes the compiler to abort |
8133
|
0
|
0
|
|
|
|
0
|
return if index($package, ")") != -1; # XXX this causes the compiler to abort |
8134
|
|
|
|
|
|
|
# core static mro has exactly one member, ext/mro has more |
8135
|
0
|
0
|
|
|
|
0
|
if ($package eq 'mro') { |
8136
|
|
|
|
|
|
|
# B::C is setting %mro:: to 3, make sure we have at least 10 |
8137
|
0
|
0
|
|
|
|
0
|
if (!is_using_mro()) { # core or ext? |
8138
|
0
|
0
|
|
|
|
0
|
warn "ext/mro not loaded - skip\n" if $debug{pkg}; |
8139
|
0
|
|
|
|
|
0
|
return; |
8140
|
|
|
|
|
|
|
} else { |
8141
|
0
|
0
|
|
|
|
0
|
warn "ext/mro already loaded\n" if $debug{pkg}; |
8142
|
|
|
|
|
|
|
# $include_package{mro} = 1 if grep { $_ eq 'mro' } @DynaLoader::dl_modules; |
8143
|
0
|
|
|
|
|
0
|
return $include_package{mro}; |
8144
|
|
|
|
|
|
|
} |
8145
|
|
|
|
|
|
|
} |
8146
|
0
|
0
|
0
|
|
|
0
|
if ($package eq 'attributes' and $] > 5.011 |
|
|
|
0
|
|
|
|
|
8147
|
0
|
|
|
|
|
0
|
and grep { $_ eq 'attributes' } @DynaLoader::dl_modules) |
8148
|
|
|
|
|
|
|
{ |
8149
|
0
|
|
|
|
|
0
|
mark_package($package, 1); |
8150
|
0
|
|
|
|
|
0
|
return 1; |
8151
|
|
|
|
|
|
|
} |
8152
|
0
|
0
|
|
|
|
0
|
if (exists $all_bc_deps{$package}) { |
8153
|
0
|
|
|
|
|
0
|
foreach my $u ( grep( $include_package{$_}, sort keys %include_package ) ) { |
8154
|
|
|
|
|
|
|
# If this package is a prefix to something we are saving, traverse it |
8155
|
|
|
|
|
|
|
# but do not mark it for saving if it is not already |
8156
|
|
|
|
|
|
|
# e.g. to get to B::OP we need to traverse B:: but need not save B |
8157
|
0
|
|
|
|
|
0
|
my $p = $package; |
8158
|
0
|
|
|
|
|
0
|
$p =~ s/(\W)/\\$1/g; |
8159
|
0
|
0
|
0
|
|
|
0
|
return 1 if ( $u =~ /^$p\:\:/ ) && $include_package{$package}; |
8160
|
|
|
|
|
|
|
} |
8161
|
|
|
|
|
|
|
} |
8162
|
|
|
|
|
|
|
# Needed since 5.12.2: Check already if deleted |
8163
|
0
|
|
|
|
|
0
|
my $incpack = inc_packname($package); |
8164
|
0
|
0
|
0
|
|
|
0
|
if ( $] > 5.015001 and exists $all_bc_deps{$package} |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
8165
|
|
|
|
|
|
|
and !exists $curINC{$incpack} and $savINC{$incpack} ) { |
8166
|
0
|
|
|
|
|
0
|
$include_package{$package} = 0; |
8167
|
0
|
0
|
|
|
|
0
|
warn "Cached $package not in \%INC, already deleted (early)\n" if $debug{pkg}; |
8168
|
0
|
|
|
|
|
0
|
return 0; |
8169
|
|
|
|
|
|
|
} |
8170
|
|
|
|
|
|
|
# issue348: only drop B::C packages, not any from user code. |
8171
|
0
|
0
|
0
|
|
|
0
|
if (($package =~ /^DynaLoader|XSLoader$/ and $use_xsloader) |
|
|
|
0
|
|
|
|
|
8172
|
|
|
|
|
|
|
or (!exists $all_bc_deps{$package})) { |
8173
|
0
|
|
|
|
|
0
|
$include_package{$package} = 1; |
8174
|
|
|
|
|
|
|
} |
8175
|
|
|
|
|
|
|
# If this package is in the same file as main:: or our source, save it. (72, 73) |
8176
|
0
|
0
|
|
|
|
0
|
if ($mainfile) { |
8177
|
|
|
|
|
|
|
# Find the first cv in this package for CV->FILE |
8178
|
55
|
|
|
55
|
|
251
|
no strict 'refs'; |
|
55
|
|
|
|
|
76
|
|
|
55
|
|
|
|
|
52780
|
|
8179
|
0
|
|
|
|
|
0
|
for my $sym (sort keys %{$package.'::'}) { |
|
0
|
|
|
|
|
0
|
|
8180
|
0
|
0
|
|
|
|
0
|
if (defined &{$package.'::'.$sym}) { |
|
0
|
|
|
|
|
0
|
|
8181
|
|
|
|
|
|
|
# compare cv->FILE to $mainfile |
8182
|
0
|
|
|
|
|
0
|
my $cv = svref_2object(\&{$package.'::'.$sym}); |
|
0
|
|
|
|
|
0
|
|
8183
|
0
|
0
|
0
|
|
|
0
|
if ($cv and $cv->can('FILE') and $cv->FILE) { |
|
|
|
0
|
|
|
|
|
8184
|
0
|
0
|
|
|
|
0
|
$include_package{$package} = 1 if $mainfile eq $cv->FILE; |
8185
|
0
|
|
|
|
|
0
|
last; |
8186
|
|
|
|
|
|
|
} |
8187
|
|
|
|
|
|
|
} |
8188
|
|
|
|
|
|
|
} |
8189
|
|
|
|
|
|
|
} |
8190
|
|
|
|
|
|
|
# add overloaded but otherwise empty packages (#172) |
8191
|
0
|
0
|
0
|
|
|
0
|
if ($savINC{'overload.pm'} and exists ${$package.'::'}{OVERLOAD} and exists ${$package.'::'}{'()'}) { |
|
0
|
|
0
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
8192
|
0
|
|
|
|
|
0
|
mark_package($package, 1); |
8193
|
0
|
|
|
|
|
0
|
mark_package('overload', 1); |
8194
|
0
|
|
|
|
|
0
|
return 1; |
8195
|
|
|
|
|
|
|
} |
8196
|
|
|
|
|
|
|
# Omit the packages which we use (and which cause grief |
8197
|
|
|
|
|
|
|
# because of fancy "goto &$AUTOLOAD" stuff). |
8198
|
|
|
|
|
|
|
# XXX Surely there must be a nicer way to do this. |
8199
|
0
|
0
|
|
|
|
0
|
if ( exists $include_package{$package} ) { |
8200
|
0
|
0
|
|
|
|
0
|
if (! exists $all_bc_deps{$package}) { |
|
|
0
|
|
|
|
|
|
8201
|
0
|
|
|
|
|
0
|
$include_package{$package} = 1; |
8202
|
0
|
|
|
|
|
0
|
$curINC{$incpack} = $savINC{$incpack}; |
8203
|
0
|
0
|
|
|
|
0
|
warn "Cached new $package is kept\n" if $debug{pkg}; |
8204
|
|
|
|
|
|
|
} |
8205
|
|
|
|
|
|
|
elsif (!$include_package{$package}) { |
8206
|
0
|
0
|
|
|
|
0
|
delete_unsaved_hashINC($package) if can_delete($package); |
8207
|
0
|
0
|
|
|
|
0
|
warn "Cached $package is already deleted\n" if $debug{pkg}; |
8208
|
|
|
|
|
|
|
} else { |
8209
|
0
|
0
|
|
|
|
0
|
warn "Cached $package is cached\n" if $debug{pkg}; |
8210
|
|
|
|
|
|
|
} |
8211
|
0
|
|
|
|
|
0
|
return $include_package{$package}; |
8212
|
|
|
|
|
|
|
} |
8213
|
|
|
|
|
|
|
|
8214
|
|
|
|
|
|
|
# Now see if current package looks like an OO class. This is probably too strong. |
8215
|
0
|
0
|
|
|
|
0
|
if (!$all_bc_deps{$package}) { |
8216
|
0
|
|
|
|
|
0
|
foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE)) { |
8217
|
|
|
|
|
|
|
# 5.10 introduced version and Regexp::DESTROY, which we dont want automatically. |
8218
|
|
|
|
|
|
|
# XXX TODO This logic here is wrong and unstable. Fixes lead to more failures. |
8219
|
|
|
|
|
|
|
# The walker deserves a rewrite. |
8220
|
0
|
0
|
0
|
|
|
0
|
if ( UNIVERSAL::can( $package, $m ) and $package !~ /^(B::C|version|Regexp|utf8|SelectSaver)$/ ) { |
8221
|
0
|
0
|
0
|
|
|
0
|
next if $package eq 'utf8' and $m eq 'DESTROY'; # utf8::DESTROY is empty |
8222
|
|
|
|
|
|
|
# we load Errno by ourself to avoid double Config warnings [perl #] |
8223
|
|
|
|
|
|
|
# and we have special logic to detect and include it |
8224
|
0
|
0
|
0
|
|
|
0
|
next if $package =~ /^(Errno|Tie::Hash::NamedCapture)$/ and $m eq 'TIEHASH'; |
8225
|
|
|
|
|
|
|
# XXX Config and FileHandle should not just return. If unneeded skip em. |
8226
|
0
|
0
|
0
|
|
|
0
|
return 0 if $package eq 'Config' and $m =~ /DESTROY|TIEHASH/; # Config detected in GV |
8227
|
|
|
|
|
|
|
# IO::File|IO::Handle added for B::CC only |
8228
|
0
|
0
|
0
|
|
|
0
|
return 0 if $package =~ /^(FileHandle|IO::File|IO::Handle)/ and $m eq 'new'; |
8229
|
0
|
0
|
|
|
|
0
|
warn "$package has method $m: saving package\n" if $debug{pkg}; |
8230
|
0
|
|
|
|
|
0
|
return mark_package($package); |
8231
|
|
|
|
|
|
|
} |
8232
|
|
|
|
|
|
|
} |
8233
|
|
|
|
|
|
|
} |
8234
|
0
|
0
|
0
|
|
|
0
|
if ($package !~ /^PerlIO/ and can_delete($package)) { |
8235
|
0
|
|
|
|
|
0
|
delete_unsaved_hashINC($package); |
8236
|
|
|
|
|
|
|
} |
8237
|
0
|
0
|
|
|
|
0
|
if (can_delete($package)) { |
|
|
0
|
|
|
|
|
|
8238
|
0
|
0
|
|
|
|
0
|
warn "Delete $package\n" if $debug{pkg}; |
8239
|
0
|
|
|
|
|
0
|
return $include_package{$package} = 0; |
8240
|
|
|
|
|
|
|
} elsif (! exists $all_bc_deps{$package}) { # and not in @deps |
8241
|
0
|
0
|
|
|
|
0
|
warn "Keep $package\n" if $debug{pkg}; |
8242
|
0
|
|
|
|
|
0
|
return $include_package{$package} = 1; |
8243
|
|
|
|
|
|
|
} else { # in @deps |
8244
|
|
|
|
|
|
|
# warn "Ignore $package\n" if $debug{pkg}; |
8245
|
0
|
|
|
|
|
0
|
return; |
8246
|
|
|
|
|
|
|
} |
8247
|
|
|
|
|
|
|
} |
8248
|
|
|
|
|
|
|
|
8249
|
|
|
|
|
|
|
sub inc_packname { |
8250
|
225
|
|
|
225
|
0
|
174
|
my $package = shift; |
8251
|
|
|
|
|
|
|
# See below at the reverse packname_inc: utf8 => utf8.pm + utf8_heavy.pl |
8252
|
225
|
|
|
|
|
457
|
$package =~ s/\:\:/\//g; |
8253
|
225
|
|
|
|
|
193
|
$package .= '.pm'; |
8254
|
225
|
|
|
|
|
241
|
return $package; |
8255
|
|
|
|
|
|
|
} |
8256
|
|
|
|
|
|
|
|
8257
|
|
|
|
|
|
|
sub packname_inc { |
8258
|
0
|
|
|
0
|
0
|
0
|
my $package = shift; |
8259
|
0
|
|
|
|
|
0
|
$package =~ s/\//::/g; |
8260
|
0
|
0
|
|
|
|
0
|
if ($package =~ /^(Config_git\.pl|Config_heavy.pl)$/) { |
8261
|
0
|
|
|
|
|
0
|
return 'Config'; |
8262
|
|
|
|
|
|
|
} |
8263
|
0
|
0
|
|
|
|
0
|
if ($package eq 'utf8_heavy.pl') { |
8264
|
0
|
|
|
|
|
0
|
return 'utf8'; |
8265
|
|
|
|
|
|
|
} |
8266
|
0
|
|
|
|
|
0
|
$package =~ s/\.p[lm]$//; |
8267
|
0
|
|
|
|
|
0
|
return $package; |
8268
|
|
|
|
|
|
|
} |
8269
|
|
|
|
|
|
|
|
8270
|
|
|
|
|
|
|
sub delete_unsaved_hashINC { |
8271
|
225
|
|
|
225
|
0
|
171
|
my $package = shift; |
8272
|
225
|
|
|
|
|
254
|
my $incpack = inc_packname($package); |
8273
|
|
|
|
|
|
|
# Not already saved package, so it is not loaded again at run-time. |
8274
|
225
|
50
|
|
|
|
465
|
return if $dumped_package{$package}; |
8275
|
|
|
|
|
|
|
# Never delete external packages, but this check is done before |
8276
|
225
|
0
|
33
|
|
|
893
|
return if $package =~ /^DynaLoader|XSLoader$/ |
|
|
|
33
|
|
|
|
|
8277
|
|
|
|
|
|
|
and defined $use_xsloader |
8278
|
|
|
|
|
|
|
and $use_xsloader == 0; |
8279
|
225
|
50
|
33
|
|
|
449
|
return if $^O eq 'MSWin32' and $package =~ /^Carp|File::Basename$/; |
8280
|
225
|
|
|
|
|
337
|
$include_package{$package} = 0; |
8281
|
225
|
50
|
|
|
|
328
|
if ($curINC{$incpack}) { |
8282
|
|
|
|
|
|
|
#warn "Deleting $package from \%INC\n" if $debug{pkg}; |
8283
|
0
|
0
|
|
|
|
0
|
$savINC{$incpack} = $curINC{$incpack} if !$savINC{$incpack}; |
8284
|
0
|
|
|
|
|
0
|
$curINC{$incpack} = undef; |
8285
|
0
|
|
|
|
|
0
|
delete $curINC{$incpack}; |
8286
|
|
|
|
|
|
|
} |
8287
|
|
|
|
|
|
|
} |
8288
|
|
|
|
|
|
|
|
8289
|
|
|
|
|
|
|
sub add_hashINC { |
8290
|
0
|
|
|
0
|
0
|
0
|
my $package = shift; |
8291
|
0
|
|
|
|
|
0
|
my $incpack = inc_packname($package); |
8292
|
0
|
|
|
|
|
0
|
$include_package{$package} = 1; |
8293
|
0
|
0
|
|
|
|
0
|
unless ($curINC{$incpack}) { |
8294
|
0
|
0
|
|
|
|
0
|
if ($savINC{$incpack}) { |
8295
|
0
|
0
|
|
|
|
0
|
warn "Adding $package to \%INC (again)\n" if $debug{pkg}; |
8296
|
0
|
|
|
|
|
0
|
$curINC{$incpack} = $savINC{$incpack}; |
8297
|
|
|
|
|
|
|
# need to check xsub |
8298
|
0
|
0
|
|
|
|
0
|
$use_xsloader = 1 if $package =~ /^DynaLoader|XSLoader$/; |
8299
|
|
|
|
|
|
|
} else { |
8300
|
0
|
0
|
|
|
|
0
|
warn "Adding $package to \%INC\n" if $debug{pkg}; |
8301
|
0
|
|
|
|
|
0
|
for (@INC) { |
8302
|
0
|
|
|
|
|
0
|
my $p = $_.'/'.$incpack; |
8303
|
0
|
0
|
|
|
|
0
|
if (-e $p) { $curINC{$incpack} = $p; last; } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
8304
|
|
|
|
|
|
|
} |
8305
|
0
|
0
|
|
|
|
0
|
$curINC{$incpack} = $incpack unless $curINC{$incpack}; |
8306
|
|
|
|
|
|
|
} |
8307
|
|
|
|
|
|
|
} |
8308
|
|
|
|
|
|
|
} |
8309
|
|
|
|
|
|
|
|
8310
|
|
|
|
|
|
|
sub walkpackages { |
8311
|
0
|
|
|
0
|
0
|
0
|
my ( $symref, $recurse, $prefix ) = @_; |
8312
|
55
|
|
|
55
|
|
265
|
no strict 'vars'; |
|
55
|
|
|
|
|
81
|
|
|
55
|
|
|
|
|
10165
|
|
8313
|
0
|
0
|
|
|
|
0
|
$prefix = '' unless defined $prefix; |
8314
|
|
|
|
|
|
|
# check if already deleted - failed since 5.15.2 |
8315
|
0
|
0
|
|
|
|
0
|
return if $savINC{inc_packname(substr($prefix,0,-2))}; |
8316
|
0
|
|
|
|
|
0
|
for my $sym (sort keys %$symref) { |
8317
|
0
|
|
|
|
|
0
|
my $ref = $symref->{$sym}; |
8318
|
0
|
0
|
|
|
|
0
|
next unless $ref; |
8319
|
0
|
|
|
|
|
0
|
local (*glob); |
8320
|
0
|
|
|
|
|
0
|
*glob = $ref; |
8321
|
0
|
0
|
|
|
|
0
|
if ( $sym =~ /::$/ ) { |
8322
|
0
|
|
|
|
|
0
|
$sym = $prefix . $sym; |
8323
|
0
|
0
|
0
|
|
|
0
|
warn("Walkpackages $sym\n") if $debug{pkg} and $debug{walk}; |
8324
|
|
|
|
|
|
|
# This walker skips main subs to avoid recursion into O compiler subs again |
8325
|
|
|
|
|
|
|
# and main syms are already handled |
8326
|
0
|
0
|
0
|
|
|
0
|
if ( $sym ne "main::" && $sym ne "::" && &$recurse($sym) ) { |
|
|
|
0
|
|
|
|
|
8327
|
0
|
|
|
|
|
0
|
walkpackages( \%glob, $recurse, $sym ); |
8328
|
|
|
|
|
|
|
} |
8329
|
|
|
|
|
|
|
} |
8330
|
|
|
|
|
|
|
} |
8331
|
|
|
|
|
|
|
} |
8332
|
|
|
|
|
|
|
|
8333
|
|
|
|
|
|
|
sub save_unused_subs { |
8334
|
55
|
|
|
55
|
|
249
|
no strict qw(refs); |
|
55
|
|
|
|
|
76
|
|
|
55
|
|
|
|
|
72372
|
|
8335
|
0
|
|
|
0
|
0
|
0
|
my %sav_debug; |
8336
|
0
|
0
|
|
|
|
0
|
if ( $debug{unused} ) { |
8337
|
0
|
|
|
|
|
0
|
%sav_debug = %debug; |
8338
|
0
|
|
|
|
|
0
|
%debug = (); |
8339
|
|
|
|
|
|
|
} |
8340
|
0
|
0
|
|
|
|
0
|
my $main = $module ? $module."::" : "main::"; |
8341
|
|
|
|
|
|
|
|
8342
|
|
|
|
|
|
|
# -fwalkall: better strategy for compile-time added and required packages: |
8343
|
|
|
|
|
|
|
# loop savecv and check pkg cache for new pkgs. |
8344
|
|
|
|
|
|
|
# if so loop again with those new pkgs only, until the list of new pkgs is empty |
8345
|
0
|
|
|
|
|
0
|
my ($walkall_cnt, @init_unused, @unused, @dumped) = (0); |
8346
|
|
|
|
|
|
|
#do |
8347
|
0
|
|
|
|
|
0
|
@init_unused = grep { $include_package{$_} } keys %include_package; |
|
0
|
|
|
|
|
0
|
|
8348
|
0
|
0
|
|
|
|
0
|
if ($verbose) { |
8349
|
0
|
0
|
|
|
|
0
|
warn "Prescan for unused subs in $main " . ($sav_debug{unused} ? " (silent)\n" : "\n"); |
8350
|
|
|
|
|
|
|
} |
8351
|
|
|
|
|
|
|
# XXX TODO better strategy for compile-time added and required packages: |
8352
|
|
|
|
|
|
|
# loop savecv and check pkg cache for new pkgs. |
8353
|
|
|
|
|
|
|
# if so loop again with those new pkgs only, until the list of new pkgs is empty |
8354
|
0
|
|
|
|
|
0
|
descend_marked_unused(); |
8355
|
0
|
0
|
|
|
|
0
|
walkpackages( \%{$main}, \&should_save, $main eq 'main::' ? undef : $main ); |
|
0
|
|
|
|
|
0
|
|
8356
|
0
|
0
|
|
|
|
0
|
warn "Saving unused subs in $main" . ($sav_debug{unused} ? " (silent)\n" : "\n") |
|
|
0
|
|
|
|
|
|
8357
|
|
|
|
|
|
|
if $verbose; |
8358
|
0
|
|
|
|
|
0
|
walksymtable( \%{$main}, "savecv", \&should_save ); |
|
0
|
|
|
|
|
0
|
|
8359
|
0
|
|
|
|
|
0
|
@unused = grep { $include_package{$_} } keys %include_package; |
|
0
|
|
|
|
|
0
|
|
8360
|
0
|
0
|
|
|
|
0
|
@dumped = grep { $dumped_package{$_} and $_ ne 'main' } keys %dumped_package; |
|
0
|
|
|
|
|
0
|
|
8361
|
0
|
0
|
|
|
|
0
|
warn sprintf("old unused: %d, new: %d, dumped: %d\n", scalar @init_unused, scalar @unused, scalar @dumped) |
8362
|
|
|
|
|
|
|
if $verbose; |
8363
|
0
|
0
|
|
|
|
0
|
if (!$B::C::walkall) { |
8364
|
0
|
|
|
|
|
0
|
@unused = @init_unused = (); |
8365
|
|
|
|
|
|
|
} else { |
8366
|
0
|
|
|
|
|
0
|
my $done; |
8367
|
0
|
|
0
|
|
|
0
|
do { |
8368
|
0
|
|
|
|
|
0
|
$done = dump_rest(); |
8369
|
0
|
|
|
|
|
0
|
@unused = grep { $include_package{$_} } keys %include_package; |
|
0
|
|
|
|
|
0
|
|
8370
|
0
|
0
|
|
|
|
0
|
@dumped = grep { $dumped_package{$_} and $_ ne 'main' } keys %dumped_package; |
|
0
|
|
|
|
|
0
|
|
8371
|
|
|
|
|
|
|
} while @unused > @dumped and $done; |
8372
|
0
|
0
|
|
|
|
0
|
last if $walkall_cnt++ > 3; |
8373
|
|
|
|
|
|
|
} |
8374
|
|
|
|
|
|
|
#} while @unused > @init_unused; |
8375
|
|
|
|
|
|
|
|
8376
|
0
|
0
|
|
|
|
0
|
if ( $sav_debug{unused} ) { |
8377
|
0
|
|
|
|
|
0
|
%debug = %sav_debug; |
8378
|
|
|
|
|
|
|
} |
8379
|
|
|
|
|
|
|
|
8380
|
|
|
|
|
|
|
# If any m//i is run-time loaded we'll get a "Undefined subroutine utf8::SWASHNEW" |
8381
|
|
|
|
|
|
|
# With -fno-fold we don't insist on loading utf8_heavy and Carp. |
8382
|
|
|
|
|
|
|
# Until it is compile-time required. |
8383
|
0
|
0
|
0
|
|
|
0
|
if (exists($INC{'unicore/To/Title.pl'}) |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
8384
|
|
|
|
|
|
|
or exists($INC{'unicore/To/Tc.pl'}) #242 |
8385
|
|
|
|
|
|
|
or exists($INC{'unicore/Heavy.pl'}) #242 |
8386
|
|
|
|
|
|
|
or ($savINC{'utf8_heavy.pl'} and ($B::C::fold or exists($savINC{'utf8.pm'})))) { |
8387
|
0
|
0
|
|
|
|
0
|
require "utf8.pm" unless $savINC{"utf8.pm"}; |
8388
|
0
|
|
|
|
|
0
|
mark_package('utf8'); |
8389
|
0
|
|
|
|
|
0
|
load_utf8_heavy(); |
8390
|
|
|
|
|
|
|
} |
8391
|
|
|
|
|
|
|
# run-time Carp |
8392
|
|
|
|
|
|
|
# With -fno-warnings we don't insist on initializing warnings::register_categories and Carp. |
8393
|
|
|
|
|
|
|
# Until it is compile-time required. |
8394
|
|
|
|
|
|
|
# 68KB exe size 32-bit |
8395
|
0
|
0
|
0
|
|
|
0
|
if ($] >= 5.013005 and ($B::C::warnings and exists $dumped_package{Carp})) { |
|
|
|
0
|
|
|
|
|
8396
|
0
|
|
|
|
|
0
|
svref_2object( \&{"warnings\::register_categories"} )->save; # 68Kb 32bit |
|
0
|
|
|
|
|
0
|
|
8397
|
0
|
|
|
|
|
0
|
add_hashINC("warnings"); |
8398
|
0
|
|
|
|
|
0
|
add_hashINC("warnings::register"); |
8399
|
|
|
|
|
|
|
} |
8400
|
|
|
|
|
|
|
#196 missing INIT |
8401
|
0
|
0
|
0
|
|
|
0
|
if ($xsub{EV} and $dumped_package{EV} and $EV::VERSION le '4.21') { |
|
|
|
0
|
|
|
|
|
8402
|
0
|
|
|
|
|
0
|
$init2->add_eval |
8403
|
|
|
|
|
|
|
( |
8404
|
|
|
|
|
|
|
q(EV::default_loop() or ) |
8405
|
|
|
|
|
|
|
.q(die 'EV: cannot initialise libev backend. bad $ENV{LIBEV_FLAGS}?';) |
8406
|
|
|
|
|
|
|
); |
8407
|
|
|
|
|
|
|
} |
8408
|
0
|
0
|
|
|
|
0
|
if ($use_xsloader) { |
8409
|
0
|
|
|
|
|
0
|
force_saving_xsloader(); |
8410
|
0
|
|
|
|
|
0
|
mark_package('Config', 1); # required by Dynaloader and special cased previously |
8411
|
|
|
|
|
|
|
} |
8412
|
|
|
|
|
|
|
} |
8413
|
|
|
|
|
|
|
|
8414
|
|
|
|
|
|
|
sub inc_cleanup { |
8415
|
0
|
|
|
0
|
0
|
0
|
my $rec_cnt = shift; |
8416
|
|
|
|
|
|
|
# %INC sanity check issue 89: |
8417
|
|
|
|
|
|
|
# omit unused, unsaved packages, so that at least run-time require will pull them in. |
8418
|
0
|
|
|
|
|
0
|
my @deleted_inc; |
8419
|
0
|
0
|
|
|
|
0
|
if ($CPERL51) { |
8420
|
0
|
|
|
|
|
0
|
for (qw(strict coretypes DynaLoader XSLoader)) { |
8421
|
0
|
|
|
|
|
0
|
$dumped_package{$_}++; |
8422
|
0
|
|
|
|
|
0
|
$curINC{$_.".pm"} = $INC{$_.".pm"}; |
8423
|
|
|
|
|
|
|
} |
8424
|
|
|
|
|
|
|
} |
8425
|
0
|
|
|
|
|
0
|
for my $package (sort keys %INC) { |
8426
|
0
|
|
|
|
|
0
|
my $pkg = packname_inc($package); |
8427
|
0
|
0
|
0
|
|
|
0
|
if ($package =~ /^(Config_git\.pl|Config_heavy.pl)$/ and !$dumped_package{'Config'}) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
8428
|
0
|
|
|
|
|
0
|
delete $curINC{$package}; |
8429
|
|
|
|
|
|
|
} elsif ($package eq 'utf8_heavy.pl' and !$include_package{'utf8'}) { |
8430
|
0
|
|
|
|
|
0
|
delete $curINC{$package}; |
8431
|
0
|
|
|
|
|
0
|
delete_unsaved_hashINC('utf8'); |
8432
|
|
|
|
|
|
|
} elsif (!$B::C::walkall and !exists $dumped_package{$pkg}) { |
8433
|
0
|
|
|
|
|
0
|
delete_unsaved_hashINC($pkg); |
8434
|
0
|
|
|
|
|
0
|
push @deleted_inc, $pkg; |
8435
|
|
|
|
|
|
|
} |
8436
|
|
|
|
|
|
|
} |
8437
|
|
|
|
|
|
|
# sync %curINC deletions back to %INC |
8438
|
0
|
|
|
|
|
0
|
for my $p (sort keys %INC) { |
8439
|
0
|
0
|
|
|
|
0
|
if (!exists $curINC{$p}) { |
8440
|
0
|
|
|
|
|
0
|
delete $INC{$p}; |
8441
|
0
|
|
|
|
|
0
|
push @deleted_inc, $p; |
8442
|
|
|
|
|
|
|
} |
8443
|
|
|
|
|
|
|
} |
8444
|
0
|
0
|
0
|
|
|
0
|
if ($debug{pkg} and $verbose) { |
8445
|
0
|
|
|
|
|
0
|
warn "\%include_package: ".join(" ",grep{$include_package{$_}} sort keys %include_package)."\n"; |
|
0
|
|
|
|
|
0
|
|
8446
|
0
|
|
|
|
|
0
|
warn "\%dumped_package: ".join(" ",grep{$dumped_package{$_}} sort keys %dumped_package)."\n"; |
|
0
|
|
|
|
|
0
|
|
8447
|
|
|
|
|
|
|
} |
8448
|
|
|
|
|
|
|
# issue 340,350: do only on -fwalkall? do it in the main walker step |
8449
|
|
|
|
|
|
|
# as in branch walkall-early? |
8450
|
0
|
0
|
|
|
|
0
|
if ($B::C::walkall) { |
8451
|
0
|
|
|
|
|
0
|
my $again = dump_rest(); |
8452
|
0
|
0
|
0
|
|
|
0
|
inc_cleanup($rec_cnt++) if $again and $rec_cnt < 2; # maximal 3 times |
8453
|
|
|
|
|
|
|
} |
8454
|
|
|
|
|
|
|
# final cleanup |
8455
|
0
|
|
|
|
|
0
|
for my $p (sort keys %INC) { |
8456
|
0
|
|
|
|
|
0
|
my $pkg = packname_inc($p); |
8457
|
0
|
0
|
|
|
|
0
|
delete_unsaved_hashINC($pkg) unless exists $dumped_package{$pkg}; |
8458
|
|
|
|
|
|
|
# sync %curINC deletions back to %INC |
8459
|
0
|
0
|
0
|
|
|
0
|
if (!exists $curINC{$p} and exists $INC{$p}) { |
8460
|
0
|
|
|
|
|
0
|
delete $INC{$p}; |
8461
|
0
|
|
|
|
|
0
|
push @deleted_inc, $p; |
8462
|
|
|
|
|
|
|
} |
8463
|
|
|
|
|
|
|
} |
8464
|
0
|
0
|
0
|
|
|
0
|
if ($debug{pkg} and $verbose) { |
8465
|
0
|
0
|
|
|
|
0
|
warn "Deleted from \%INC: ".join(" ",@deleted_inc)."\n" if @deleted_inc; |
8466
|
0
|
|
|
|
|
0
|
my @inc = grep !/auto\/.+\.(al|ix)$/, sort keys %INC; |
8467
|
0
|
|
|
|
|
0
|
warn "\%INC: ".join(" ",@inc)."\n"; |
8468
|
|
|
|
|
|
|
} |
8469
|
|
|
|
|
|
|
} |
8470
|
|
|
|
|
|
|
|
8471
|
|
|
|
|
|
|
sub dump_rest { |
8472
|
0
|
|
|
0
|
0
|
0
|
my $again; |
8473
|
0
|
0
|
0
|
|
|
0
|
warn "dump_rest:\n" if $verbose or $debug{pkg}; |
8474
|
|
|
|
|
|
|
#for my $p (sort keys %INC) { |
8475
|
|
|
|
|
|
|
#} |
8476
|
0
|
|
|
|
|
0
|
for my $p (sort keys %include_package) { |
8477
|
0
|
|
|
|
|
0
|
$p =~ s/^main:://; |
8478
|
0
|
0
|
0
|
|
|
0
|
if ($include_package{$p} and !exists $dumped_package{$p} |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
8479
|
|
|
|
|
|
|
and !$static_core_pkg{$p} |
8480
|
|
|
|
|
|
|
and $p !~ /^(threads|main|__ANON__|PerlIO)$/ |
8481
|
|
|
|
|
|
|
) |
8482
|
|
|
|
|
|
|
{ |
8483
|
0
|
0
|
0
|
|
|
0
|
if ($p eq 'warnings::register' and !$B::C::warnings) { |
8484
|
0
|
|
|
|
|
0
|
delete_unsaved_hashINC('warnings::register'); |
8485
|
0
|
|
|
|
|
0
|
next; |
8486
|
|
|
|
|
|
|
} |
8487
|
0
|
|
|
|
|
0
|
$again++; |
8488
|
0
|
0
|
0
|
|
|
0
|
warn "$p marked but not saved, save now\n" if $verbose or $debug{pkg}; |
8489
|
|
|
|
|
|
|
# mark_package( $p, 1); |
8490
|
|
|
|
|
|
|
#eval { |
8491
|
|
|
|
|
|
|
# require(inc_packname($p)) && add_hashINC( $p ); |
8492
|
|
|
|
|
|
|
#} unless $savINC{inc_packname($p)}; |
8493
|
0
|
|
|
|
|
0
|
walk_syms( $p ); |
8494
|
|
|
|
|
|
|
} |
8495
|
|
|
|
|
|
|
} |
8496
|
0
|
|
|
|
|
0
|
$again; |
8497
|
|
|
|
|
|
|
} |
8498
|
|
|
|
|
|
|
|
8499
|
|
|
|
|
|
|
my @made_c3; |
8500
|
|
|
|
|
|
|
|
8501
|
|
|
|
|
|
|
sub make_c3 { |
8502
|
0
|
0
|
|
0
|
0
|
0
|
my $package = shift or die; |
8503
|
|
|
|
|
|
|
|
8504
|
0
|
0
|
|
|
|
0
|
return if ( grep { $_ eq $package } @made_c3 ); |
|
0
|
|
|
|
|
0
|
|
8505
|
0
|
|
|
|
|
0
|
push @made_c3, $package; |
8506
|
|
|
|
|
|
|
|
8507
|
0
|
|
|
|
|
0
|
mark_package( 'mro', 1 ); |
8508
|
0
|
|
|
|
|
0
|
mark_package($package); |
8509
|
0
|
|
0
|
|
|
0
|
my $isa_packages = mro::get_linear_isa($package) || []; |
8510
|
0
|
|
|
|
|
0
|
foreach my $isa (@$isa_packages) { |
8511
|
0
|
|
|
|
|
0
|
mark_package($isa); |
8512
|
|
|
|
|
|
|
} |
8513
|
0
|
0
|
0
|
|
|
0
|
warn "set c3 for $package\n" if $verbose or $debug{pkg}; |
8514
|
|
|
|
|
|
|
|
8515
|
|
|
|
|
|
|
## from setmro.xs: |
8516
|
|
|
|
|
|
|
# classname = ST(0); |
8517
|
|
|
|
|
|
|
# class_stash = gv_stashsv(classname, GV_ADD); |
8518
|
|
|
|
|
|
|
# meta = HvMROMETA(class_stash); |
8519
|
|
|
|
|
|
|
# Perl_mro_set_mro(aTHX_ meta, ST(1)); |
8520
|
|
|
|
|
|
|
|
8521
|
0
|
|
|
|
|
0
|
$init2->add( sprintf( 'Perl_mro_set_mro(aTHX_ HvMROMETA(%s), newSVpvs("c3"));', |
8522
|
|
|
|
|
|
|
savestashpv($package) ) ); |
8523
|
|
|
|
|
|
|
} |
8524
|
|
|
|
|
|
|
|
8525
|
|
|
|
|
|
|
# global state only, unneeded for modules |
8526
|
|
|
|
|
|
|
sub save_context { |
8527
|
|
|
|
|
|
|
# forbid run-time extends of curpad syms, names and INC |
8528
|
0
|
0
|
|
0
|
0
|
0
|
warn "save context:\n" if $verbose; |
8529
|
0
|
|
|
|
|
0
|
my $warner = $SIG{__WARN__}; |
8530
|
0
|
0
|
|
|
|
0
|
save_sig($warner) if $B::C::save_sig; |
8531
|
|
|
|
|
|
|
# honour -w and %^H |
8532
|
0
|
|
|
|
|
0
|
$init->add( "/* honor -w */", |
8533
|
|
|
|
|
|
|
sprintf "PL_dowarn = ( %s ) ? G_WARN_ON : G_WARN_OFF;", $^W ); |
8534
|
0
|
0
|
|
|
|
0
|
if ($^{TAINT}) { |
8535
|
|
|
|
|
|
|
$init->add( "/* honor -Tt */", |
8536
|
|
|
|
|
|
|
"PL_tainting = TRUE;", |
8537
|
|
|
|
|
|
|
# -T -1 false, -t 1 true |
8538
|
0
|
0
|
|
|
|
0
|
"PL_taint_warn = ".($^{TAINT} < 0 ? "FALSE" : "TRUE").";"); |
8539
|
|
|
|
|
|
|
} |
8540
|
|
|
|
|
|
|
|
8541
|
0
|
0
|
|
|
|
0
|
if ($PERL510) { |
8542
|
|
|
|
|
|
|
# need to mark assign c3 to %main::. no need to assign the default dfs |
8543
|
0
|
0
|
0
|
|
|
0
|
if (is_using_mro() && mro::get_mro("main") eq 'c3') { |
8544
|
0
|
|
|
|
|
0
|
make_c3('main'); |
8545
|
|
|
|
|
|
|
} |
8546
|
|
|
|
|
|
|
# Tie::Hash::NamedCapture is added for *+ *-, Errno for *! |
8547
|
|
|
|
|
|
|
#no strict 'refs'; |
8548
|
|
|
|
|
|
|
#if ( defined(objsym(svref_2object(\*{'main::+'}))) or defined(objsym(svref_2object(\*{'main::-'}))) ) { |
8549
|
|
|
|
|
|
|
# use strict 'refs'; |
8550
|
|
|
|
|
|
|
# if (!$include_package{'Tie::Hash::NamedCapture'}) { |
8551
|
|
|
|
|
|
|
# $init->add("/* force saving of Tie::Hash::NamedCapture */"); |
8552
|
|
|
|
|
|
|
# if ($] >= 5.014) { |
8553
|
|
|
|
|
|
|
# mark_package('Config', 1); # DynaLoader needs Config to set the EGV |
8554
|
|
|
|
|
|
|
# walk_syms('Config'); |
8555
|
|
|
|
|
|
|
# svref_2object(\&{'Tie::Hash::NamedCapture::bootstrap'})->save; |
8556
|
|
|
|
|
|
|
# } |
8557
|
|
|
|
|
|
|
# mark_package('Tie::Hash::NamedCapture', 1); |
8558
|
|
|
|
|
|
|
# } # else already included |
8559
|
|
|
|
|
|
|
#} else { |
8560
|
|
|
|
|
|
|
# use strict 'refs'; |
8561
|
|
|
|
|
|
|
# delete_unsaved_hashINC('Tie::Hash::NamedCapture'); |
8562
|
|
|
|
|
|
|
#} |
8563
|
55
|
|
|
55
|
|
275
|
no strict 'refs'; |
|
55
|
|
|
|
|
74
|
|
|
55
|
|
|
|
|
2933
|
|
8564
|
0
|
0
|
|
|
|
0
|
if ( defined(objsym(svref_2object(\*{'main::!'}))) ) { |
|
0
|
|
|
|
|
0
|
|
8565
|
55
|
|
|
55
|
|
221
|
use strict 'refs'; |
|
55
|
|
|
|
|
69
|
|
|
55
|
|
|
|
|
3768
|
|
8566
|
0
|
0
|
|
|
|
0
|
if (!$include_package{'Errno'}) { |
8567
|
0
|
|
|
|
|
0
|
$init->add("/* force saving of Errno */"); |
8568
|
0
|
|
|
|
|
0
|
mark_package('Config', 1); |
8569
|
0
|
|
|
|
|
0
|
walk_syms('Config'); |
8570
|
0
|
|
|
|
|
0
|
mark_package('Errno', 1); |
8571
|
0
|
|
|
|
|
0
|
svref_2object(\&{'Errno::bootstrap'})->save; |
|
0
|
|
|
|
|
0
|
|
8572
|
|
|
|
|
|
|
} # else already included |
8573
|
|
|
|
|
|
|
} else { |
8574
|
55
|
|
|
55
|
|
205
|
use strict 'refs'; |
|
55
|
|
|
|
|
79
|
|
|
55
|
|
|
|
|
9878
|
|
8575
|
0
|
|
|
|
|
0
|
delete_unsaved_hashINC('Errno'); |
8576
|
|
|
|
|
|
|
} |
8577
|
|
|
|
|
|
|
} |
8578
|
|
|
|
|
|
|
|
8579
|
0
|
|
|
|
|
0
|
my ($curpad_nam, $curpad_sym); |
8580
|
|
|
|
|
|
|
{ |
8581
|
|
|
|
|
|
|
# Record comppad sv's names, may not be static |
8582
|
0
|
|
|
|
|
0
|
local $B::C::const_strings = 0; |
|
0
|
|
|
|
|
0
|
|
8583
|
0
|
|
|
|
|
0
|
$init->add("/* curpad names */"); |
8584
|
0
|
0
|
|
|
|
0
|
warn "curpad names:\n" if $verbose; |
8585
|
0
|
|
|
|
|
0
|
$curpad_nam = ( comppadlist->ARRAY )[0]->save('curpad_name'); |
8586
|
0
|
0
|
|
|
|
0
|
warn "curpad syms:\n" if $verbose; |
8587
|
0
|
|
|
|
|
0
|
$init->add("/* curpad syms */"); |
8588
|
0
|
|
|
|
|
0
|
$curpad_sym = ( comppadlist->ARRAY )[1]->save('curpad_syms'); |
8589
|
|
|
|
|
|
|
} |
8590
|
0
|
|
|
|
|
0
|
my ($inc_hv, $inc_av); |
8591
|
|
|
|
|
|
|
{ |
8592
|
0
|
0
|
|
|
|
0
|
local $B::C::const_strings = 1 if $B::C::ro_inc; |
|
0
|
|
|
|
|
0
|
|
8593
|
0
|
0
|
|
|
|
0
|
warn "\%INC and \@INC:\n" if $verbose; |
8594
|
0
|
|
|
|
|
0
|
$init->add('/* %INC */'); |
8595
|
0
|
|
|
|
|
0
|
inc_cleanup(0); |
8596
|
0
|
|
|
|
|
0
|
my $inc_gv = svref_2object( \*main::INC ); |
8597
|
0
|
|
|
|
|
0
|
$inc_hv = $inc_gv->HV->save('main::INC'); |
8598
|
0
|
|
|
|
|
0
|
$init->add('/* @INC */'); |
8599
|
0
|
|
|
|
|
0
|
$inc_av = $inc_gv->AV->save('main::INC'); |
8600
|
|
|
|
|
|
|
} |
8601
|
|
|
|
|
|
|
# ensure all included @ISA's are stored (#308), and also assign c3 (#325) |
8602
|
0
|
|
|
|
|
0
|
my @saved_isa; |
8603
|
0
|
|
|
|
|
0
|
for my $p (sort keys %include_package) { |
8604
|
55
|
|
|
55
|
|
215
|
no strict 'refs'; |
|
55
|
|
|
|
|
78
|
|
|
55
|
|
|
|
|
34627
|
|
8605
|
0
|
0
|
0
|
|
|
0
|
if ($include_package{$p} and exists(${$p.'::'}{ISA}) and ${$p.'::'}{ISA}) { |
|
0
|
|
0
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
8606
|
0
|
|
|
|
|
0
|
push @saved_isa, $p; |
8607
|
0
|
|
|
|
|
0
|
svref_2object( \@{$p.'::ISA'} )->save($p.'::ISA'); |
|
0
|
|
|
|
|
0
|
|
8608
|
0
|
0
|
0
|
|
|
0
|
if ($PERL510 and is_using_mro() && mro::get_mro($p) eq 'c3') { |
|
|
|
0
|
|
|
|
|
8609
|
0
|
|
|
|
|
0
|
make_c3($p); |
8610
|
|
|
|
|
|
|
} |
8611
|
|
|
|
|
|
|
} |
8612
|
|
|
|
|
|
|
} |
8613
|
0
|
0
|
0
|
|
|
0
|
warn "Saved \@ISA for: ".join(" ",@saved_isa)."\n" if @saved_isa and ($verbose or $debug{pkg}); |
|
|
|
0
|
|
|
|
|
8614
|
0
|
|
|
|
|
0
|
$init->add( |
8615
|
|
|
|
|
|
|
"GvHV(PL_incgv) = $inc_hv;", |
8616
|
|
|
|
|
|
|
"GvAV(PL_incgv) = $inc_av;", |
8617
|
|
|
|
|
|
|
"PL_curpad = AvARRAY($curpad_sym);", |
8618
|
|
|
|
|
|
|
"PL_comppad = $curpad_sym;", # fixed "panic: illegal pad" |
8619
|
|
|
|
|
|
|
"PL_stack_sp = PL_stack_base;" # reset stack (was 1++) |
8620
|
|
|
|
|
|
|
); |
8621
|
0
|
0
|
|
|
|
0
|
if ($] < 5.017005) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
8622
|
0
|
|
|
|
|
0
|
$init->add( |
8623
|
|
|
|
|
|
|
"av_store((AV*)CvPADLIST(PL_main_cv), 0, SvREFCNT_inc_simple_NN($curpad_nam)); /* namepad */", |
8624
|
|
|
|
|
|
|
"av_store((AV*)CvPADLIST(PL_main_cv), 1, SvREFCNT_inc_simple_NN($curpad_sym)); /* curpad */"); |
8625
|
|
|
|
|
|
|
} elsif ($] < 5.019003) { |
8626
|
0
|
|
|
|
|
0
|
$init->add( |
8627
|
|
|
|
|
|
|
"PadlistARRAY(CvPADLIST(PL_main_cv))[0] = PL_comppad_name = (PAD*)SvREFCNT_inc_simple_NN($curpad_nam); /* namepad */", |
8628
|
|
|
|
|
|
|
"PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)SvREFCNT_inc_simple_NN($curpad_sym); /* curpad */"); |
8629
|
|
|
|
|
|
|
} elsif ($] < 5.022) { |
8630
|
0
|
|
|
|
|
0
|
$init->add( |
8631
|
|
|
|
|
|
|
"PadlistARRAY(CvPADLIST(PL_main_cv))[0] = PL_comppad_name = (PAD*)SvREFCNT_inc_simple_NN($curpad_nam); /* namepad */", |
8632
|
|
|
|
|
|
|
"PadnamelistMAXNAMED(PL_comppad_name) = AvFILL($curpad_nam);", |
8633
|
|
|
|
|
|
|
"PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)SvREFCNT_inc_simple_NN($curpad_sym); /* curpad */"); |
8634
|
|
|
|
|
|
|
} else { |
8635
|
0
|
|
|
|
|
0
|
$init->add( |
8636
|
|
|
|
|
|
|
"PadlistNAMES(CvPADLIST(PL_main_cv)) = PL_comppad_name = $curpad_nam; /* namepad */", |
8637
|
|
|
|
|
|
|
"PadlistARRAY(CvPADLIST(PL_main_cv))[1] = (PAD*)$curpad_sym; /* curpad */"); |
8638
|
|
|
|
|
|
|
} |
8639
|
0
|
0
|
|
|
|
0
|
if ($] < 5.017) { |
8640
|
0
|
|
|
|
|
0
|
my $amagic_generate = B::amagic_generation(); |
8641
|
0
|
0
|
|
|
|
0
|
warn "amagic_generation = $amagic_generate\n" if $verbose; |
8642
|
0
|
|
|
|
|
0
|
$init->add("PL_amagic_generation = $amagic_generate;"); |
8643
|
|
|
|
|
|
|
}; |
8644
|
|
|
|
|
|
|
} |
8645
|
|
|
|
|
|
|
|
8646
|
|
|
|
|
|
|
sub descend_marked_unused { |
8647
|
|
|
|
|
|
|
#if ($B::C::walkall) { |
8648
|
|
|
|
|
|
|
# for my $pack (keys %all_bc_deps) { |
8649
|
|
|
|
|
|
|
# mark_unused($pack, 0) if !exists $include_package{$pack} and !skip_pkg($pack); |
8650
|
|
|
|
|
|
|
# } |
8651
|
|
|
|
|
|
|
#} |
8652
|
0
|
|
|
0
|
0
|
0
|
foreach my $pack ( sort keys %INC ) { |
8653
|
0
|
|
|
|
|
0
|
my $p = packname_inc($pack); |
8654
|
0
|
0
|
0
|
|
|
0
|
mark_package($p) if !skip_pkg($p) and !$all_bc_deps{$p} and $pack !~ /(autosplit\.ix|\.al)$/; |
|
|
|
0
|
|
|
|
|
8655
|
|
|
|
|
|
|
} |
8656
|
0
|
0
|
0
|
|
|
0
|
if ($debug{pkg} and $verbose) { |
8657
|
0
|
|
|
|
|
0
|
warn "\%include_package: ".join(" ",grep{$include_package{$_}} sort keys %include_package)."\n"; |
|
0
|
|
|
|
|
0
|
|
8658
|
0
|
|
|
|
|
0
|
warn "\%skip_package: ".join(" ",sort keys %skip_package)."\n"; |
8659
|
|
|
|
|
|
|
} |
8660
|
0
|
|
|
|
|
0
|
foreach my $pack ( sort keys %include_package ) { |
8661
|
0
|
0
|
|
|
|
0
|
mark_package($pack) unless skip_pkg($pack); |
8662
|
|
|
|
|
|
|
} |
8663
|
|
|
|
|
|
|
warn "descend_marked_unused: " |
8664
|
0
|
0
|
|
|
|
0
|
.join(" ",sort keys %include_package)."\n" if $debug{pkg}; |
8665
|
|
|
|
|
|
|
} |
8666
|
|
|
|
|
|
|
|
8667
|
|
|
|
|
|
|
sub save_main { |
8668
|
|
|
|
|
|
|
|
8669
|
0
|
0
|
|
0
|
0
|
0
|
warn "Starting compile\n" if $verbose; |
8670
|
0
|
0
|
|
|
|
0
|
warn "Walking tree\n" if $verbose; |
8671
|
0
|
|
|
|
|
0
|
%Exporter::Cache = (); # avoid B::C and B symbols being stored |
8672
|
0
|
0
|
|
|
|
0
|
_delete_macros_vendor_undefined() if $PERL512; |
8673
|
0
|
|
|
|
|
0
|
set_curcv B::main_cv; |
8674
|
0
|
|
|
|
|
0
|
seek( STDOUT, 0, 0 ); #exclude print statements in BEGIN{} into output |
8675
|
0
|
0
|
|
|
|
0
|
binmode( STDOUT, ':utf8' ) unless $PERL56; |
8676
|
|
|
|
|
|
|
|
8677
|
0
|
0
|
|
|
|
0
|
$verbose |
8678
|
|
|
|
|
|
|
? walkoptree_slow( main_root, "save" ) |
8679
|
|
|
|
|
|
|
: walkoptree( main_root, "save" ); |
8680
|
0
|
|
|
|
|
0
|
save_main_rest(); |
8681
|
|
|
|
|
|
|
} |
8682
|
|
|
|
|
|
|
|
8683
|
|
|
|
|
|
|
sub _delete_macros_vendor_undefined { |
8684
|
0
|
|
|
0
|
|
0
|
foreach my $class (qw(POSIX IO Fcntl Socket Exporter Errno)) { |
8685
|
55
|
|
|
55
|
|
251
|
no strict 'refs'; |
|
55
|
|
|
|
|
90
|
|
|
55
|
|
|
|
|
1365
|
|
8686
|
55
|
|
|
55
|
|
190
|
no strict 'subs'; |
|
55
|
|
|
|
|
68
|
|
|
55
|
|
|
|
|
1329
|
|
8687
|
55
|
|
|
55
|
|
204
|
no warnings 'uninitialized'; |
|
55
|
|
|
|
|
76
|
|
|
55
|
|
|
|
|
136549
|
|
8688
|
0
|
|
|
|
|
0
|
my $symtab = $class . '::'; |
8689
|
0
|
|
|
|
|
0
|
for my $symbol ( sort keys %$symtab ) { |
8690
|
0
|
0
|
0
|
|
|
0
|
next if $symbol !~ m{^[0-9A-Z_]+$} || $symbol =~ m{(?:^ISA$|^EXPORT|^DESTROY|^TIE|^VERSION|^AUTOLOAD|^BEGIN|^INIT|^__|^DELETE|^CLEAR|^STORE|^NEXTKEY|^FIRSTKEY|^FETCH|^EXISTS)}; |
8691
|
0
|
0
|
|
|
|
0
|
next if ref $symtab->{$symbol}; |
8692
|
0
|
|
|
|
|
0
|
local $@; |
8693
|
0
|
|
|
|
|
0
|
my $code = "$class\:\:$symbol();"; |
8694
|
0
|
|
|
|
|
0
|
eval $code; |
8695
|
0
|
0
|
|
|
|
0
|
if ( $@ =~ m{vendor has not defined} ) { |
8696
|
0
|
|
|
|
|
0
|
delete $symtab->{$symbol}; |
8697
|
0
|
|
|
|
|
0
|
next; |
8698
|
|
|
|
|
|
|
} |
8699
|
|
|
|
|
|
|
} |
8700
|
|
|
|
|
|
|
} |
8701
|
0
|
|
|
|
|
0
|
return 1; |
8702
|
|
|
|
|
|
|
} |
8703
|
|
|
|
|
|
|
|
8704
|
|
|
|
|
|
|
sub fixup_ppaddr { |
8705
|
|
|
|
|
|
|
# init op addrs must be the last action, otherwise |
8706
|
|
|
|
|
|
|
# some ops might not be initialized |
8707
|
|
|
|
|
|
|
# but it needs to happen before CALLREGCOMP, as a /i calls a compiled utf8::SWASHNEW |
8708
|
0
|
0
|
|
0
|
0
|
0
|
if ($B::C::optimize_ppaddr) { |
8709
|
0
|
|
|
|
|
0
|
foreach my $i (@op_sections) { |
8710
|
0
|
|
|
|
|
0
|
my $section = $$i; |
8711
|
0
|
|
|
|
|
0
|
my $num = $section->index; |
8712
|
0
|
0
|
|
|
|
0
|
next unless $num >= 0; |
8713
|
0
|
|
|
|
|
0
|
init_op_addr( $section->name, $num + 1 ); |
8714
|
|
|
|
|
|
|
} |
8715
|
|
|
|
|
|
|
} |
8716
|
|
|
|
|
|
|
} |
8717
|
|
|
|
|
|
|
|
8718
|
|
|
|
|
|
|
# save %SIG ( in case it was set in a BEGIN block ) |
8719
|
|
|
|
|
|
|
sub save_sig { |
8720
|
|
|
|
|
|
|
# local $SIG{__WARN__} = shift; |
8721
|
0
|
|
|
0
|
0
|
0
|
$init->no_split; |
8722
|
0
|
|
|
|
|
0
|
my @save_sig; |
8723
|
0
|
|
|
|
|
0
|
foreach my $k ( sort keys %SIG ) { |
8724
|
0
|
0
|
|
|
|
0
|
next unless ref $SIG{$k}; |
8725
|
0
|
|
|
|
|
0
|
my $cvref = svref_2object( \$SIG{$k} ); |
8726
|
0
|
0
|
0
|
|
|
0
|
next if ref($cvref) eq 'B::CV' and $cvref->FILE =~ m|B/C\.pm$|; # ignore B::C SIG warn handler |
8727
|
0
|
|
|
|
|
0
|
push @save_sig, [$k, $cvref]; |
8728
|
|
|
|
|
|
|
} |
8729
|
0
|
0
|
|
|
|
0
|
unless (@save_sig) { |
8730
|
0
|
0
|
|
|
|
0
|
$init->add( "/* no %SIG in BEGIN block */" ) if $verbose; |
8731
|
0
|
0
|
|
|
|
0
|
warn "no %SIG in BEGIN block\n" if $verbose; |
8732
|
0
|
|
|
|
|
0
|
return; |
8733
|
|
|
|
|
|
|
} |
8734
|
0
|
0
|
|
|
|
0
|
$init->add( "/* save %SIG */" ) if $verbose; |
8735
|
0
|
0
|
|
|
|
0
|
warn "save %SIG\n" if $verbose; |
8736
|
0
|
|
|
|
|
0
|
$init->add( "{", "\tHV* hv = get_hvs(\"main::SIG\", GV_ADD);" ); |
8737
|
0
|
|
|
|
|
0
|
foreach my $x ( @save_sig ) { |
8738
|
0
|
|
|
|
|
0
|
my ($k, $cvref) = @$x; |
8739
|
0
|
|
|
|
|
0
|
my $sv = $cvref->save; |
8740
|
0
|
|
|
|
|
0
|
my ($cstring, $cur, $utf8) = strlen_flags($k); |
8741
|
0
|
|
|
|
|
0
|
$init->add( '{', sprintf "\t".'SV* sv = (SV*)%s;', $sv ); |
8742
|
0
|
|
|
|
|
0
|
$init->add( sprintf("\thv_store(hv, %s, %u, %s, %d);", |
8743
|
|
|
|
|
|
|
$cstring, $cur, 'sv', 0 ) ); |
8744
|
0
|
|
|
|
|
0
|
$init->add( "\t".'mg_set(sv);', '}' ); |
8745
|
|
|
|
|
|
|
} |
8746
|
0
|
|
|
|
|
0
|
$init->add('}'); |
8747
|
0
|
|
|
|
|
0
|
$init->split; |
8748
|
|
|
|
|
|
|
} |
8749
|
|
|
|
|
|
|
|
8750
|
|
|
|
|
|
|
sub force_saving_xsloader { |
8751
|
0
|
|
|
0
|
0
|
0
|
mark_package("XSLoader", 1); |
8752
|
|
|
|
|
|
|
# mark_package("DynaLoader", 1); |
8753
|
0
|
0
|
|
|
|
0
|
if ($] < 5.015003) { |
|
|
0
|
|
|
|
|
|
8754
|
0
|
|
|
|
|
0
|
$init->add("/* force saving of XSLoader::load */"); |
8755
|
0
|
|
|
|
|
0
|
eval { XSLoader::load; }; |
|
0
|
|
|
|
|
0
|
|
8756
|
|
|
|
|
|
|
# does this really save the whole packages? |
8757
|
0
|
|
|
|
|
0
|
$dumped_package{XSLoader} = 1; |
8758
|
0
|
|
|
|
|
0
|
svref_2object( \&XSLoader::load )->save; |
8759
|
|
|
|
|
|
|
} elsif ($CPERL51) { |
8760
|
0
|
|
|
|
|
0
|
$init->add("/* XSLoader::load_file already builtin into cperl */"); |
8761
|
0
|
|
|
|
|
0
|
$dumped_package{XSLoader} = 1; |
8762
|
0
|
|
|
|
|
0
|
$dumped_package{DynaLoader} = 1; |
8763
|
0
|
|
|
|
|
0
|
add_hashINC("XSLoader"); # builtin |
8764
|
|
|
|
|
|
|
} else { |
8765
|
0
|
|
|
|
|
0
|
$init->add("/* custom XSLoader::load_file */"); |
8766
|
|
|
|
|
|
|
# does this really save the whole packages? |
8767
|
0
|
|
|
|
|
0
|
$dumped_package{DynaLoader} = 1; |
8768
|
0
|
|
|
|
|
0
|
svref_2object( \&XSLoader::load_file )->save; |
8769
|
0
|
|
|
|
|
0
|
svref_2object( \&DynaLoader::dl_load_flags )->save; # not saved as XSUB constant? |
8770
|
|
|
|
|
|
|
} |
8771
|
0
|
0
|
|
|
|
0
|
add_hashINC("XSLoader") if $] < 5.015003; |
8772
|
0
|
|
|
|
|
0
|
add_hashINC("DynaLoader"); |
8773
|
0
|
|
|
|
|
0
|
$use_xsloader = 0; # do not load again |
8774
|
|
|
|
|
|
|
} |
8775
|
|
|
|
|
|
|
|
8776
|
|
|
|
|
|
|
sub save_main_rest { |
8777
|
|
|
|
|
|
|
# this is mainly for the test suite |
8778
|
|
|
|
|
|
|
# local $SIG{__WARN__} = sub { print STDERR @_ } unless $debug{runtime}; |
8779
|
|
|
|
|
|
|
|
8780
|
|
|
|
|
|
|
warn "done main optree, walking symtable for extras\n" |
8781
|
0
|
0
|
0
|
0
|
0
|
0
|
if $verbose or $debug{cv}; |
8782
|
0
|
|
|
|
|
0
|
$init->add(""); |
8783
|
0
|
|
|
|
|
0
|
$init->add("/* done main optree, extra subs which might be unused */"); |
8784
|
0
|
|
|
|
|
0
|
save_unused_subs(); |
8785
|
0
|
|
|
|
|
0
|
$init->add("/* done extras */"); |
8786
|
|
|
|
|
|
|
|
8787
|
|
|
|
|
|
|
# startpoints: XXX TODO push BEGIN/END blocks to modules code. |
8788
|
0
|
0
|
|
|
|
0
|
warn "Writing init_av\n" if $debug{av}; |
8789
|
0
|
|
|
|
|
0
|
my $init_av = init_av->save('INIT'); |
8790
|
0
|
|
|
|
|
0
|
my $end_av; |
8791
|
|
|
|
|
|
|
{ |
8792
|
|
|
|
|
|
|
# >=5.10 need to defer nullifying of all vars in END, not only new ones. |
8793
|
0
|
|
|
|
|
0
|
local ($B::C::pv_copy_on_grow, $B::C::const_strings); |
|
0
|
|
|
|
|
0
|
|
8794
|
0
|
|
|
|
|
0
|
$in_endav = 1; |
8795
|
0
|
0
|
|
|
|
0
|
warn "Writing end_av\n" if $debug{av}; |
8796
|
0
|
|
|
|
|
0
|
$init->add("/* END block */"); |
8797
|
0
|
|
|
|
|
0
|
$end_av = end_av->save('END'); |
8798
|
0
|
|
|
|
|
0
|
$in_endav = 0; |
8799
|
|
|
|
|
|
|
} |
8800
|
0
|
0
|
|
|
|
0
|
if ( !defined($module) ) { |
8801
|
|
|
|
|
|
|
$init->add( |
8802
|
|
|
|
|
|
|
"/* startpoints */", |
8803
|
0
|
|
|
|
|
0
|
sprintf( "PL_main_root = s\\_%x;", ${ main_root() } ), |
8804
|
0
|
|
|
|
|
0
|
sprintf( "PL_main_start = s\\_%x;", ${ main_start() } ), |
|
0
|
|
|
|
|
0
|
|
8805
|
|
|
|
|
|
|
); |
8806
|
0
|
0
|
|
|
|
0
|
$init->add(index($init_av,'(AV*)')>=0 |
8807
|
|
|
|
|
|
|
? "PL_initav = $init_av;" |
8808
|
|
|
|
|
|
|
: "PL_initav = (AV*)$init_av;"); |
8809
|
0
|
0
|
|
|
|
0
|
$init->add(index($end_av,'(AV*)')>=0 |
8810
|
|
|
|
|
|
|
? "PL_endav = $end_av;" |
8811
|
|
|
|
|
|
|
: "PL_endav = (AV*)$end_av;"); |
8812
|
|
|
|
|
|
|
} |
8813
|
0
|
0
|
|
|
|
0
|
save_context() unless defined($module); |
8814
|
|
|
|
|
|
|
# warn "use_xsloader=$use_xsloader\n" if $verbose; |
8815
|
|
|
|
|
|
|
# If XSLoader was forced later, e.g. in curpad, INIT or END block |
8816
|
0
|
0
|
|
|
|
0
|
force_saving_xsloader() if $use_xsloader; |
8817
|
|
|
|
|
|
|
|
8818
|
0
|
0
|
|
|
|
0
|
return if $check; |
8819
|
0
|
0
|
|
|
|
0
|
warn "Writing output\n" if $verbose; |
8820
|
0
|
|
|
|
|
0
|
output_boilerplate(); |
8821
|
|
|
|
|
|
|
|
8822
|
|
|
|
|
|
|
# add static modules like " Win32CORE" |
8823
|
0
|
|
|
|
|
0
|
foreach my $stashname ( split /\s+/, $Config{static_ext} ) { |
8824
|
0
|
0
|
|
|
|
0
|
next if $stashname =~ /^\s*$/; # often a leading space |
8825
|
0
|
|
|
|
|
0
|
$static_ext{$stashname}++; |
8826
|
0
|
|
|
|
|
0
|
my $stashxsub = $stashname; |
8827
|
0
|
|
|
|
|
0
|
$stashxsub =~ s/::/__/g; |
8828
|
0
|
|
|
|
|
0
|
print "EXTERN_C void boot_$stashxsub (pTHX_ CV* cv);\n"; |
8829
|
|
|
|
|
|
|
} |
8830
|
0
|
|
|
|
|
0
|
print "\n"; |
8831
|
0
|
|
0
|
|
|
0
|
output_all($init_name || "perl_init"); |
8832
|
0
|
|
|
|
|
0
|
print "\n"; |
8833
|
0
|
|
|
|
|
0
|
output_main_rest(); |
8834
|
|
|
|
|
|
|
|
8835
|
0
|
0
|
|
|
|
0
|
if ( defined($module) ) { |
8836
|
0
|
0
|
|
|
|
0
|
my $cmodule = $module ? $module : "main"; |
8837
|
0
|
|
|
|
|
0
|
$cmodule =~ s/::/__/g; |
8838
|
|
|
|
|
|
|
|
8839
|
0
|
|
|
|
|
0
|
my $start = "op_list[0]"; |
8840
|
0
|
0
|
|
|
|
0
|
warn "curpad syms:\n" if $verbose; |
8841
|
0
|
|
|
|
|
0
|
$init->add("/* curpad syms */"); |
8842
|
0
|
|
|
|
|
0
|
my $curpad_sym = ( comppadlist->ARRAY )[1]->save; |
8843
|
|
|
|
|
|
|
|
8844
|
0
|
|
|
|
|
0
|
print <<"EOT"; |
8845
|
|
|
|
|
|
|
|
8846
|
|
|
|
|
|
|
#include "XSUB.h" |
8847
|
|
|
|
|
|
|
XS(boot_$cmodule) |
8848
|
|
|
|
|
|
|
{ |
8849
|
|
|
|
|
|
|
dXSARGS; |
8850
|
|
|
|
|
|
|
perl_init(); |
8851
|
|
|
|
|
|
|
ENTER; |
8852
|
|
|
|
|
|
|
SAVETMPS; |
8853
|
|
|
|
|
|
|
SAVEVPTR(PL_curpad); |
8854
|
|
|
|
|
|
|
SAVEVPTR(PL_op); |
8855
|
|
|
|
|
|
|
dl_init(aTHX); |
8856
|
|
|
|
|
|
|
PL_curpad = AvARRAY($curpad_sym); |
8857
|
|
|
|
|
|
|
PL_comppad = $curpad_sym; |
8858
|
|
|
|
|
|
|
PL_op = $start; |
8859
|
|
|
|
|
|
|
perl_run( aTHX ); /* Perl_runops_standard(aTHX); */ |
8860
|
|
|
|
|
|
|
FREETMPS; |
8861
|
|
|
|
|
|
|
LEAVE; |
8862
|
|
|
|
|
|
|
ST(0) = &PL_sv_yes; |
8863
|
|
|
|
|
|
|
XSRETURN(1); |
8864
|
|
|
|
|
|
|
} |
8865
|
|
|
|
|
|
|
EOT |
8866
|
|
|
|
|
|
|
|
8867
|
|
|
|
|
|
|
} else { |
8868
|
0
|
|
|
|
|
0
|
output_main(); |
8869
|
|
|
|
|
|
|
} |
8870
|
|
|
|
|
|
|
} |
8871
|
|
|
|
|
|
|
|
8872
|
|
|
|
|
|
|
sub init_sections { |
8873
|
0
|
|
|
0
|
0
|
0
|
my @sections = ( |
8874
|
|
|
|
|
|
|
decl => \$decl, |
8875
|
|
|
|
|
|
|
init0 => \$init0, |
8876
|
|
|
|
|
|
|
free => \$free, |
8877
|
|
|
|
|
|
|
sym => \$symsect, |
8878
|
|
|
|
|
|
|
hek => \$heksect, |
8879
|
|
|
|
|
|
|
binop => \$binopsect, |
8880
|
|
|
|
|
|
|
condop => \$condopsect, |
8881
|
|
|
|
|
|
|
cop => \$copsect, |
8882
|
|
|
|
|
|
|
padop => \$padopsect, |
8883
|
|
|
|
|
|
|
listop => \$listopsect, |
8884
|
|
|
|
|
|
|
logop => \$logopsect, |
8885
|
|
|
|
|
|
|
loop => \$loopsect, |
8886
|
|
|
|
|
|
|
op => \$opsect, |
8887
|
|
|
|
|
|
|
pmop => \$pmopsect, |
8888
|
|
|
|
|
|
|
pvop => \$pvopsect, |
8889
|
|
|
|
|
|
|
svop => \$svopsect, |
8890
|
|
|
|
|
|
|
unop => \$unopsect, |
8891
|
|
|
|
|
|
|
unopaux => \$unopauxsect, |
8892
|
|
|
|
|
|
|
methop => \$methopsect, |
8893
|
|
|
|
|
|
|
sv => \$svsect, |
8894
|
|
|
|
|
|
|
xpv => \$xpvsect, |
8895
|
|
|
|
|
|
|
xpvav => \$xpvavsect, |
8896
|
|
|
|
|
|
|
xpvhv => \$xpvhvsect, |
8897
|
|
|
|
|
|
|
xpvcv => \$xpvcvsect, |
8898
|
|
|
|
|
|
|
xpviv => \$xpvivsect, |
8899
|
|
|
|
|
|
|
xpvuv => \$xpvuvsect, |
8900
|
|
|
|
|
|
|
xpvnv => \$xpvnvsect, |
8901
|
|
|
|
|
|
|
xpvmg => \$xpvmgsect, |
8902
|
|
|
|
|
|
|
xpvlv => \$xpvlvsect, |
8903
|
|
|
|
|
|
|
xrv => \$xrvsect, |
8904
|
|
|
|
|
|
|
xpvbm => \$xpvbmsect, |
8905
|
|
|
|
|
|
|
xpvio => \$xpviosect, |
8906
|
|
|
|
|
|
|
padlist => \$padlistsect, |
8907
|
|
|
|
|
|
|
padnamelist => \$padnlsect, |
8908
|
|
|
|
|
|
|
padname => \$padnamesect, |
8909
|
|
|
|
|
|
|
); |
8910
|
0
|
0
|
|
|
|
0
|
if ($PERL522) { |
8911
|
0
|
|
|
|
|
0
|
pop @sections; |
8912
|
|
|
|
|
|
|
} |
8913
|
0
|
|
|
|
|
0
|
my ( $name, $sectref ); |
8914
|
0
|
|
|
|
|
0
|
while ( ( $name, $sectref ) = splice( @sections, 0, 2 ) ) { |
8915
|
0
|
|
|
|
|
0
|
$$sectref = new B::C::Section $name, \%symtable, 0; |
8916
|
|
|
|
|
|
|
} |
8917
|
0
|
0
|
|
|
|
0
|
if ($PERL522) { |
8918
|
0
|
|
|
|
|
0
|
for my $size (@padnamesect_sizes) { |
8919
|
0
|
|
|
|
|
0
|
my $name = "padname_$size"; |
8920
|
0
|
|
|
|
|
0
|
$padnamesect{$size} = new B::C::Section $name, \%symtable, 0; |
8921
|
|
|
|
|
|
|
} |
8922
|
|
|
|
|
|
|
} |
8923
|
0
|
|
|
|
|
0
|
$init = new B::C::InitSection 'init', \%symtable, 0; |
8924
|
0
|
|
|
|
|
0
|
$init1 = new B::C::InitSection 'init1', \%symtable, 0; |
8925
|
0
|
|
|
|
|
0
|
$init2 = new B::C::InitSection 'init2', \%symtable, 0; |
8926
|
0
|
|
|
|
|
0
|
%savINC = %curINC = %INC; |
8927
|
|
|
|
|
|
|
} |
8928
|
|
|
|
|
|
|
|
8929
|
|
|
|
|
|
|
sub mark_unused { |
8930
|
0
|
|
|
0
|
0
|
0
|
my ( $pkg, $val ) = @_; |
8931
|
0
|
|
|
|
|
0
|
$include_package{$pkg} = $val; |
8932
|
|
|
|
|
|
|
} |
8933
|
|
|
|
|
|
|
|
8934
|
|
|
|
|
|
|
sub mark_skip { |
8935
|
15
|
|
|
15
|
0
|
50
|
for (@_) { |
8936
|
225
|
|
|
|
|
269
|
delete_unsaved_hashINC($_); |
8937
|
|
|
|
|
|
|
# $include_package{$_} = 0; |
8938
|
225
|
50
|
|
|
|
432
|
$skip_package{$_} = 1 unless $include_package{$_}; |
8939
|
|
|
|
|
|
|
} |
8940
|
|
|
|
|
|
|
} |
8941
|
|
|
|
|
|
|
|
8942
|
|
|
|
|
|
|
sub compile { |
8943
|
0
|
|
|
0
|
0
|
|
my @options = @_; |
8944
|
|
|
|
|
|
|
# Allow debugging in CHECK blocks without Od |
8945
|
0
|
0
|
|
|
|
|
$DB::single = 1 if defined &DB::DB; |
8946
|
0
|
|
|
|
|
|
my ( $option, $opt, $arg ); |
8947
|
0
|
|
|
|
|
|
my @eval_at_startup; |
8948
|
0
|
|
|
|
|
|
$B::C::can_delete_pkg = 1; |
8949
|
0
|
|
|
|
|
|
$B::C::save_sig = 1; |
8950
|
0
|
|
|
|
|
|
$B::C::destruct = 1; |
8951
|
0
|
|
|
|
|
|
$B::C::stash = 0; |
8952
|
0
|
|
|
|
|
|
$B::C::cow = 0; |
8953
|
0
|
0
|
|
|
|
|
$B::C::fold = 1 if $] >= 5.013009; # always include utf8::Cased tables |
8954
|
0
|
0
|
|
|
|
|
$B::C::warnings = 1 if $] >= 5.013005; # always include Carp warnings categories and B |
8955
|
0
|
0
|
0
|
|
|
|
$B::C::optimize_warn_sv = 1 if $^O ne 'MSWin32' or $Config{cc} !~ m/^cl/i; |
8956
|
0
|
0
|
|
|
|
|
$B::C::dyn_padlist = 1 if $] >= 5.017; # default is dynamic and safe, disable with -O4 |
8957
|
0
|
|
|
|
|
|
$B::C::walkall = 1; |
8958
|
|
|
|
|
|
|
|
8959
|
0
|
|
|
|
|
|
mark_skip qw(B::C B::C::Config B::CC B::Asmdata B::FAKEOP O |
8960
|
|
|
|
|
|
|
B::Pseudoreg B::Shadow B::C::InitSection); |
8961
|
|
|
|
|
|
|
#mark_skip('DB', 'Term::ReadLine') if defined &DB::DB; |
8962
|
|
|
|
|
|
|
|
8963
|
|
|
|
|
|
|
OPTION: |
8964
|
0
|
|
|
|
|
|
while ( $option = shift @options ) { |
8965
|
0
|
0
|
|
|
|
|
if ( $option =~ /^-(.)(.*)/ ) { |
8966
|
0
|
|
|
|
|
|
$opt = $1; |
8967
|
0
|
|
|
|
|
|
$arg = $2; |
8968
|
|
|
|
|
|
|
} |
8969
|
|
|
|
|
|
|
else { |
8970
|
0
|
|
|
|
|
|
unshift @options, $option; |
8971
|
0
|
|
|
|
|
|
last OPTION; |
8972
|
|
|
|
|
|
|
} |
8973
|
0
|
0
|
0
|
|
|
|
if ( $opt eq "-" && $arg eq "-" ) { |
8974
|
0
|
|
|
|
|
|
shift @options; |
8975
|
0
|
|
|
|
|
|
last OPTION; |
8976
|
|
|
|
|
|
|
} |
8977
|
0
|
0
|
|
|
|
|
if ( $opt eq "w" ) { |
8978
|
0
|
|
|
|
|
|
$warn_undefined_syms = 1; |
8979
|
|
|
|
|
|
|
} |
8980
|
0
|
0
|
0
|
|
|
|
if ( $opt eq "c" ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
8981
|
0
|
|
|
|
|
|
$check = 1; |
8982
|
|
|
|
|
|
|
} |
8983
|
|
|
|
|
|
|
elsif ( $opt eq "D" ) { |
8984
|
0
|
|
0
|
|
|
|
$arg ||= shift @options; |
8985
|
0
|
0
|
|
|
|
|
if ($arg eq 'full') { |
|
|
0
|
|
|
|
|
|
8986
|
0
|
|
|
|
|
|
$arg = 'OcAHCMGSPpsWF'; |
8987
|
0
|
|
|
|
|
|
$all_bc_deps{'B::Flags'}++; |
8988
|
|
|
|
|
|
|
} |
8989
|
|
|
|
|
|
|
elsif ($arg eq 'ufull') { |
8990
|
0
|
|
|
|
|
|
$arg = 'uOcAHCMGSPpsWF'; |
8991
|
0
|
|
|
|
|
|
$all_bc_deps{'B::Flags'}++; |
8992
|
|
|
|
|
|
|
} |
8993
|
0
|
|
|
|
|
|
foreach my $arg ( split( //, $arg ) ) { |
8994
|
0
|
0
|
|
|
|
|
if (exists $debug_map{$arg}) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
8995
|
0
|
|
|
|
|
|
$debug{ $debug_map{$arg} }++; |
8996
|
|
|
|
|
|
|
} |
8997
|
|
|
|
|
|
|
elsif ( $arg eq "o" ) { |
8998
|
0
|
|
|
|
|
|
$verbose++; |
8999
|
0
|
|
|
|
|
|
B->debug(1); |
9000
|
|
|
|
|
|
|
} |
9001
|
|
|
|
|
|
|
elsif ( $arg eq "F" ) { |
9002
|
0
|
0
|
0
|
|
|
|
$debug{flags}++ if $] > 5.008 and eval "require B::Flags;"; |
9003
|
0
|
|
|
|
|
|
$all_bc_deps{'B::Flags'}++; |
9004
|
|
|
|
|
|
|
# $debug{flags}++ if require B::Flags; |
9005
|
|
|
|
|
|
|
} |
9006
|
|
|
|
|
|
|
elsif ( $arg eq "r" ) { |
9007
|
0
|
|
|
|
|
|
$debug{runtime}++; |
9008
|
|
|
|
|
|
|
$SIG{__WARN__} = sub { |
9009
|
0
|
|
|
0
|
|
|
warn @_; |
9010
|
0
|
|
|
|
|
|
my $s = join(" ", @_); |
9011
|
0
|
|
|
|
|
|
chomp $s; |
9012
|
0
|
0
|
|
|
|
|
$init->add("/* ".$s." */") if $init; |
9013
|
0
|
|
|
|
|
|
}; |
9014
|
|
|
|
|
|
|
} |
9015
|
|
|
|
|
|
|
else { |
9016
|
0
|
|
|
|
|
|
warn "ignoring unknown debug option: $arg\n"; |
9017
|
|
|
|
|
|
|
} |
9018
|
|
|
|
|
|
|
} |
9019
|
|
|
|
|
|
|
} |
9020
|
|
|
|
|
|
|
elsif ( $opt eq "o" ) { |
9021
|
0
|
|
0
|
|
|
|
$arg ||= shift @options; |
9022
|
0
|
|
|
|
|
|
$outfile = $arg; |
9023
|
0
|
0
|
|
|
|
|
if ($check) { |
9024
|
0
|
|
|
|
|
|
warn "Warning: -o argument ignored with -c\n"; |
9025
|
|
|
|
|
|
|
} else { |
9026
|
0
|
0
|
|
|
|
|
open( STDOUT, ">", $arg ) or return "$arg: $!\n"; |
9027
|
|
|
|
|
|
|
} |
9028
|
|
|
|
|
|
|
} |
9029
|
|
|
|
|
|
|
elsif ( $opt eq "s" and $arg eq "taticxs" ) { |
9030
|
0
|
0
|
|
|
|
|
$outfile = "perlcc" unless $outfile; |
9031
|
0
|
|
|
|
|
|
$staticxs = 1; |
9032
|
|
|
|
|
|
|
} |
9033
|
|
|
|
|
|
|
elsif ( $opt eq "n" ) { |
9034
|
0
|
|
0
|
|
|
|
$arg ||= shift @options; |
9035
|
0
|
|
|
|
|
|
$init_name = $arg; |
9036
|
|
|
|
|
|
|
} |
9037
|
|
|
|
|
|
|
elsif ( $opt eq "m" ) { |
9038
|
|
|
|
|
|
|
# $arg ||= shift @options; |
9039
|
0
|
|
|
|
|
|
$module = $arg; |
9040
|
0
|
|
|
|
|
|
mark_unused( $arg, 1 ); |
9041
|
|
|
|
|
|
|
} |
9042
|
|
|
|
|
|
|
elsif ( $opt eq "v" ) { |
9043
|
0
|
|
|
|
|
|
$verbose = 1; |
9044
|
|
|
|
|
|
|
} |
9045
|
|
|
|
|
|
|
elsif ( $opt eq "u" ) { |
9046
|
0
|
|
0
|
|
|
|
$arg ||= shift @options; |
9047
|
0
|
0
|
|
|
|
|
if ($arg =~ /\.p[lm]$/) { |
9048
|
0
|
|
|
|
|
|
eval "require(\"$arg\");"; # path as string |
9049
|
|
|
|
|
|
|
} else { |
9050
|
0
|
|
|
|
|
|
eval "require $arg;"; # package as bareword with :: |
9051
|
|
|
|
|
|
|
} |
9052
|
0
|
|
|
|
|
|
mark_unused( $arg, 1 ); |
9053
|
|
|
|
|
|
|
} |
9054
|
|
|
|
|
|
|
elsif ( $opt eq "U" ) { |
9055
|
0
|
|
0
|
|
|
|
$arg ||= shift @options; |
9056
|
0
|
|
|
|
|
|
mark_skip( $arg ); |
9057
|
|
|
|
|
|
|
} |
9058
|
|
|
|
|
|
|
elsif ( $opt eq "f" ) { |
9059
|
0
|
|
0
|
|
|
|
$arg ||= shift @options; |
9060
|
0
|
|
|
|
|
|
$arg =~ m/(no-)?(.*)/; |
9061
|
0
|
|
0
|
|
|
|
my $no = defined($1) && $1 eq 'no-'; |
9062
|
0
|
0
|
|
|
|
|
$arg = $no ? $2 : $arg; |
9063
|
0
|
0
|
|
|
|
|
if ( exists $option_map{$arg} ) { |
9064
|
0
|
|
|
|
|
|
${ $option_map{$arg} } = !$no; |
|
0
|
|
|
|
|
|
|
9065
|
|
|
|
|
|
|
} |
9066
|
|
|
|
|
|
|
else { |
9067
|
0
|
|
|
|
|
|
die "Invalid optimization '$arg'"; |
9068
|
|
|
|
|
|
|
} |
9069
|
|
|
|
|
|
|
} |
9070
|
|
|
|
|
|
|
elsif ( $opt eq "O" ) { |
9071
|
0
|
0
|
|
|
|
|
$arg = 1 if $arg eq ""; |
9072
|
0
|
|
|
|
|
|
my @opt; |
9073
|
0
|
|
|
|
|
|
foreach my $i ( 1 .. $arg ) { |
9074
|
0
|
|
|
|
|
|
push @opt, @{ $optimization_map{$i} } |
9075
|
0
|
0
|
|
|
|
|
if exists $optimization_map{$i}; |
9076
|
|
|
|
|
|
|
} |
9077
|
0
|
|
|
|
|
|
unshift @options, @opt; |
9078
|
0
|
0
|
|
|
|
|
warn "options : ".(join " ",@opt)."\n" if $verbose; |
9079
|
|
|
|
|
|
|
} |
9080
|
|
|
|
|
|
|
elsif ( $opt eq "e" ) { |
9081
|
0
|
|
|
|
|
|
push @eval_at_startup, $arg; |
9082
|
|
|
|
|
|
|
} |
9083
|
|
|
|
|
|
|
elsif ( $opt eq "l" ) { |
9084
|
0
|
|
|
|
|
|
$max_string_len = $arg; |
9085
|
|
|
|
|
|
|
} |
9086
|
|
|
|
|
|
|
} |
9087
|
0
|
0
|
0
|
|
|
|
if (!$B::C::Config::have_independent_comalloc) { |
|
|
0
|
|
|
|
|
|
9088
|
0
|
0
|
|
|
|
|
if ($B::C::av_init2) { |
|
|
0
|
|
|
|
|
|
9089
|
0
|
|
|
|
|
|
$B::C::av_init = 1; |
9090
|
0
|
|
|
|
|
|
$B::C::av_init2 = 0; |
9091
|
|
|
|
|
|
|
} elsif ($B::C::av_init) { |
9092
|
0
|
|
|
|
|
|
$B::C::av_init2 = 0; |
9093
|
|
|
|
|
|
|
} |
9094
|
|
|
|
|
|
|
} elsif ($B::C::av_init2 and $B::C::av_init) { |
9095
|
0
|
|
|
|
|
|
$B::C::av_init = 0; |
9096
|
|
|
|
|
|
|
} |
9097
|
0
|
0
|
0
|
|
|
|
$B::C::save_data_fh = 1 if $] >= 5.008 and (($] < 5.009004) or $MULTI); |
|
|
|
0
|
|
|
|
|
9098
|
0
|
0
|
0
|
|
|
|
$B::C::destruct = 1 if $] < 5.008 or $^O eq 'MSWin32'; # skip -ffast-destruct there |
9099
|
|
|
|
|
|
|
|
9100
|
0
|
|
|
|
|
|
init_sections(); |
9101
|
0
|
|
|
|
|
|
foreach my $i (@eval_at_startup) { |
9102
|
0
|
|
|
|
|
|
$init2->add_eval($i); |
9103
|
|
|
|
|
|
|
} |
9104
|
0
|
0
|
|
|
|
|
if (@options) { # modules or main? |
9105
|
|
|
|
|
|
|
return sub { |
9106
|
0
|
|
|
0
|
|
|
my $objname; |
9107
|
0
|
|
|
|
|
|
foreach $objname (@options) { |
9108
|
0
|
|
|
|
|
|
eval "save_object(\\$objname)"; |
9109
|
|
|
|
|
|
|
} |
9110
|
0
|
|
0
|
|
|
|
output_all($init_name || "init_module"); |
9111
|
|
|
|
|
|
|
} |
9112
|
0
|
|
|
|
|
|
} |
9113
|
|
|
|
|
|
|
else { |
9114
|
0
|
|
|
0
|
|
|
return sub { save_main() }; |
|
0
|
|
|
|
|
|
|
9115
|
|
|
|
|
|
|
} |
9116
|
|
|
|
|
|
|
} |
9117
|
|
|
|
|
|
|
|
9118
|
|
|
|
|
|
|
1; |
9119
|
|
|
|
|
|
|
|
9120
|
|
|
|
|
|
|
__END__ |