Commit | Line | Data |
---|---|---|
a798dbf2 MB |
1 | package B::Debug; |
2 | use strict; | |
3 | use B qw(peekop class walkoptree walkoptree_exec | |
4 | main_start main_root cstring sv_undef); | |
5 | use B::Asmdata qw(@specialsv_name); | |
6 | ||
7 | my %done_gv; | |
8 | ||
9 | sub B::OP::debug { | |
10 | my ($op) = @_; | |
11 | printf <<'EOT', class($op), $$op, ${$op->next}, ${$op->sibling}, $op->ppaddr, $op->targ, $op->type, $op->seq, $op->flags, $op->private; | |
12 | %s (0x%lx) | |
13 | op_next 0x%x | |
14 | op_sibling 0x%x | |
15 | op_ppaddr %s | |
16 | op_targ %d | |
17 | op_type %d | |
18 | op_seq %d | |
19 | op_flags %d | |
20 | op_private %d | |
21 | EOT | |
22 | } | |
23 | ||
24 | sub B::UNOP::debug { | |
25 | my ($op) = @_; | |
26 | $op->B::OP::debug(); | |
27 | printf "\top_first\t0x%x\n", ${$op->first}; | |
28 | } | |
29 | ||
30 | sub B::BINOP::debug { | |
31 | my ($op) = @_; | |
32 | $op->B::UNOP::debug(); | |
33 | printf "\top_last\t\t0x%x\n", ${$op->last}; | |
34 | } | |
35 | ||
36 | sub B::LOGOP::debug { | |
37 | my ($op) = @_; | |
38 | $op->B::UNOP::debug(); | |
39 | printf "\top_other\t0x%x\n", ${$op->other}; | |
40 | } | |
41 | ||
42 | sub B::CONDOP::debug { | |
43 | my ($op) = @_; | |
44 | $op->B::UNOP::debug(); | |
45 | printf "\top_true\t0x%x\n", ${$op->true}; | |
46 | printf "\top_false\t0x%x\n", ${$op->false}; | |
47 | } | |
48 | ||
49 | sub B::LISTOP::debug { | |
50 | my ($op) = @_; | |
51 | $op->B::BINOP::debug(); | |
52 | printf "\top_children\t%d\n", $op->children; | |
53 | } | |
54 | ||
55 | sub B::PMOP::debug { | |
56 | my ($op) = @_; | |
57 | $op->B::LISTOP::debug(); | |
58 | printf "\top_pmreplroot\t0x%x\n", ${$op->pmreplroot}; | |
59 | printf "\top_pmreplstart\t0x%x\n", ${$op->pmreplstart}; | |
60 | printf "\top_pmnext\t0x%x\n", ${$op->pmnext}; | |
61 | printf "\top_pmregexp->precomp\t%s\n", cstring($op->precomp); | |
62 | printf "\top_pmflags\t0x%x\n", $op->pmflags; | |
63 | $op->pmshort->debug; | |
64 | $op->pmreplroot->debug; | |
65 | } | |
66 | ||
67 | sub B::COP::debug { | |
68 | my ($op) = @_; | |
69 | $op->B::OP::debug(); | |
70 | my ($filegv) = $op->filegv; | |
71 | printf <<'EOT', $op->label, ${$op->stash}, $$filegv, $op->seq, $op->arybase, $op->line; | |
72 | cop_label %s | |
73 | cop_stash 0x%x | |
74 | cop_filegv 0x%x | |
75 | cop_seq %d | |
76 | cop_arybase %d | |
77 | cop_line %d | |
78 | EOT | |
79 | $filegv->debug; | |
80 | } | |
81 | ||
82 | sub B::SVOP::debug { | |
83 | my ($op) = @_; | |
84 | $op->B::OP::debug(); | |
85 | printf "\top_sv\t\t0x%x\n", ${$op->sv}; | |
86 | $op->sv->debug; | |
87 | } | |
88 | ||
89 | sub B::PVOP::debug { | |
90 | my ($op) = @_; | |
91 | $op->B::OP::debug(); | |
92 | printf "\top_pv\t\t0x%x\n", $op->pv; | |
93 | } | |
94 | ||
95 | sub B::GVOP::debug { | |
96 | my ($op) = @_; | |
97 | $op->B::OP::debug(); | |
98 | printf "\top_gv\t\t0x%x\n", ${$op->gv}; | |
99 | $op->gv->debug; | |
100 | } | |
101 | ||
102 | sub B::CVOP::debug { | |
103 | my ($op) = @_; | |
104 | $op->B::OP::debug(); | |
105 | printf "\top_cv\t\t0x%x\n", ${$op->cv}; | |
106 | } | |
107 | ||
108 | sub B::NULL::debug { | |
109 | my ($sv) = @_; | |
110 | if ($$sv == ${sv_undef()}) { | |
111 | print "&sv_undef\n"; | |
112 | } else { | |
113 | printf "NULL (0x%x)\n", $$sv; | |
114 | } | |
115 | } | |
116 | ||
117 | sub B::SV::debug { | |
118 | my ($sv) = @_; | |
119 | if (!$$sv) { | |
120 | print class($sv), " = NULL\n"; | |
121 | return; | |
122 | } | |
123 | printf <<'EOT', class($sv), $$sv, $sv->REFCNT, $sv->FLAGS; | |
124 | %s (0x%x) | |
125 | REFCNT %d | |
126 | FLAGS 0x%x | |
127 | EOT | |
128 | } | |
129 | ||
130 | sub B::PV::debug { | |
131 | my ($sv) = @_; | |
132 | $sv->B::SV::debug(); | |
133 | my $pv = $sv->PV(); | |
134 | printf <<'EOT', cstring($pv), length($pv); | |
135 | xpv_pv %s | |
136 | xpv_cur %d | |
137 | EOT | |
138 | } | |
139 | ||
140 | sub B::IV::debug { | |
141 | my ($sv) = @_; | |
142 | $sv->B::SV::debug(); | |
143 | printf "\txiv_iv\t\t%d\n", $sv->IV; | |
144 | } | |
145 | ||
146 | sub B::NV::debug { | |
147 | my ($sv) = @_; | |
148 | $sv->B::IV::debug(); | |
149 | printf "\txnv_nv\t\t%s\n", $sv->NV; | |
150 | } | |
151 | ||
152 | sub B::PVIV::debug { | |
153 | my ($sv) = @_; | |
154 | $sv->B::PV::debug(); | |
155 | printf "\txiv_iv\t\t%d\n", $sv->IV; | |
156 | } | |
157 | ||
158 | sub B::PVNV::debug { | |
159 | my ($sv) = @_; | |
160 | $sv->B::PVIV::debug(); | |
161 | printf "\txnv_nv\t\t%s\n", $sv->NV; | |
162 | } | |
163 | ||
164 | sub B::PVLV::debug { | |
165 | my ($sv) = @_; | |
166 | $sv->B::PVNV::debug(); | |
167 | printf "\txlv_targoff\t%d\n", $sv->TARGOFF; | |
168 | printf "\txlv_targlen\t%u\n", $sv->TARGLEN; | |
169 | printf "\txlv_type\t%s\n", cstring(chr($sv->TYPE)); | |
170 | } | |
171 | ||
172 | sub B::BM::debug { | |
173 | my ($sv) = @_; | |
174 | $sv->B::PVNV::debug(); | |
175 | printf "\txbm_useful\t%d\n", $sv->USEFUL; | |
176 | printf "\txbm_previous\t%u\n", $sv->PREVIOUS; | |
177 | printf "\txbm_rare\t%s\n", cstring(chr($sv->RARE)); | |
178 | } | |
179 | ||
180 | sub B::CV::debug { | |
181 | my ($sv) = @_; | |
182 | $sv->B::PVNV::debug(); | |
183 | my ($stash) = $sv->STASH; | |
184 | my ($start) = $sv->START; | |
185 | my ($root) = $sv->ROOT; | |
186 | my ($padlist) = $sv->PADLIST; | |
187 | my ($gv) = $sv->GV; | |
188 | my ($filegv) = $sv->FILEGV; | |
189 | printf <<'EOT', $$stash, $$start, $$root, $$gv, $$filegv, $sv->DEPTH, $padlist, ${$sv->OUTSIDE}; | |
190 | STASH 0x%x | |
191 | START 0x%x | |
192 | ROOT 0x%x | |
193 | GV 0x%x | |
194 | FILEGV 0x%x | |
195 | DEPTH %d | |
196 | PADLIST 0x%x | |
197 | OUTSIDE 0x%x | |
198 | EOT | |
199 | $start->debug if $start; | |
200 | $root->debug if $root; | |
201 | $gv->debug if $gv; | |
202 | $filegv->debug if $filegv; | |
203 | $padlist->debug if $padlist; | |
204 | } | |
205 | ||
206 | sub B::AV::debug { | |
207 | my ($av) = @_; | |
208 | $av->B::SV::debug; | |
209 | my(@array) = $av->ARRAY; | |
210 | print "\tARRAY\t\t(", join(", ", map("0x" . $$_, @array)), ")\n"; | |
211 | printf <<'EOT', scalar(@array), $av->MAX, $av->OFF, $av->AvFLAGS; | |
212 | FILL %d | |
213 | MAX %d | |
214 | OFF %d | |
215 | AvFLAGS %d | |
216 | EOT | |
217 | } | |
218 | ||
219 | sub B::GV::debug { | |
220 | my ($gv) = @_; | |
221 | if ($done_gv{$$gv}++) { | |
222 | printf "GV %s::%s\n", $gv->STASH->NAME, $gv->NAME; | |
223 | return; | |
224 | } | |
225 | my ($sv) = $gv->SV; | |
226 | my ($av) = $gv->AV; | |
227 | my ($cv) = $gv->CV; | |
228 | $gv->B::SV::debug; | |
229 | printf <<'EOT', $gv->NAME, $gv->STASH->NAME, $gv->STASH, $$sv, $gv->GvREFCNT, $gv->FORM, $$av, ${$gv->HV}, ${$gv->EGV}, $$cv, $gv->CVGEN, $gv->LINE, $gv->FILEGV, $gv->GvFLAGS; | |
230 | NAME %s | |
231 | STASH %s (0x%x) | |
232 | SV 0x%x | |
233 | GvREFCNT %d | |
234 | FORM 0x%x | |
235 | AV 0x%x | |
236 | HV 0x%x | |
237 | EGV 0x%x | |
238 | CV 0x%x | |
239 | CVGEN %d | |
240 | LINE %d | |
241 | FILEGV 0x%x | |
242 | GvFLAGS 0x%x | |
243 | EOT | |
244 | $sv->debug if $sv; | |
245 | $av->debug if $av; | |
246 | $cv->debug if $cv; | |
247 | } | |
248 | ||
249 | sub B::SPECIAL::debug { | |
250 | my $sv = shift; | |
251 | print $specialsv_name[$$sv], "\n"; | |
252 | } | |
253 | ||
254 | sub compile { | |
255 | my $order = shift; | |
256 | if ($order eq "exec") { | |
257 | return sub { walkoptree_exec(main_start, "debug") } | |
258 | } else { | |
259 | return sub { walkoptree(main_root, "debug") } | |
260 | } | |
261 | } | |
262 | ||
263 | 1; |