1
package B::Module::Info;
6
use B::Utils qw(walkoptree_filtered walkoptree_simple
8
@B::Utils::bad_stashes = qw(); # give us everything.
11
# From: Roland Walker <walker@ncbi.nlm.nih.gov>
12
# "Syntax OK" may land inside output and render it unusable
13
my $oldfh = select STDERR; $| = 1; # STDERR is unbuffered, but just in case
14
select STDOUT; $| = 1;
18
my $the_file = $0; # when walking all subroutines, you need to skip
19
# the ones in other modules
22
return opgrep {name => [qw(nextstate dbstate setstate)]}, @_
28
my $pack = $op->stashpv;
29
print "$pack\n" if !defined($cur_pack) || $pack ne $cur_pack;
35
my %roots = all_roots;
36
my %filtered_roots = ();
37
while( my($name, $op) = each %roots ) {
38
next if $name eq '__MAIN__';
39
$filtered_roots{$name} = $op;
41
return %filtered_roots;
47
Returns a list of pairs, each containing a root with the relative
48
B::CV object; this list includes B::main_root/cv.
53
my %roots = filtered_roots;
54
my @roots = ( [ B::main_root, B::main_cv ],
56
B::svref_2object(\&{$_}) ] }
63
walkoptree_filtered(B::main_root,
68
my %roots = filtered_roots();
69
while( my($name, $op) = each %roots ) {
70
local($File, $Start, $End);
71
walkoptree_simple($op, \&sub_info);
72
print "$name at \"$File\" from $Start to $End\n";
76
# begin_av is an undocumented B function.
77
# note: if module hasn't any BEGIN block,
78
# begin_av will be a B::SPECIAL
79
my @arr = B::begin_av->isa('B::SPECIAL') ?
82
foreach my $begin_cv (@arr) {
83
my $root = $begin_cv->ROOT;
84
local $CurCV = $begin_cv;
86
next unless $begin_cv->FILE eq $the_file;
87
# cheat otherwise show_require guard prevents display
88
local $B::Utils::file = $begin_cv->FILE;
89
local $B::Utils::line = $begin_cv->START->line;
91
# this is from $ENV{PERL5OPT}, skip it
92
next if $B::Utils::line == 0;
94
my $lineseq = $root->first;
95
next if $lineseq->name ne 'lineseq';
97
my $req_op = $lineseq->first->sibling;
98
if( $req_op->name eq 'require' ) {
100
if( $req_op->first->private & B::OPpCONST_BARE ) {
101
$module = const_sv($req_op->first)->PV;
102
$module =~ s[/][::]g;
106
# if it is not bare it can't be an "use"
107
show_require($req_op);
111
printf "use %s (%s) at \"%s\" line %s\n",
113
get_required_version($req_op, $module),
115
$begin_cv->START->line;
117
# it can't be an use, scan the optree
119
walkoptree_filtered($root,
127
foreach my $p ( roots_cv_pairs ) {
128
local $CurCV = $p->[1];
129
walkoptree_filtered($p->[0],
137
my %roots = filtered_roots;
138
foreach my $p ( roots_cv_pairs ) {
139
local $CurCV = $p->[1];
140
walkoptree_filtered($p->[0],
150
my $sv = $op->sv if $op->can('sv');
151
# the constant could be in the pad (under useithreads)
152
$sv = padval($op->targ) unless $$sv;
156
# Don't do this for regexes
165
if (B::class($sv) eq "SPECIAL") {
166
return ('undef', '1', '0')[$$sv-1]; # sv_undef, sv_yes, sv_no
167
} elsif (B::class($sv) eq "NULL") {
169
} elsif ($sv->FLAGS & B::SVf_IOK) {
170
return $sv->int_value;
171
} elsif ($sv->FLAGS & B::SVf_NOK) {
172
# try the default stringification
175
# If it's in scientific notation, we might have lost information
176
return sprintf("%.20e", $sv->NV);
179
} elsif ($sv->FLAGS & B::SVf_ROK && $sv->can("RV")) {
180
return "\\(" . B::const($sv->RV) . ")"; # constant folded
181
} elsif ($sv->FLAGS & B::SVf_POK) {
183
if ($str =~ /[^ -~]/) { # ASCII for non-printing
184
return single_delim("qq", '"', uninterp escape_str unback $str);
186
return single_delim("q", "'", unback $str);
195
my($q, $default, $str) = @_;
196
return "$default$str$default" if $default and index($str, $default) == -1;
197
my($succeed, $delim);
198
($succeed, $str) = balanced_delim($str);
199
return "$q$str" if $succeed;
200
for $delim ('/', '"', '#') {
201
return "$q$delim" . $str . $delim if index($str, $delim) == -1;
204
$str =~ s/$default/\\$default/g;
205
return "$default$str$default";
215
return (($CurCV->PADLIST->ARRAY)[1]->ARRAY)[$targ];
220
$File = undef if $File eq '__none__';
221
$File ||= $B::Utils::file;
222
$Start = $B::Utils::line if !$Start || $B::Utils::line < $Start;
223
$End = $B::Utils::line if !$End || $B::Utils::line > $End;
230
return $name eq 'BEGIN';
240
my($pvmg, $type) = @_;
241
my $magic = $pvmg->MAGIC;
244
return $magic if $magic->TYPE eq $type;
247
return $magic; # false
250
sub get_required_version {
251
my($req_op, $module) = (shift, shift);
254
my $version_op = $req_op->sibling;
255
return if B::class($version_op) eq 'NULL';
256
if ($version_op->name eq 'lineseq') {
257
# We have a version parameter; skip nextstate &
259
my $constop = $version_op->first->next->next;
261
return '' unless const_sv($constop)->PV eq $module;
262
$constop = $constop->sibling;
263
$version = const_sv($constop);
264
my $class = B::class($version);
266
$version = $class eq 'IV' ? $version->int_value :
267
$class eq 'NV' ? $version->NV :
268
($class eq 'PVMG' && ($magic = grep_magic($version, 'V'))
269
&& $$magic) ? 'v' . $magic->PTR :
270
((($class eq 'PVNV' && $] < 5.009) || $class eq 'PVMG')
271
&& length($version->PV)) ?
272
'v' . join('.', map(ord,
276
$class eq 'PVIV' ? $version->int_value :
279
$constop = $constop->sibling;
280
return '' if $constop->name ne "method_named";
281
return '' if const_sv($constop)->PV ne "VERSION";
289
B::class($_[0]) ne 'NULL' && $_[0]->name eq 'require';
293
return unless $B::Utils::file eq $the_file;
297
if( B::class($op) eq "UNOP" and $op->first->name eq 'const'
298
and $op->first->private & B::OPpCONST_BARE ) {
300
$name = const_sv($op->first)->PV;
304
if ($op->flags & B::OPf_KIDS) {
305
my $kid = $op->first;
306
if (defined prototype("CORE::$name")
307
&& prototype("CORE::$name") =~ /^;?\*/
308
&& $kid->name eq "rv2gv") {
312
my $sv = const_sv($kid);
313
return unless defined $sv && !$sv->isa('B::NULL');
314
$name = $sv->isa("B::NV") ? $sv->NV : 0;
315
$name ||= $sv->isa("B::PV") ? $sv->PV : '';
322
printf "require %s %s at line %d\n", $bare, $name, $B::Utils::line;
329
return $modes{$mode};
334
B::class($_[0]) ne 'NULL' && $_[0]->name eq 'entersub';
340
unless( $op->name eq 'entersub' ) {
341
warn "sub_check only works with entersub ops";
345
my @kids = $op->kids;
348
if( my($kid) = grep $_->name eq 'method_named', @kids ) {
349
my $class = _class_or_object_method(@kids);
350
printf "%s method call to %s%s at \"%s\" line %d\n",
351
$class ? "class" : "object",
353
$class ? " via $class" : '',
354
$B::Utils::file, $B::Utils::line;
356
# dynamic method call
357
elsif( my($kid) = grep $_->name eq 'method', @kids ) {
358
my $class = _class_or_object_method(@kids);
359
printf "dynamic %s method call%s at \"%s\" line %d\n",
360
$class ? "class" : "object",
361
$class ? " via $class" : '',
362
$B::Utils::file, $B::Utils::line;
366
my($name_op) = grep($_->name eq 'gv', @kids);
368
my $gv = gv_or_padgv($name_op);
369
printf "function call to %s at \"%s\" line %d\n",
370
$gv->NAME, $B::Utils::file, $B::Utils::line;
373
printf "function call using symbolic ref at \"%s\" line %d\n",
374
$B::Utils::file, $B::Utils::line;
383
if ($op->isa("B::PADOP")) {
384
return padval($op->padix);
386
else { # class($op) eq "SVOP"
392
sub _class_or_object_method {
396
my($classop) = $kids[1];
397
if( $classop->name eq 'const' ) {
398
$class = const_sv($classop)->PV;