op_dump(): display names of variables for pad ops.

Make op_dump(), as used by 'perl -Dx', display the names of pad
variables when dumping pad ops.

The runtime perl -Dt already does this (note the $x, $y etc appearing in
the op name displays):

    $ perl -Dt -e'my ($x, $y); $y = 1+$x'

    (-e:0)	enter
    (-e:0)	nextstate
    (-e:1)	padrange($x,$y)
    (-e:1)	nextstate
    (-e:1)	const(IV(1))
    (-e:1)	padsv($x)
    (-e:1)	add($y)
    (-e:1)	leave

While the (typically compile-time) -Dx detailed optree dumping didn't.
Here are some 'before this commit' and 'after' examples of how some of
those ops were/are now displayed. Note the changes in the 'TARG = N'
lines for the following code:

    $  perl -Dx -e'my ($x, $y); $y = 1+$x'

Before:

    4    |   +--padrange OP(0x31b08960) ===> 6 [nextstate 0x31b09fc0]
         |   |   TARG = 1
         |   |   FLAGS = (VOID,MOD,SLABBED,MORESIB)
         |   |   PRIVATE = (LVINTRO,range=0x2)

    10   +--add BINOP(0x31b0a060) ===> 1 [leave 0x31b08880]
             TARG = 2
             FLAGS = (VOID,KIDS,SLABBED)
             PRIVATE = (TARGMY,0x2)

    11       +--padsv OP(0x31b0a0a0) ===> 10 [add 0x31b0a060]
                 TARG = 1
                 FLAGS = (SCALAR,SLABBED)

After:

    4    |   +--padrange OP(0x18ffe920) ===> 6 [nextstate 0x18ffff80]
         |   |   TARG = 1 ($x,$y)
         |   |   FLAGS = (VOID,MOD,SLABBED,MORESIB)
         |   |   PRIVATE = (LVINTRO,range=0x2)

    10   +--add BINOP(0x19000020) ===> 1 [leave 0x18ffe840]
             TARG = 2 ($y)
             FLAGS = (VOID,KIDS,SLABBED)
             PRIVATE = (TARGMY,0x2)

    11       +--padsv OP(0x19000060) ===> 10 [add 0x19000020]
                 TARG = 1 ($x)
                 FLAGS = (SCALAR,SLABBED)
This commit is contained in:
David Mitchell 2025-11-12 13:57:12 +00:00
parent a95603a297
commit 067d8a664e

38
dump.c
View File

@ -1285,7 +1285,9 @@ S_sequence_num(pTHX_ const OP *o)
} }
/* forward declaration */
STATIC void
S_deb_padvar_cv(pTHX_ CV *cv, PADOFFSET off, int n, bool paren);
const struct flag_to_name op_flags_names[] = { const struct flag_to_name op_flags_names[] = {
@ -1379,10 +1381,40 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o,
} }
} }
if (o->op_targ && optype != OP_NULL) if (o->op_targ && optype != OP_NULL) {
S_opdump_indent(aTHX_ o, level, bar, file, "TARG = %ld\n", S_opdump_indent(aTHX_ o, level, bar, file, "TARG = %ld",
(long)o->op_targ); (long)o->op_targ);
/* Display the names of the lexical variables (if any)
* associated with op_targ */
int n = 1;
switch (o->op_type) {
case OP_PADRANGE:
n = o->op_private & OPpPADRANGE_COUNTMASK;
/* FALLTHROUGH */
case OP_PADSV:
case OP_PADAV:
case OP_PADHV:
case OP_ARGELEM:
case OP_PADSV_STORE:
case OP_AELEMFAST_LEX:
do_lex:
PerlIO_puts(file, " ");
S_deb_padvar_cv(aTHX_ S_get_cv_from_op(aTHX_ o, rootcv),
o->op_targ,
n, 1);
break;
default:
if ( (PL_opargs[o->op_type] & OA_TARGLEX)
&& (o->op_private & OPpTARGET_MY))
goto do_lex;
}
PerlIO_puts(file, "\n");
}
if (o->op_flags || o->op_slabbed || o->op_savefree || o->op_static) { if (o->op_flags || o->op_slabbed || o->op_savefree || o->op_static) {
SV * const tmpsv = newSVpvs(""); SV * const tmpsv = newSVpvs("");
switch (o->op_flags & OPf_WANT) { switch (o->op_flags & OPf_WANT) {