7 use B qw(peekop class walkoptree walkoptree_exec
8 main_start main_root cstring sv_undef SVf_NOK SVf_IOK);
10 my (@optype, @specialsv_name);
14 B::Asmdata->import (qw(@optype @specialsv_name));
16 B->import (qw(@optype @specialsv_name));
20 eval q|sub B::GV::SAFENAME {
21 my $name = (shift())->NAME;
22 # The regex below corresponds to the isCONTROLVAR macro from toke.c
23 $name =~ s/^([\cA-\cZ\c\\c[\c]\c?\c_\c^])/"^".chr(64 ^ ord($1))/e;
28 my ($have_B_Flags, $have_B_Flags_extra);
29 if (!$ENV{PERL_CORE}){ # avoid CORE test crashes
30 eval { require B::Flags and $have_B_Flags++ };
31 $have_B_Flags_extra++ if $have_B_Flags and $B::Flags::VERSION gt '0.03';
37 my $addr = ${$op} ? $op->ppaddr : '';
38 $addr =~ s/^PL_ppaddr// if $addr;
40 return sprintf "0x%08x %6s %s", ${$op}, class($op), $addr;
42 return sprintf "0x%x %6s %s", ${$op}, '', $addr;
48 printf <<'EOT', class($op), $$op, _printop($op), _printop($op->next), _printop($op->sibling), $op->targ, $op->type, $op->name;
57 printf <<'EOT', $op->opt;
61 printf <<'EOT', $op->seq;
66 printf <<'EOT', $op->flags, $op->flagspv, $op->private, $op->privatepv;
71 printf <<'EOT', $op->flags, $op->private;
81 printf "\top_first\t%s\n", _printop($op->first);
86 $op->B::UNOP::debug();
87 printf "\top_last \t%s\n", _printop($op->last);
92 $op->B::BINOP::debug();
93 printf <<'EOT', _printop($op->redoop), _printop($op->nextop), _printop($op->lastop);
100 sub B::LOGOP::debug {
102 $op->B::UNOP::debug();
103 printf "\top_other\t%s\n", _printop($op->other);
106 sub B::LISTOP::debug {
108 $op->B::BINOP::debug();
109 printf "\top_children\t%d\n", $op->children;
114 $op->B::LISTOP::debug();
115 printf "\top_pmreplroot\t0x%x\n", $] < 5.008 ? ${$op->pmreplroot} : $op->pmreplroot;
116 printf "\top_pmreplstart\t0x%x\n", ${$op->pmreplstart};
117 printf "\top_pmnext\t0x%x\n", ${$op->pmnext} if $] < 5.009005;
118 if ($Config{'useithreads'}) {
119 printf "\top_pmstashpv\t%s\n", cstring($op->pmstashpv);
120 printf "\top_pmoffset\t%d\n", $op->pmoffset;
122 printf "\top_pmstash\t%s\n", cstring($op->pmstash);
124 printf "\top_precomp\t%s\n", cstring($op->precomp);
125 printf "\top_pmflags\t0x%x\n", $op->pmflags;
126 printf "\top_reflags\t0x%x\n", $op->reflags if $] >= 5.009;
127 printf "\top_pmpermflags\t0x%x\n", $op->pmpermflags if $] < 5.009;
128 printf "\top_pmdynflags\t0x%x\n", $op->pmdynflags if $] < 5.009;
129 $op->pmreplroot->debug if $] < 5.008;
135 my $warnings = ref $op->warnings ? ${$op->warnings} : 0;
136 printf <<'EOT', $op->label, $op->stashpv, $op->file, $op->cop_seq, $op->arybase, $op->line, $warnings;
145 if ($] > 5.008 and $] < 5.011) {
146 my $cop_io = class($op->io) eq 'SPECIAL' ? '' : $op->io->as_string;
147 printf(" cop_io %s\n", cstring($cop_io));
154 printf "\top_sv\t\t0x%x\n", ${$op->sv};
158 sub B::METHOP::debug {
162 printf "\top_first\t0x%x\n", ${$op->first};
165 printf "\top_meth_sv\t0x%x\n", ${$op->meth_sv};
173 printf "\top_pv\t\t%s\n", cstring($op->pv);
176 sub B::PADOP::debug {
179 printf "\top_padix\t%ld\n", $op->padix;
184 if ($$sv == ${sv_undef()}) {
187 printf "NULL (0x%x)\n", $$sv;
194 print class($sv), " = NULL\n";
197 printf <<'EOT', class($sv), $$sv, $sv->REFCNT;
201 printf "\tFLAGS\t\t0x%x", $sv->FLAGS;
203 printf "\t%s", $have_B_Flags_extra ? $sv->flagspv(0) : $sv->flagspv;
211 printf <<'EOT', ${$rv->RV};
221 printf <<'EOT', cstring($pv), $sv->CUR, $sv->LEN;
231 printf "\txiv_iv\t\t%d\n", $sv->IV if $sv->FLAGS & SVf_IOK;
237 printf "\txnv_nv\t\t%s\n", $sv->NV if $sv->FLAGS & SVf_NOK;
243 printf "\txiv_iv\t\t%d\n", $sv->IV if $sv->FLAGS & SVf_IOK;
248 $sv->B::PVIV::debug();
249 printf "\txnv_nv\t\t%s\n", $sv->NV if $sv->FLAGS & SVf_NOK;
254 $sv->B::PVNV::debug();
255 printf "\txlv_targoff\t%d\n", $sv->TARGOFF;
256 printf "\txlv_targlen\t%u\n", $sv->TARGLEN;
257 printf "\txlv_type\t%s\n", cstring(chr($sv->TYPE));
262 $sv->B::PVNV::debug();
263 printf "\txbm_useful\t%d\n", $sv->USEFUL;
264 printf "\txbm_previous\t%u\n", $sv->PREVIOUS;
265 printf "\txbm_rare\t%s\n", cstring(chr($sv->RARE));
270 $sv->B::PVNV::debug();
271 my ($stash) = $sv->STASH;
272 my ($start) = $sv->START;
273 my ($root) = $sv->ROOT;
274 my ($padlist) = $sv->PADLIST;
275 my ($file) = $sv->FILE;
277 printf <<'EOT', $$stash, $$start, $$root;
282 if ( $]>5.017 && ($sv->FLAGS & 0x40000)) { #lexsub
283 printf("\tNAME\t%%s\n", $sv->NAME);
285 printf("\tGV\t%0x%x\t%s\n", $$gv, $gv->SAFENAME);
287 printf <<'EOT', $file, $sv->DEPTH, $padlist, ${$sv->OUTSIDE};
293 printf("\tOUTSIDE_SEQ\t%d\n", $sv->OUTSIDE_SEQ) if $] > 5.007;
295 my $SVt_PVCV = $] < 5.010 ? 12 : 13;
296 printf("\tCvFLAGS\t0x%x\t%s\n", $sv->CvFLAGS,
297 $have_B_Flags_extra ? $sv->flagspv($SVt_PVCV) : $sv->flagspv);
299 printf("\tCvFLAGS\t0x%x\n", $sv->CvFLAGS);
301 $start->debug if $start;
302 $root->debug if $root;
304 $padlist->debug if $padlist;
315 # tied arrays may leave out FETCHSIZE
316 my (@array) = eval { $av->ARRAY; };
317 print "\tARRAY\t\t(", join(", ", map("0x" . $$_, @array)), ")\n";
318 my $fill = eval { scalar(@array) };
319 if ($Config{'useithreads'} && class($av) ne 'PADLIST') {
320 printf <<'EOT', $fill, $av->MAX, $av->OFF;
326 printf <<'EOT', $fill, $av->MAX;
333 printf("\tAvFLAGS\t0x%x\t%s\n", $av->AvFLAGS,
334 $have_B_Flags_extra ? $av->flagspv(10) : $av->flagspv);
336 printf("\tAvFLAGS\t0x%x\n", $av->AvFLAGS);
343 if ($done_gv{$$gv}++) {
344 printf "GV %s::%s\n", $gv->STASH->NAME, $gv->SAFENAME;
351 printf <<'EOT', $gv->SAFENAME, $gv->STASH->NAME, $gv->STASH, $$sv, $gv->GvREFCNT, $gv->FORM, $$av, ${$gv->HV}, ${$gv->EGV}, $$cv, $gv->CVGEN, $gv->LINE, $gv->FILE, $gv->GvFLAGS;
366 my $SVt_PVGV = $] < 5.010 ? 13 : 9;
367 printf("\tGvFLAGS\t0x%x\t%s\n", $gv->GvFLAGS,
368 $have_B_Flags_extra ? $gv->flagspv($SVt_PVGV) : $gv->flagspv);
370 printf("\tGvFLAGS\t0x%x\n", $gv->GvFLAGS);
377 sub B::SPECIAL::debug {
379 my $i = ref $sv ? $$sv : 0;
380 print defined $specialsv_name[$i] ? $specialsv_name[$i] : "", "\n";
383 sub B::PADLIST::debug {
385 printf <<'EOT', class($padlist), $$padlist, $padlist->REFCNT;
389 _array_debug($padlist);
395 $DB::single = 1 if defined &DB::DB;
396 if ($order && $order eq "exec") {
397 return sub { walkoptree_exec(main_start, "debug") }
399 return sub { walkoptree(main_root, "debug") }
409 B::Debug - Walk Perl syntax tree, printing debug info about ops
413 perl -MO=Debug foo.pl
414 perl -MO=Debug,-exec foo.pl
418 See F<ext/B/README> and the newer L<B::Concise>, L<B::Terse>.
422 With option -exec, walks tree in execute order,
423 otherwise in basic order.
427 Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>
428 Reini Urban C<rurban@cpan.org>
432 Copyright (c) 1996, 1997 Malcolm Beattie
433 Copyright (c) 2008, 2010, 2013, 2014 Reini Urban
435 This program is free software; you can redistribute it and/or modify
436 it under the terms of either:
438 a) the GNU General Public License as published by the Free
439 Software Foundation; either version 1, or (at your option) any
442 b) the "Artistic License" which comes with this kit.
444 This program is distributed in the hope that it will be useful,
445 but WITHOUT ANY WARRANTY; without even the implied warranty of
446 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either
447 the GNU General Public License or the Artistic License for more details.
449 You should have received a copy of the Artistic License with this kit,
450 in the file named "Artistic". If not, you can get one from the Perl
451 distribution. You should also have received a copy of the GNU General
452 Public License, in the file named "Copying". If not, you can get one
453 from the Perl distribution or else write to the Free Software Foundation,
454 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.