Commit | Line | Data |
---|---|---|
c5be433b | 1 | #define PERL_NO_GET_CONTEXT |
3967c732 JD |
2 | #include "EXTERN.h" |
3 | #include "perl.h" | |
4 | #include "XSUB.h" | |
5 | ||
f681a178 | 6 | static bool |
bd16a5f0 IZ |
7 | _runops_debug(int flag) |
8 | { | |
9 | dTHX; | |
ef69c8fc | 10 | const bool d = PL_runops == Perl_runops_debug; |
bd16a5f0 IZ |
11 | |
12 | if (flag >= 0) | |
ef69c8fc | 13 | PL_runops = flag ? Perl_runops_debug : Perl_runops_standard; |
bd16a5f0 IZ |
14 | return d; |
15 | } | |
16 | ||
f681a178 | 17 | static SV * |
cea2e8a9 | 18 | DeadCode(pTHX) |
3967c732 | 19 | { |
8ecf7187 GS |
20 | #ifdef PURIFY |
21 | return Nullsv; | |
22 | #else | |
3967c732 | 23 | SV* sva; |
9c5ffd7c | 24 | SV* sv; |
3967c732 | 25 | SV* ret = newRV_noinc((SV*)newAV()); |
5aaab254 | 26 | SV* svend; |
3967c732 JD |
27 | int tm = 0, tref = 0, ts = 0, ta = 0, tas = 0; |
28 | ||
29 | for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) { | |
30 | svend = &sva[SvREFCNT(sva)]; | |
31 | for (sv = sva + 1; sv < svend; ++sv) { | |
32 | if (SvTYPE(sv) == SVt_PVCV) { | |
33 | CV *cv = (CV*)sv; | |
eacbb379 | 34 | PADLIST* padlist; |
c9795579 | 35 | AV *argav; |
3967c732 JD |
36 | SV** svp; |
37 | SV** pad; | |
38 | int i = 0, j, levelm, totm = 0, levelref, totref = 0; | |
39 | int levels, tots = 0, levela, tota = 0, levelas, totas = 0; | |
40 | int dumpit = 0; | |
41 | ||
aed2304a | 42 | if (CvISXSUB(sv)) { |
3967c732 JD |
43 | continue; /* XSUB */ |
44 | } | |
45 | if (!CvGV(sv)) { | |
46 | continue; /* file-level scope. */ | |
47 | } | |
48 | if (!CvROOT(cv)) { | |
bf49b057 | 49 | /* PerlIO_printf(Perl_debug_log, " no root?!\n"); */ |
3967c732 JD |
50 | continue; /* autoloading stub. */ |
51 | } | |
bf49b057 | 52 | do_gvgv_dump(0, Perl_debug_log, "GVGV::GV", CvGV(sv)); |
3967c732 | 53 | if (CvDEPTH(cv)) { |
bf49b057 | 54 | PerlIO_printf(Perl_debug_log, " busy\n"); |
3967c732 JD |
55 | continue; |
56 | } | |
eacbb379 | 57 | padlist = CvPADLIST(cv); |
86d2498c FC |
58 | svp = (SV**) PadlistARRAY(padlist); |
59 | while (++i <= PadlistMAX(padlist)) { /* Depth. */ | |
3967c732 JD |
60 | SV **args; |
61 | ||
c9795579 | 62 | if (!svp[i]) continue; |
3967c732 JD |
63 | pad = AvARRAY((AV*)svp[i]); |
64 | argav = (AV*)pad[0]; | |
65 | if (!argav || (SV*)argav == &PL_sv_undef) { | |
bf49b057 | 66 | PerlIO_printf(Perl_debug_log, " closure-template\n"); |
3967c732 JD |
67 | continue; |
68 | } | |
69 | args = AvARRAY(argav); | |
70 | levelm = levels = levelref = levelas = 0; | |
71 | levela = sizeof(SV*) * (AvMAX(argav) + 1); | |
72 | if (AvREAL(argav)) { | |
73 | for (j = 0; j < AvFILL(argav); j++) { | |
74 | if (SvROK(args[j])) { | |
bf49b057 | 75 | PerlIO_printf(Perl_debug_log, " ref in args!\n"); |
3967c732 JD |
76 | levelref++; |
77 | } | |
78 | /* else if (SvPOK(args[j]) && SvPVX(args[j])) { */ | |
79 | else if (SvTYPE(args[j]) >= SVt_PV && SvLEN(args[j])) { | |
80 | levelas += SvLEN(args[j])/SvREFCNT(args[j]); | |
81 | } | |
82 | } | |
83 | } | |
84 | for (j = 1; j < AvFILL((AV*)svp[1]); j++) { /* Vars. */ | |
ce0d59fd | 85 | if (!pad[j]) continue; |
3967c732 JD |
86 | if (SvROK(pad[j])) { |
87 | levelref++; | |
bf49b057 | 88 | do_sv_dump(0, Perl_debug_log, pad[j], 0, 4, 0, 0); |
3967c732 JD |
89 | dumpit = 1; |
90 | } | |
91 | /* else if (SvPOK(pad[j]) && SvPVX(pad[j])) { */ | |
92 | else if (SvTYPE(pad[j]) >= SVt_PVAV) { | |
93 | if (!SvPADMY(pad[j])) { | |
94 | levelref++; | |
bf49b057 | 95 | do_sv_dump(0, Perl_debug_log, pad[j], 0, 4, 0, 0); |
3967c732 JD |
96 | dumpit = 1; |
97 | } | |
98 | } | |
99 | else if (SvTYPE(pad[j]) >= SVt_PV && SvLEN(pad[j])) { | |
3967c732 JD |
100 | levels++; |
101 | levelm += SvLEN(pad[j])/SvREFCNT(pad[j]); | |
102 | /* Dump(pad[j],4); */ | |
103 | } | |
104 | } | |
bf49b057 | 105 | PerlIO_printf(Perl_debug_log, " level %i: refs: %i, strings: %i in %i,\targsarray: %i, argsstrings: %i\n", |
3967c732 JD |
106 | i, levelref, levelm, levels, levela, levelas); |
107 | totm += levelm; | |
108 | tota += levela; | |
109 | totas += levelas; | |
110 | tots += levels; | |
111 | totref += levelref; | |
112 | if (dumpit) | |
bf49b057 | 113 | do_sv_dump(0, Perl_debug_log, (SV*)cv, 0, 2, 0, 0); |
3967c732 | 114 | } |
86d2498c | 115 | if (PadlistMAX(padlist) > 1) { |
bf49b057 | 116 | PerlIO_printf(Perl_debug_log, " total: refs: %i, strings: %i in %i,\targsarrays: %i, argsstrings: %i\n", |
3967c732 JD |
117 | totref, totm, tots, tota, totas); |
118 | } | |
119 | tref += totref; | |
120 | tm += totm; | |
121 | ts += tots; | |
122 | ta += tota; | |
123 | tas += totas; | |
124 | } | |
125 | } | |
126 | } | |
bf49b057 | 127 | PerlIO_printf(Perl_debug_log, "total: refs: %i, strings: %i in %i\targsarray: %i, argsstrings: %i\n", tref, tm, ts, ta, tas); |
3967c732 JD |
128 | |
129 | return ret; | |
3967c732 | 130 | #endif /* !PURIFY */ |
8ecf7187 | 131 | } |
3967c732 | 132 | |
3128eefe | 133 | #if defined(MYMALLOC) |
3967c732 JD |
134 | # define mstat(str) dump_mstats(str) |
135 | #else | |
136 | # define mstat(str) \ | |
3128eefe | 137 | PerlIO_printf(Perl_debug_log, "%s: perl not compiled with MYMALLOC\n",str); |
3967c732 JD |
138 | #endif |
139 | ||
3128eefe | 140 | #if defined(MYMALLOC) |
d1424c31 IZ |
141 | |
142 | /* Very coarse overestimate, 2-per-power-of-2, one more to determine NBUCKETS. */ | |
143 | # define _NBUCKETS (2*8*IVSIZE+1) | |
144 | ||
145 | struct mstats_buffer | |
146 | { | |
147 | perl_mstats_t buffer; | |
148 | UV buf[_NBUCKETS*4]; | |
149 | }; | |
150 | ||
f681a178 | 151 | static void |
d1424c31 IZ |
152 | _fill_mstats(struct mstats_buffer *b, int level) |
153 | { | |
c024d977 | 154 | dTHX; |
d1424c31 IZ |
155 | b->buffer.nfree = b->buf; |
156 | b->buffer.ntotal = b->buf + _NBUCKETS; | |
157 | b->buffer.bucket_mem_size = b->buf + 2*_NBUCKETS; | |
158 | b->buffer.bucket_available_size = b->buf + 3*_NBUCKETS; | |
159 | Zero(b->buf, (level ? 4*_NBUCKETS: 2*_NBUCKETS), unsigned long); | |
160 | get_mstats(&(b->buffer), _NBUCKETS, level); | |
161 | } | |
162 | ||
f681a178 | 163 | static void |
d1424c31 IZ |
164 | fill_mstats(SV *sv, int level) |
165 | { | |
c024d977 | 166 | dTHX; |
d1424c31 IZ |
167 | |
168 | if (SvREADONLY(sv)) | |
169 | croak("Cannot modify a readonly value"); | |
b59747ac | 170 | sv_grow(sv, sizeof(struct mstats_buffer)+1); |
d1424c31 IZ |
171 | _fill_mstats((struct mstats_buffer*)SvPVX(sv),level); |
172 | SvCUR_set(sv, sizeof(struct mstats_buffer)); | |
173 | *SvEND(sv) = '\0'; | |
174 | SvPOK_only(sv); | |
175 | } | |
176 | ||
f681a178 | 177 | static void |
7698c435 | 178 | _mstats_to_hv(HV *hv, const struct mstats_buffer *b, int level) |
d1424c31 | 179 | { |
c024d977 | 180 | dTHX; |
d1424c31 IZ |
181 | SV **svp; |
182 | int type; | |
183 | ||
184 | svp = hv_fetch(hv, "topbucket", 9, 1); | |
185 | sv_setiv(*svp, b->buffer.topbucket); | |
186 | ||
187 | svp = hv_fetch(hv, "topbucket_ev", 12, 1); | |
188 | sv_setiv(*svp, b->buffer.topbucket_ev); | |
189 | ||
190 | svp = hv_fetch(hv, "topbucket_odd", 13, 1); | |
191 | sv_setiv(*svp, b->buffer.topbucket_odd); | |
192 | ||
193 | svp = hv_fetch(hv, "totfree", 7, 1); | |
194 | sv_setiv(*svp, b->buffer.totfree); | |
195 | ||
196 | svp = hv_fetch(hv, "total", 5, 1); | |
197 | sv_setiv(*svp, b->buffer.total); | |
198 | ||
199 | svp = hv_fetch(hv, "total_chain", 11, 1); | |
200 | sv_setiv(*svp, b->buffer.total_chain); | |
201 | ||
202 | svp = hv_fetch(hv, "total_sbrk", 10, 1); | |
203 | sv_setiv(*svp, b->buffer.total_sbrk); | |
204 | ||
205 | svp = hv_fetch(hv, "sbrks", 5, 1); | |
206 | sv_setiv(*svp, b->buffer.sbrks); | |
207 | ||
208 | svp = hv_fetch(hv, "sbrk_good", 9, 1); | |
209 | sv_setiv(*svp, b->buffer.sbrk_good); | |
210 | ||
211 | svp = hv_fetch(hv, "sbrk_slack", 10, 1); | |
212 | sv_setiv(*svp, b->buffer.sbrk_slack); | |
213 | ||
214 | svp = hv_fetch(hv, "start_slack", 11, 1); | |
215 | sv_setiv(*svp, b->buffer.start_slack); | |
216 | ||
217 | svp = hv_fetch(hv, "sbrked_remains", 14, 1); | |
218 | sv_setiv(*svp, b->buffer.sbrked_remains); | |
219 | ||
220 | svp = hv_fetch(hv, "minbucket", 9, 1); | |
221 | sv_setiv(*svp, b->buffer.minbucket); | |
222 | ||
223 | svp = hv_fetch(hv, "nbuckets", 8, 1); | |
224 | sv_setiv(*svp, b->buffer.nbuckets); | |
225 | ||
226 | if (_NBUCKETS < b->buffer.nbuckets) | |
227 | warn("FIXME: internal mstats buffer too short"); | |
228 | ||
229 | for (type = 0; type < (level ? 4 : 2); type++) { | |
f0f74ded | 230 | UV *p = 0, *p1 = 0, i; |
d1424c31 | 231 | AV *av; |
d1424c31 IZ |
232 | static const char *types[4] = { |
233 | "free", "used", "mem_size", "available_size" | |
234 | }; | |
235 | ||
236 | svp = hv_fetch(hv, types[type], strlen(types[type]), 1); | |
237 | ||
238 | if (SvOK(*svp) && !(SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVAV)) | |
239 | croak("Unexpected value for the key '%s' in the mstats hash", types[type]); | |
240 | if (!SvOK(*svp)) { | |
241 | av = newAV(); | |
d05c1ba0 | 242 | (void)SvUPGRADE(*svp, SVt_RV); |
b162af07 | 243 | SvRV_set(*svp, (SV*)av); |
d1424c31 IZ |
244 | SvROK_on(*svp); |
245 | } else | |
246 | av = (AV*)SvRV(*svp); | |
247 | ||
248 | av_extend(av, b->buffer.nbuckets - 1); | |
249 | /* XXXX What is the official way to reduce the size of the array? */ | |
250 | switch (type) { | |
251 | case 0: | |
252 | p = b->buffer.nfree; | |
253 | break; | |
254 | case 1: | |
255 | p = b->buffer.ntotal; | |
256 | p1 = b->buffer.nfree; | |
257 | break; | |
258 | case 2: | |
259 | p = b->buffer.bucket_mem_size; | |
260 | break; | |
261 | case 3: | |
262 | p = b->buffer.bucket_available_size; | |
263 | break; | |
264 | } | |
265 | for (i = 0; i < b->buffer.nbuckets; i++) { | |
266 | svp = av_fetch(av, i, 1); | |
267 | if (type == 1) | |
268 | sv_setiv(*svp, p[i]-p1[i]); | |
269 | else | |
270 | sv_setuv(*svp, p[i]); | |
271 | } | |
272 | } | |
273 | } | |
f681a178 AT |
274 | |
275 | static void | |
d1424c31 IZ |
276 | mstats_fillhash(SV *sv, int level) |
277 | { | |
278 | struct mstats_buffer buf; | |
279 | ||
280 | if (!(SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV)) | |
281 | croak("Not a hash reference"); | |
282 | _fill_mstats(&buf, level); | |
283 | _mstats_to_hv((HV *)SvRV(sv), &buf, level); | |
284 | } | |
f681a178 AT |
285 | |
286 | static void | |
d1424c31 IZ |
287 | mstats2hash(SV *sv, SV *rv, int level) |
288 | { | |
289 | if (!(SvROK(rv) && SvTYPE(SvRV(rv)) == SVt_PVHV)) | |
290 | croak("Not a hash reference"); | |
291 | if (!SvPOK(sv)) | |
292 | croak("Undefined value when expecting mstats buffer"); | |
293 | if (SvCUR(sv) != sizeof(struct mstats_buffer)) | |
294 | croak("Wrong size for a value with a mstats buffer"); | |
295 | _mstats_to_hv((HV *)SvRV(rv), (struct mstats_buffer*)SvPVX(sv), level); | |
296 | } | |
3128eefe | 297 | #else /* defined(MYMALLOC) */ |
f681a178 | 298 | static void |
d1424c31 IZ |
299 | fill_mstats(SV *sv, int level) |
300 | { | |
c33e8be1 Z |
301 | PERL_UNUSED_ARG(sv); |
302 | PERL_UNUSED_ARG(level); | |
d1424c31 IZ |
303 | croak("Cannot report mstats without Perl malloc"); |
304 | } | |
f681a178 AT |
305 | |
306 | static void | |
d1424c31 IZ |
307 | mstats_fillhash(SV *sv, int level) |
308 | { | |
c33e8be1 Z |
309 | PERL_UNUSED_ARG(sv); |
310 | PERL_UNUSED_ARG(level); | |
d1424c31 IZ |
311 | croak("Cannot report mstats without Perl malloc"); |
312 | } | |
f681a178 AT |
313 | |
314 | static void | |
d1424c31 IZ |
315 | mstats2hash(SV *sv, SV *rv, int level) |
316 | { | |
c33e8be1 Z |
317 | PERL_UNUSED_ARG(sv); |
318 | PERL_UNUSED_ARG(rv); | |
319 | PERL_UNUSED_ARG(level); | |
d1424c31 IZ |
320 | croak("Cannot report mstats without Perl malloc"); |
321 | } | |
3128eefe | 322 | #endif /* defined(MYMALLOC) */ |
d1424c31 | 323 | |
83ee9e09 GS |
324 | #define _CvGV(cv) \ |
325 | (SvROK(cv) && (SvTYPE(SvRV(cv))==SVt_PVCV) \ | |
15bcf759 | 326 | ? SvREFCNT_inc(CvGV((CV*)SvRV(cv))) : &PL_sv_undef) |
83ee9e09 | 327 | |
34b94bc4 FC |
328 | static void |
329 | S_do_dump(pTHX_ SV *const sv, I32 lim) | |
330 | { | |
331 | dVAR; | |
332 | SV *pv_lim_sv = perl_get_sv("Devel::Peek::pv_limit", 0); | |
333 | const STRLEN pv_lim = pv_lim_sv ? SvIV(pv_lim_sv) : 0; | |
334 | SV *dumpop = perl_get_sv("Devel::Peek::dump_ops", 0); | |
335 | const U16 save_dumpindent = PL_dumpindent; | |
336 | PL_dumpindent = 2; | |
337 | do_sv_dump(0, Perl_debug_log, sv, 0, lim, | |
338 | (bool)(dumpop && SvTRUE(dumpop)), pv_lim); | |
339 | PL_dumpindent = save_dumpindent; | |
340 | } | |
341 | ||
342 | static OP * | |
343 | S_pp_dump(pTHX) | |
344 | { | |
345 | dSP; | |
346 | const I32 lim = PL_op->op_private == 2 ? (I32)POPi : 4; | |
347 | dPOPss; | |
348 | S_do_dump(aTHX_ sv, lim); | |
349 | RETPUSHUNDEF; | |
350 | } | |
351 | ||
352 | static OP * | |
353 | S_ck_dump(pTHX_ OP *entersubop, GV *namegv, SV *cv) | |
354 | { | |
3253bf85 | 355 | OP *parent, *pm, *first, *second; |
34b94bc4 | 356 | BINOP *newop; |
98f21952 DM |
357 | |
358 | PERL_UNUSED_ARG(cv); | |
34b94bc4 FC |
359 | |
360 | ck_entersub_args_proto(entersubop, namegv, | |
361 | newSVpvn_flags("$;$", 3, SVs_TEMP)); | |
362 | ||
3253bf85 DM |
363 | parent = entersubop; |
364 | pm = cUNOPx(entersubop)->op_first; | |
365 | if (!OP_HAS_SIBLING(pm)) { | |
366 | parent = pm; | |
367 | pm = cUNOPx(pm)->op_first; | |
368 | } | |
369 | first = OP_SIBLING(pm); | |
370 | second = OP_SIBLING(first); | |
371 | if (!second) { | |
372 | /* It doesn’t really matter what we return here, as this only | |
373 | occurs after yyerror. */ | |
374 | return entersubop; | |
375 | } | |
376 | /* we either have Dump($x): [pushmark]->[first]->[ex-cvop] | |
377 | * or Dump($x,1); [pushmark]->[first]->[second]->[ex-cvop] | |
378 | */ | |
379 | if (!OP_HAS_SIBLING(second)) | |
380 | second = NULL; | |
1ed44841 | 381 | |
34b94bc4 FC |
382 | if (first->op_type == OP_RV2AV || |
383 | first->op_type == OP_PADAV || | |
384 | first->op_type == OP_RV2HV || | |
385 | first->op_type == OP_PADHV | |
386 | ) | |
387 | first->op_flags |= OPf_REF; | |
388 | else | |
389 | first->op_flags &= ~OPf_MOD; | |
313efa90 | 390 | |
3253bf85 DM |
391 | /* splice out first (and optionally second) ops, then discard the rest |
392 | * of the op tree */ | |
34b94bc4 | 393 | |
3253bf85 | 394 | op_sibling_splice(parent, pm, second ? 2 : 1, NULL); |
34b94bc4 FC |
395 | op_free(entersubop); |
396 | ||
3253bf85 DM |
397 | /* then attach first (and second) to a new binop */ |
398 | ||
34b94bc4 FC |
399 | NewOp(1234, newop, 1, BINOP); |
400 | newop->op_type = OP_CUSTOM; | |
401 | newop->op_ppaddr = S_pp_dump; | |
34b94bc4 FC |
402 | newop->op_private= second ? 2 : 1; |
403 | newop->op_flags = OPf_KIDS|OPf_WANT_SCALAR; | |
29e61fd9 | 404 | op_sibling_splice((OP*)newop, NULL, 0, first); |
34b94bc4 FC |
405 | |
406 | return (OP *)newop; | |
407 | } | |
408 | ||
409 | static XOP my_xop; | |
410 | ||
3967c732 JD |
411 | MODULE = Devel::Peek PACKAGE = Devel::Peek |
412 | ||
413 | void | |
414 | mstat(str="Devel::Peek::mstat: ") | |
d3f5e399 | 415 | const char *str |
3967c732 JD |
416 | |
417 | void | |
d1424c31 IZ |
418 | fill_mstats(SV *sv, int level = 0) |
419 | ||
420 | void | |
421 | mstats_fillhash(SV *sv, int level = 0) | |
422 | PROTOTYPE: \%;$ | |
423 | ||
424 | void | |
425 | mstats2hash(SV *sv, SV *rv, int level = 0) | |
426 | PROTOTYPE: $\%;$ | |
427 | ||
428 | void | |
3967c732 JD |
429 | Dump(sv,lim=4) |
430 | SV * sv | |
431 | I32 lim | |
432 | PPCODE: | |
433 | { | |
34b94bc4 FC |
434 | S_do_dump(aTHX_ sv, lim); |
435 | } | |
436 | ||
437 | BOOT: | |
438 | { | |
439 | CV * const cv = get_cvn_flags("Devel::Peek::Dump", 17, 0); | |
316ebaf2 | 440 | assert(cv); |
34b94bc4 FC |
441 | cv_set_call_checker(cv, S_ck_dump, (SV *)cv); |
442 | ||
0e61cc55 | 443 | XopENTRY_set(&my_xop, xop_name, "Devel_Peek_Dump"); |
34b94bc4 FC |
444 | XopENTRY_set(&my_xop, xop_desc, "Dump"); |
445 | XopENTRY_set(&my_xop, xop_class, OA_BINOP); | |
446 | Perl_custom_op_register(aTHX_ S_pp_dump, &my_xop); | |
3967c732 JD |
447 | } |
448 | ||
449 | void | |
450 | DumpArray(lim,...) | |
451 | I32 lim | |
452 | PPCODE: | |
453 | { | |
454 | long i; | |
64ace3f8 | 455 | SV *pv_lim_sv = perl_get_sv("Devel::Peek::pv_limit", 0); |
7698c435 | 456 | const STRLEN pv_lim = pv_lim_sv ? SvIV(pv_lim_sv) : 0; |
64ace3f8 | 457 | SV *dumpop = perl_get_sv("Devel::Peek::dump_ops", 0); |
16d8f38a | 458 | const U16 save_dumpindent = PL_dumpindent; |
3967c732 JD |
459 | PL_dumpindent = 2; |
460 | ||
461 | for (i=1; i<items; i++) { | |
7b0972df | 462 | PerlIO_printf(Perl_debug_log, "Elt No. %ld 0x%"UVxf"\n", i - 1, PTR2UV(ST(i))); |
eb160463 GS |
463 | do_sv_dump(0, Perl_debug_log, ST(i), 0, lim, |
464 | (bool)(dumpop && SvTRUE(dumpop)), pv_lim); | |
3967c732 | 465 | } |
16d8f38a | 466 | PL_dumpindent = save_dumpindent; |
3967c732 JD |
467 | } |
468 | ||
469 | void | |
470 | DumpProg() | |
471 | PPCODE: | |
472 | { | |
d2560b70 | 473 | warn("dumpindent is %d", (int)PL_dumpindent); |
3967c732 JD |
474 | if (PL_main_root) |
475 | op_dump(PL_main_root); | |
476 | } | |
477 | ||
da1929e7 | 478 | U32 |
3967c732 JD |
479 | SvREFCNT(sv) |
480 | SV * sv | |
da1929e7 TC |
481 | PROTOTYPE: \[$@%&*] |
482 | CODE: | |
e4c0574e TC |
483 | SvGETMAGIC(sv); |
484 | if (!SvROK(sv)) | |
485 | croak_xs_usage(cv, "SCALAR"); | |
da1929e7 TC |
486 | RETVAL = SvREFCNT(SvRV(sv)) - 1; /* -1 because our ref doesn't count */ |
487 | OUTPUT: | |
488 | RETVAL | |
3967c732 JD |
489 | |
490 | SV * | |
491 | DeadCode() | |
cea2e8a9 GS |
492 | CODE: |
493 | RETVAL = DeadCode(aTHX); | |
494 | OUTPUT: | |
495 | RETVAL | |
83ee9e09 GS |
496 | |
497 | MODULE = Devel::Peek PACKAGE = Devel::Peek PREFIX = _ | |
498 | ||
499 | SV * | |
500 | _CvGV(cv) | |
501 | SV *cv | |
bd16a5f0 IZ |
502 | |
503 | bool | |
504 | _runops_debug(int flag = -1) |