/* dump.c
*
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- * 2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
+ * 2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
#define PERL_IN_DUMP_C
#include "perl.h"
#include "regcomp.h"
+#include "proto.h"
+
#define Sequence PL_op_sequence
void
Perl_dump_vindent(pTHX_ I32 level, PerlIO *file, const char* pat, va_list *args)
{
+ dVAR;
PerlIO_printf(file, "%*s", (int)(level*PL_dumpindent), "");
PerlIO_vprintf(file, pat, *args);
}
void
Perl_dump_all(pTHX)
{
+ dVAR;
PerlIO_setlinebuf(Perl_debug_log);
if (PL_main_root)
op_dump(PL_main_root);
void
Perl_dump_packsubs(pTHX_ const HV *stash)
{
+ dVAR;
I32 i;
if (!HvARRAY(stash))
void
Perl_dump_eval(pTHX)
{
+ dVAR;
op_dump(PL_eval_root);
}
break;
}
switch (*pv) {
- case '\t': sv_catpvn(dsv, "\\t", 2); break;
- case '\n': sv_catpvn(dsv, "\\n", 2); break;
- case '\r': sv_catpvn(dsv, "\\r", 2); break;
- case '\f': sv_catpvn(dsv, "\\f", 2); break;
- case '"': sv_catpvn(dsv, "\\\"", 2); break;
- case '\\': sv_catpvn(dsv, "\\\\", 2); break;
+ case '\t': sv_catpvs(dsv, "\\t"); break;
+ case '\n': sv_catpvs(dsv, "\\n"); break;
+ case '\r': sv_catpvs(dsv, "\\r"); break;
+ case '\f': sv_catpvs(dsv, "\\f"); break;
+ case '"': sv_catpvs(dsv, "\\\""); break;
+ case '\\': sv_catpvs(dsv, "\\\\"); break;
default:
if (isPRINT(*pv))
sv_catpvn(dsv, pv, 1);
Perl_sv_catpvf(aTHX_ dsv, "\\%o", (U8)*pv);
}
}
- sv_catpvn(dsv, "\"", 1);
+ sv_catpvs(dsv, "\"");
if (truncated)
- sv_catpvn(dsv, "...", 3);
+ sv_catpvs(dsv, "...");
if (nul_terminated)
- sv_catpvn(dsv, "\\0", 2);
+ sv_catpvs(dsv, "\\0");
return SvPVX(dsv);
}
Perl_sv_peek(pTHX_ SV *sv)
{
dVAR;
- SV *t = sv_newmortal();
+ SV * const t = sv_newmortal();
int unref = 0;
sv_setpvn(t, "", 0);
if (!SvPVX_const(sv))
sv_catpv(t, "(null)");
else {
- SV *tmp = newSVpvn("", 0);
+ SV *tmp = newSVpvs("");
sv_catpv(t, "(");
if (SvOOK(sv))
Perl_sv_catpvf(aTHX_ t, "[%s]", pv_display(tmp, SvPVX_const(sv)-SvIVX(sv), SvIVX(sv), 0, 127));
op_dump(pm->op_pmreplroot);
}
if (pm->op_pmflags || (PM_GETRE(pm) && PM_GETRE(pm)->check_substr)) {
- SV *tmpsv = newSVpvn("", 0);
+ SV *tmpsv = newSVpvs("");
if (pm->op_pmdynflags & PMdf_USED)
sv_catpv(tmpsv, ",USED");
if (pm->op_pmdynflags & PMdf_TAINTED)
/* An op sequencer. We visit the ops in the order they're to execute. */
STATIC void
-sequence(pTHX_ register const OP *o)
+S_sequence(pTHX_ register const OP *o)
{
dVAR;
SV *op;
- char *key;
+ const char *key;
STRLEN len;
- const OP *oldop = 0;
+ const OP *oldop = NULL;
OP *l;
if (!o)
return;
- op = newSVuv(PTR2UV(o));
- key = SvPV(op, len);
- if (hv_exists(Sequence, key, len))
- return;
+ if (!Sequence)
+ Sequence = newHV();
for (; o; o = o->op_next) {
op = newSVuv(PTR2UV(o));
- key = SvPV(op, len);
+ key = SvPV_const(op, len);
if (hv_exists(Sequence, key, len))
break;
hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0);
for (l = cLOGOPo->op_other; l && l->op_type == OP_NULL; l = l->op_next)
;
- sequence(aTHX_ l);
+ sequence(l);
break;
case OP_ENTERLOOP:
hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0);
for (l = cLOOPo->op_redoop; l && l->op_type == OP_NULL; l = l->op_next)
;
- sequence(aTHX_ l);
+ sequence(l);
for (l = cLOOPo->op_nextop; l && l->op_type == OP_NULL; l = l->op_next)
;
- sequence(aTHX_ l);
+ sequence(l);
for (l = cLOOPo->op_lastop; l && l->op_type == OP_NULL; l = l->op_next)
;
- sequence(aTHX_ l);
+ sequence(l);
break;
case OP_QR:
hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0);
for (l = cPMOPo->op_pmreplstart; l && l->op_type == OP_NULL; l = l->op_next)
;
- sequence(aTHX_ l);
+ sequence(l);
break;
case OP_HELEM:
}
STATIC UV
-sequence_num(pTHX_ const OP *o)
+S_sequence_num(pTHX_ const OP *o)
{
dVAR;
SV *op,
**seq;
- char *key;
+ const char *key;
STRLEN len;
if (!o) return 0;
op = newSVuv(PTR2UV(o));
- key = SvPV(op, len);
+ key = SvPV_const(op, len);
seq = hv_fetch(Sequence, key, len, 0);
return seq ? SvUV(*seq): 0;
}
{
dVAR;
UV seq;
- sequence(aTHX_ o);
+ sequence(o);
Perl_dump_indent(aTHX_ level, file, "{\n");
level++;
- seq = sequence_num(aTHX_ o);
+ seq = sequence_num(o);
if (seq)
PerlIO_printf(file, "%-4"UVf, seq);
else
(int)(PL_dumpindent*level-4), "", OP_NAME(o));
if (o->op_next)
PerlIO_printf(file, seq ? "%"UVf"\n" : "(%"UVf")\n",
- sequence_num(aTHX_ o->op_next));
+ sequence_num(o->op_next));
else
PerlIO_printf(file, "DONE\n");
if (o->op_targ) {
Perl_dump_indent(aTHX_ level, file, "ADDR = 0x%"UVxf" => 0x%"UVxf"\n", (UV)o, (UV)o->op_next);
#endif
if (o->op_flags) {
- SV *tmpsv = newSVpvn("", 0);
+ SV *tmpsv = newSVpvs("");
switch (o->op_flags & OPf_WANT) {
case OPf_WANT_VOID:
sv_catpv(tmpsv, ",VOID");
SvREFCNT_dec(tmpsv);
}
if (o->op_private) {
- SV *tmpsv = newSVpvn("", 0);
+ SV *tmpsv = newSVpvs("");
if (PL_opargs[o->op_type] & OA_TARGLEX) {
if (o->op_private & OPpTARGET_MY)
sv_catpv(tmpsv, ",TARGET_MY");
case OP_ENTERLOOP:
Perl_dump_indent(aTHX_ level, file, "REDO ===> ");
if (cLOOPo->op_redoop)
- PerlIO_printf(file, "%"UVf"\n", sequence_num(aTHX_ cLOOPo->op_redoop));
+ PerlIO_printf(file, "%"UVf"\n", sequence_num(cLOOPo->op_redoop));
else
PerlIO_printf(file, "DONE\n");
Perl_dump_indent(aTHX_ level, file, "NEXT ===> ");
if (cLOOPo->op_nextop)
- PerlIO_printf(file, "%"UVf"\n", sequence_num(aTHX_ cLOOPo->op_nextop));
+ PerlIO_printf(file, "%"UVf"\n", sequence_num(cLOOPo->op_nextop));
else
PerlIO_printf(file, "DONE\n");
Perl_dump_indent(aTHX_ level, file, "LAST ===> ");
if (cLOOPo->op_lastop)
- PerlIO_printf(file, "%"UVf"\n", sequence_num(aTHX_ cLOOPo->op_lastop));
+ PerlIO_printf(file, "%"UVf"\n", sequence_num(cLOOPo->op_lastop));
else
PerlIO_printf(file, "DONE\n");
break;
case OP_AND:
Perl_dump_indent(aTHX_ level, file, "OTHER ===> ");
if (cLOGOPo->op_other)
- PerlIO_printf(file, "%"UVf"\n", sequence_num(aTHX_ cLOGOPo->op_other));
+ PerlIO_printf(file, "%"UVf"\n", sequence_num(cLOGOPo->op_other));
else
PerlIO_printf(file, "DONE\n");
break;
" MAGIC = 0x%"UVxf"\n", PTR2UV(mg));
if (mg->mg_virtual) {
const MGVTBL * const v = mg->mg_virtual;
- const char *s = 0;
+ const char *s = NULL;
if (v == &PL_vtbl_sv) s = "sv";
else if (v == &PL_vtbl_env) s = "env";
else if (v == &PL_vtbl_envelem) s = "envelem";
else if (v == &PL_vtbl_amagicelem) s = "amagicelem";
else if (v == &PL_vtbl_backref) s = "backref";
else if (v == &PL_vtbl_utf8) s = "utf8";
+ else if (v == &PL_vtbl_arylen_p) s = "arylen_p";
if (s)
Perl_dump_indent(aTHX_ level, file, " MG_VIRTUAL = &PL_vtbl_%s\n", s);
else
{
int n;
- const char *name = 0;
+ const char *name = NULL;
for (n = 0; magic_names[n].name; n++) {
if (mg->mg_type == magic_names[n].type) {
name = magic_names[n].name;
Perl_dump_indent(aTHX_ level, file, " MG_PTR = 0x%"UVxf, PTR2UV(mg->mg_ptr));
if (mg->mg_len >= 0) {
if (mg->mg_type != PERL_MAGIC_utf8) {
- SV *sv = newSVpvn("", 0);
+ SV *sv = newSVpvs("");
PerlIO_printf(file, " %s", pv_display(sv, mg->mg_ptr, mg->mg_len, 0, pvlim));
SvREFCNT_dec(sv);
}
void
Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bool dumpops, STRLEN pvlim)
{
+ dVAR;
SV *d;
const char *s;
U32 flags;
/* FALL THROUGH */
default:
if (SvEVALED(sv)) sv_catpv(d, "EVALED,");
- if (SvIsUV(sv)) sv_catpv(d, "IsUV,");
+ if (SvIsUV(sv) && !(flags & SVf_ROK)) sv_catpv(d, "IsUV,");
break;
case SVt_PVBM:
if (SvTAIL(sv)) sv_catpv(d, "TAIL,");
PerlIO_printf(file, " (");
Zero(freq, FREQ_MAX + 1, int);
for (i = 0; (STRLEN)i <= HvMAX(sv); i++) {
- HE* h; int count = 0;
+ HE* h;
+ int count = 0;
for (h = HvARRAY(sv)[i]; h; h = HeNEXT(h))
count++;
if (count > FREQ_MAX)
if (hvname)
Perl_dump_indent(aTHX_ level, file, " NAME = \"%s\"\n", hvname);
}
+ if (SvOOK(sv)) {
+ AV *backrefs = *Perl_hv_backreferences_p(aTHX_ (HV*)sv);
+ if (backrefs) {
+ Perl_dump_indent(aTHX_ level, file, " BACKREFS = 0x%"UVxf"\n",
+ PTR2UV(backrefs));
+ do_sv_dump(level+1, file, (SV*)backrefs, nest+1, maxnest,
+ dumpops, pvlim);
+ }
+ }
if (nest < maxnest && !HvEITER_get(sv)) { /* Try to preserve iterator */
HE *he;
- HV *hv = (HV*)sv;
+ HV * const hv = (HV*)sv;
int count = maxnest - nest;
hv_iterinit(hv);
SV *elt, *keysv;
const char *keypv;
STRLEN len;
- U32 hash = HeHASH(he);
+ const U32 hash = HeHASH(he);
keysv = hv_iterkeysv(he);
- keypv = SvPV(keysv, len);
+ keypv = SvPV_const(keysv, len);
elt = hv_iterval(hv, he);
Perl_dump_indent(aTHX_ level+1, file, "Elt %s ", pv_display(d, keypv, len, 0, pvlim));
if (SvUTF8(keysv))
break;
case SVt_PVCV:
if (SvPOK(sv))
- Perl_dump_indent(aTHX_ level, file, " PROTOTYPE = \"%s\"\n", SvPV_nolen(sv));
+ Perl_dump_indent(aTHX_ level, file, " PROTOTYPE = \"%s\"\n", SvPV_nolen_const(sv));
/* FALL THROUGH */
case SVt_PVFM:
do_hv_dump(level, file, " COMP_STASH", CvSTASH(sv));
if (CvSTART(sv))
- Perl_dump_indent(aTHX_ level, file, " START = 0x%"UVxf" ===> %"IVdf"\n", PTR2UV(CvSTART(sv)), (IV)sequence_num(aTHX_ CvSTART(sv)));
+ Perl_dump_indent(aTHX_ level, file, " START = 0x%"UVxf" ===> %"IVdf"\n", PTR2UV(CvSTART(sv)), (IV)sequence_num(CvSTART(sv)));
Perl_dump_indent(aTHX_ level, file, " ROOT = 0x%"UVxf"\n", PTR2UV(CvROOT(sv)));
if (CvROOT(sv) && dumpops)
do_op_dump(level+1, file, CvROOT(sv));
Perl_dump_indent(aTHX_ level, file, " XSUB = 0x%"UVxf"\n", PTR2UV(CvXSUB(sv)));
- Perl_dump_indent(aTHX_ level, file, " XSUBANY = %"IVdf"\n", (IV)CvXSUBANY(sv).any_i32);
+ {
+ SV *constant = cv_const_sv((CV *)sv);
+
+
+ if (constant) {
+ Perl_dump_indent(aTHX_ level, file, " XSUBANY = 0x%"UVxf
+ " (CONST SV)\n",
+ PTR2UV(CvXSUBANY(sv).any_ptr));
+ do_sv_dump(level+1, file, constant, nest+1, maxnest, dumpops,
+ pvlim);
+ } else {
+ Perl_dump_indent(aTHX_ level, file, " XSUBANY = %"IVdf"\n",
+ (IV)CvXSUBANY(sv).any_i32);
+ }
+ }
do_gvgv_dump(level, file, " GVGV::GV", CvGV(sv));
Perl_dump_indent(aTHX_ level, file, " FILE = \"%s\"\n", CvFILE(sv));
Perl_dump_indent(aTHX_ level, file, " DEPTH = %"IVdf"\n", (IV)CvDEPTH(sv));
Perl_dump_indent(aTHX_ level, file, " HV = 0x%"UVxf"\n", PTR2UV(GvHV(sv)));
Perl_dump_indent(aTHX_ level, file, " CV = 0x%"UVxf"\n", PTR2UV(GvCV(sv)));
Perl_dump_indent(aTHX_ level, file, " CVGEN = 0x%"UVxf"\n", (UV)GvCVGEN(sv));
- Perl_dump_indent(aTHX_ level, file, " GPFLAGS = 0x%"UVxf"\n", (UV)GvGPFLAGS(sv));
Perl_dump_indent(aTHX_ level, file, " LINE = %"IVdf"\n", (IV)GvLINE(sv));
Perl_dump_indent(aTHX_ level, file, " FILE = \"%s\"\n", GvFILE(sv));
Perl_dump_indent(aTHX_ level, file, " FLAGS = 0x%"UVxf"\n", (UV)GvFLAGS(sv));
void
Perl_sv_dump(pTHX_ SV *sv)
{
+ dVAR;
do_sv_dump(0, Perl_debug_log, sv, 0, 0, 0, 0);
}
int
Perl_runops_debug(pTHX)
{
+ dVAR;
if (!PL_op) {
if (ckWARN_d(WARN_DEBUGGING))
Perl_warner(aTHX_ packWARN(WARN_DEBUGGING), "NULL OP IN RUN");
I32
Perl_debop(pTHX_ const OP *o)
{
+ dVAR;
if (CopSTASH_eq(PL_curcop, PL_debstash) && !DEBUG_J_TEST_)
return 0;
if (cGVOPo_gv) {
SV *sv = NEWSV(0,0);
gv_fullname3(sv, cGVOPo_gv, Nullch);
- PerlIO_printf(Perl_debug_log, "(%s)", SvPV_nolen(sv));
+ PerlIO_printf(Perl_debug_log, "(%s)", SvPV_nolen_const(sv));
SvREFCNT_dec(sv);
}
else
} else
sv = Nullsv;
if (sv)
- PerlIO_printf(Perl_debug_log, "(%s)", SvPV_nolen(sv));
+ PerlIO_printf(Perl_debug_log, "(%s)", SvPV_nolen_const(sv));
else
PerlIO_printf(Perl_debug_log, "[%"UVuf"]", (UV)o->op_targ);
}
STATIC CV*
S_deb_curcv(pTHX_ I32 ix)
{
+ dVAR;
const PERL_CONTEXT *cx = &cxstack[ix];
if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT)
return cx->blk_sub.cv;
void
Perl_watch(pTHX_ char **addr)
{
+ dVAR;
PL_watchaddr = addr;
PL_watchok = *addr;
PerlIO_printf(Perl_debug_log, "WATCHING, %"UVxf" is currently %"UVxf"\n",
STATIC void
S_debprof(pTHX_ const OP *o)
{
+ dVAR;
if (CopSTASH_eq(PL_curcop, PL_debstash) && !DEBUG_J_TEST_)
return;
if (!PL_profiledata)
- Newz(000, PL_profiledata, MAXO, U32);
+ Newxz(PL_profiledata, MAXO, U32);
++PL_profiledata[o->op_type];
}
void
Perl_debprofdump(pTHX)
{
+ dVAR;
unsigned i;
if (!PL_profiledata)
return;