summaryrefslogtreecommitdiff
path: root/dump.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-01-24 14:43:05 +0000
committerDavid Mitchell <davem@iabyn.com>2017-01-24 14:56:43 +0000
commitabd07ec01964fc49e914e765cdba6f27072decda (patch)
treeb7ebeccd8a3bb474e1d4a216cf91e17fb25bf342 /dump.c
parent8f5d5a51d02eb509ca7ebc82d950207828c3aa7c (diff)
downloadperl-abd07ec01964fc49e914e765cdba6f27072decda.tar.gz
handle op_pv better in op_clear() and op_dump()
In op_clear(), the ops with labels stored in the op_pv field (OP_NEXT etc) fall-through to the OP_TRANS/OP_TRANSR code, which determines whether to free op_pv based on the OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF flags, which are only valid for OP_TRANS/OP_TRANSR. At the moment the fall-through fields don't use either of those private bits, but in case this changes in future, only check those flag bits for trans ops. At the same time, enhance op_dump() to display the OP_PV field of such ops. Also, fix a leak I introduced in the recently-added S_gv_display() function.
Diffstat (limited to 'dump.c')
-rw-r--r--dump.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/dump.c b/dump.c
index ce63f351e8..349a3e42cd 100644
--- a/dump.c
+++ b/dump.c
@@ -737,7 +737,7 @@ Perl_dump_eval(pTHX)
static SV *
S_gv_display(pTHX_ GV *gv)
{
- SV * const name = newSV(0);
+ SV * const name = newSVpvs_flags("", SVs_TEMP);
if (gv) {
SV * const raw = newSVpvs_flags("", SVs_TEMP);
STRLEN len;
@@ -1217,6 +1217,30 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o)
S_opdump_indent(aTHX_ o, level, bar, file,
"REFCNT = %" UVuf "\n", (UV)o->op_targ);
break;
+
+ case OP_DUMP:
+ case OP_GOTO:
+ case OP_NEXT:
+ case OP_LAST:
+ case OP_REDO:
+ if (o->op_flags & (OPf_SPECIAL|OPf_STACKED|OPf_KIDS))
+ break;
+ /* FALLTHROUGH */
+ case OP_TRANS:
+ case OP_TRANSR:
+ if ( (o->op_type == OP_TRANS || o->op_type == OP_TRANSR)
+ && (o->op_private & (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF)))
+ break;
+
+ {
+ SV * const label = newSVpvs_flags("", SVs_TEMP);
+ generic_pv_escape(label, cPVOPo->op_pv, strlen(cPVOPo->op_pv), 0);
+ S_opdump_indent(aTHX_ o, level, bar, file,
+ "PV = \"%" SVf "\" (0x%" UVxf ")\n",
+ SVfARG(label), PTR2UV(cPVOPo->op_pv));
+ }
+
+
default:
break;
}