X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/145bf8eec5be8c17bd592ec8d28efb239bdafa93..d19fe907288ac4a936ca7052f12f200dcc8ebab7:/dump.c diff --git a/dump.c b/dump.c index 16ac581..f888a48 100644 --- a/dump.c +++ b/dump.c @@ -96,7 +96,10 @@ S_append_flags(pTHX_ SV *sv, U32 flags, const struct flag_to_name *start, Escapes at most the first "count" chars of pv and puts the results into dsv such that the size of the escaped string will not exceed "max" chars -and will not contain any incomplete escape sequences. +and will not contain any incomplete escape sequences. The number of bytes +escaped will be returned in the STRLEN *escaped parameter if it is not null. +When the dsv parameter is null no escaping actually occurs, but the number +of bytes that would be escaped were it not null will be calculated. If flags contains PERL_PV_ESCAPE_QUOTE then any double quotes in the string will also be escaped. @@ -104,9 +107,9 @@ will also be escaped. Normally the SV will be cleared before the escaped string is prepared, but when PERL_PV_ESCAPE_NOCLEAR is set this will not occur. -If PERL_PV_ESCAPE_UNI is set then the input string is treated as Unicode, +If PERL_PV_ESCAPE_UNI is set then the input string is treated as UTF-8 if PERL_PV_ESCAPE_UNI_DETECT is set then the input string is scanned -using C to determine if it is Unicode. +using C to determine if it is UTF-8. If PERL_PV_ESCAPE_ALL is set then all input chars will be output using C<\x01F1> style escapes, otherwise if PERL_PV_ESCAPE_NONASCII is set, only @@ -144,14 +147,14 @@ Perl_pv_escape( pTHX_ SV *dsv, char const * const str, STRLEN wrote = 0; /* chars written so far */ STRLEN chsize = 0; /* size of data to be written */ STRLEN readsize = 1; /* size of data just read */ - bool isuni= flags & PERL_PV_ESCAPE_UNI ? 1 : 0; /* is this Unicode */ + bool isuni= flags & PERL_PV_ESCAPE_UNI ? 1 : 0; /* is this UTF-8 */ const char *pv = str; const char * const end = pv + count; /* end of string */ octbuf[0] = esc; PERL_ARGS_ASSERT_PV_ESCAPE; - if (!(flags & PERL_PV_ESCAPE_NOCLEAR)) { + if (dsv && !(flags & PERL_PV_ESCAPE_NOCLEAR)) { /* This won't alter the UTF-8 flag */ sv_setpvs(dsv, ""); } @@ -221,7 +224,8 @@ Perl_pv_escape( pTHX_ SV *dsv, char const * const str, if ( max && (wrote + chsize > max) ) { break; } else if (chsize > 1) { - sv_catpvn(dsv, octbuf, chsize); + if (dsv) + sv_catpvn(dsv, octbuf, chsize); wrote += chsize; } else { /* If PERL_PV_ESCAPE_NOBACKSLASH is set then non-ASCII bytes @@ -230,7 +234,8 @@ Perl_pv_escape( pTHX_ SV *dsv, char const * const str, Or add a new API call sv_catpvc(). Think about that name, and how to keep it clear that it's unlike the s of catpvs, which is really an array of octets, not a string. */ - Perl_sv_catpvf( aTHX_ dsv, "%c", c); + if (dsv) + Perl_sv_catpvf( aTHX_ dsv, "%c", c); wrote++; } if ( flags & PERL_PV_ESCAPE_FIRSTCHAR ) @@ -238,7 +243,7 @@ Perl_pv_escape( pTHX_ SV *dsv, char const * const str, } if (escaped != NULL) *escaped= pv - str; - return SvPVX(dsv); + return dsv ? SvPVX(dsv) : NULL; } /* =for apidoc pv_pretty @@ -270,36 +275,51 @@ Perl_pv_pretty( pTHX_ SV *dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags ) { - const U8 dq = (flags & PERL_PV_PRETTY_QUOTE) ? '"' : '%'; + const U8 *quotes = (U8*)((flags & PERL_PV_PRETTY_QUOTE) ? "\"\"" : + (flags & PERL_PV_PRETTY_LTGT) ? "<>" : NULL); STRLEN escaped; + STRLEN max_adjust= 0; + STRLEN orig_cur; PERL_ARGS_ASSERT_PV_PRETTY; if (!(flags & PERL_PV_PRETTY_NOCLEAR)) { - /* This won't alter the UTF-8 flag */ - sv_setpvs(dsv, ""); + /* This won't alter the UTF-8 flag */ + sv_setpvs(dsv, ""); } + orig_cur= SvCUR(dsv); - if ( dq == '"' ) - sv_catpvs(dsv, "\""); - else if ( flags & PERL_PV_PRETTY_LTGT ) - sv_catpvs(dsv, "<"); + if ( quotes ) + Perl_sv_catpvf(aTHX_ dsv, "%c", quotes[0]); if ( start_color != NULL ) sv_catpv(dsv, start_color); - - pv_escape( dsv, str, count, max, &escaped, flags | PERL_PV_ESCAPE_NOCLEAR ); - + + if ((flags & PERL_PV_PRETTY_EXACTSIZE)) { + if (quotes) + max_adjust += 2; + assert(max > max_adjust); + pv_escape( NULL, str, count, max - max_adjust, &escaped, flags ); + if ( (flags & PERL_PV_PRETTY_ELLIPSES) && ( escaped < count ) ) + max_adjust += 3; + assert(max > max_adjust); + } + + pv_escape( dsv, str, count, max - max_adjust, &escaped, flags | PERL_PV_ESCAPE_NOCLEAR ); + if ( end_color != NULL ) sv_catpv(dsv, end_color); - if ( dq == '"' ) - sv_catpvs( dsv, "\""); - else if ( flags & PERL_PV_PRETTY_LTGT ) - sv_catpvs(dsv, ">"); + if ( quotes ) + Perl_sv_catpvf(aTHX_ dsv, "%c", quotes[1]); if ( (flags & PERL_PV_PRETTY_ELLIPSES) && ( escaped < count ) ) sv_catpvs(dsv, "..."); + + if ((flags & PERL_PV_PRETTY_EXACTSIZE)) { + while( SvCUR(dsv) - orig_cur < max ) + sv_catpvs(dsv," "); + } return SvPVX(dsv); } @@ -642,8 +662,8 @@ Perl_do_pmop_dump(pTHX_ I32 level, PerlIO *file, const PMOP *pm) else ch = '/'; if (PM_GETRE(pm)) - Perl_dump_indent(aTHX_ level, file, "PMf_PRE %c%s%c%s\n", - ch, RX_PRECOMP(PM_GETRE(pm)), ch, + Perl_dump_indent(aTHX_ level, file, "PMf_PRE %c%.*s%c%s\n", + ch,(int)RX_PRELEN(PM_GETRE(pm)), RX_PRECOMP(PM_GETRE(pm)), ch, (pm->op_private & OPpRUNTIME) ? " (RUNTIME)" : ""); else Perl_dump_indent(aTHX_ level, file, "PMf_PRE (RUNTIME)\n"); @@ -792,30 +812,6 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) if (o->op_targ) { if (optype == OP_NULL) { Perl_dump_indent(aTHX_ level, file, " (was %s)\n", PL_op_name[o->op_targ]); - if (o->op_targ == OP_NEXTSTATE) { - if (CopLINE(cCOPo)) - Perl_dump_indent(aTHX_ level, file, "LINE = %"UVuf"\n", - (UV)CopLINE(cCOPo)); - if (CopSTASHPV(cCOPo)) { - SV* tmpsv = newSVpvs_flags("", SVs_TEMP); - HV *stash = CopSTASH(cCOPo); - const char * const hvname = HvNAME_get(stash); - - Perl_dump_indent(aTHX_ level, file, "PACKAGE = \"%s\"\n", - generic_pv_escape( tmpsv, hvname, HvNAMELEN(stash), HvNAMEUTF8(stash))); - } - if (CopLABEL(cCOPo)) { - SV* tmpsv = newSVpvs_flags("", SVs_TEMP); - STRLEN label_len; - U32 label_flags; - const char *label = CopLABEL_len_flags(cCOPo, - &label_len, - &label_flags); - Perl_dump_indent(aTHX_ level, file, "LABEL = \"%s\"\n", - generic_pv_escape( tmpsv, label, label_len,(label_flags & SVf_UTF8))); - } - - } } else Perl_dump_indent(aTHX_ level, file, "TARG = %ld\n", (long)o->op_targ); @@ -956,15 +952,34 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) } #endif break; + + case OP_MULTIDEREF: + { + UNOP_AUX_item *items = cUNOP_AUXo->op_aux; + UV i, count = items[-1].uv; + + Perl_dump_indent(aTHX_ level, file, "ARGS = \n"); + for (i=0; i < count; i++) + Perl_dump_indent(aTHX_ level+1, file, "%"UVuf" => 0x%"UVxf"\n", + i, items[i].uv); + } + case OP_CONST: case OP_HINTSEVAL: case OP_METHOD_NAMED: + case OP_METHOD_SUPER: + case OP_METHOD_REDIR: + case OP_METHOD_REDIR_SUPER: #ifndef USE_ITHREADS /* with ITHREADS, consts are stored in the pad, and the right pad * may not be active here, so skip */ - Perl_dump_indent(aTHX_ level, file, "SV = %s\n", SvPEEK(cSVOPo_sv)); + Perl_dump_indent(aTHX_ level, file, "SV = %s\n", SvPEEK(cMETHOPx_meth(o))); #endif break; + case OP_NULL: + if (o->op_targ != OP_NEXTSTATE && o->op_targ != OP_DBSTATE) + break; + /* FALLTHROUGH */ case OP_NEXTSTATE: case OP_DBSTATE: if (CopLINE(cCOPo)) @@ -989,6 +1004,8 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) generic_pv_escape( tmpsv, label, label_len, (label_flags & SVf_UTF8))); } + Perl_dump_indent(aTHX_ level, file, "SEQ = %u\n", + (unsigned int)cCOPo->cop_seq); break; case OP_ENTERLOOP: Perl_dump_indent(aTHX_ level, file, "REDO ===> "); @@ -1039,7 +1056,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) } if (o->op_flags & OPf_KIDS) { OP *kid; - for (kid = cUNOPo->op_first; kid; kid = OP_SIBLING(kid)) + for (kid = cUNOPo->op_first; kid; kid = OpSIBLING(kid)) do_op_dump(level, file, kid); } Perl_dump_indent(aTHX_ level-1, file, "}\n"); @@ -1363,6 +1380,7 @@ const struct flag_to_name regexp_extflags_names[] = { {RXf_PMf_SINGLELINE, "PMf_SINGLELINE,"}, {RXf_PMf_FOLD, "PMf_FOLD,"}, {RXf_PMf_EXTENDED, "PMf_EXTENDED,"}, + {RXf_PMf_EXTENDED_MORE, "PMf_EXTENDED_MORE,"}, {RXf_PMf_KEEPCOPY, "PMf_KEEPCOPY,"}, {RXf_IS_ANCHORED, "IS_ANCHORED,"}, {RXf_NO_INPLACE_SUBST, "NO_INPLACE_SUBST,"}, @@ -1427,15 +1445,10 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo (int)(PL_dumpindent*level), "", (IV)SvREFCNT(sv), (int)(PL_dumpindent*level), ""); - if (!((flags & SVpad_NAME) == SVpad_NAME - && (type == SVt_PVMG || type == SVt_PVNV))) { - if ((flags & SVs_PADSTALE)) + if ((flags & SVs_PADSTALE)) sv_catpv(d, "PADSTALE,"); - } - if (!((flags & SVpad_NAME) == SVpad_NAME && type == SVt_PVMG)) { - if ((flags & SVs_PADTMP)) + if ((flags & SVs_PADTMP)) sv_catpv(d, "PADTMP,"); - } append_flags(d, flags, first_sv_flags_names); if (flags & SVf_ROK) { sv_catpv(d, "ROK,"); @@ -1485,14 +1498,9 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo case SVt_PVMG: if (SvTAIL(sv)) sv_catpv(d, "TAIL,"); if (SvVALID(sv)) sv_catpv(d, "VALID,"); - if (SvPAD_TYPED(sv)) sv_catpv(d, "TYPED,"); - if (SvPAD_OUR(sv)) sv_catpv(d, "OUR,"); /* FALLTHROUGH */ - case SVt_PVNV: - if (SvPAD_STATE(sv)) sv_catpv(d, "STATE,"); goto evaled_or_uv; case SVt_PVAV: - if (AvPAD_NAMELIST(sv)) sv_catpvs(d, "NAMELIST,"); break; } /* SVphv_SHAREKEYS is also 0x20000000 */ @@ -1559,13 +1567,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo PerlIO_putc(file, '\n'); } - if ((type == SVt_PVNV || type == SVt_PVMG) - && (SvFLAGS(sv) & SVpad_NAME) == SVpad_NAME) { - Perl_dump_indent(aTHX_ level, file, " COP_LOW = %"UVuf"\n", - (UV) COP_SEQ_RANGE_LOW(sv)); - Perl_dump_indent(aTHX_ level, file, " COP_HIGH = %"UVuf"\n", - (UV) COP_SEQ_RANGE_HIGH(sv)); - } else if ((type >= SVt_PVNV && type != SVt_PVAV && type != SVt_PVHV + if ((type >= SVt_PVNV && type != SVt_PVAV && type != SVt_PVHV && type != SVt_PVCV && type != SVt_PVFM && type != SVt_REGEXP && type != SVt_PVIO && !isGV_with_GP(sv) && !SvVALID(sv)) || type == SVt_NV) { @@ -1635,17 +1637,8 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo } if (type >= SVt_PVMG) { - if (type == SVt_PVMG && SvPAD_OUR(sv)) { - HV * const ost = SvOURSTASH(sv); - if (ost) - do_hv_dump(level, file, " OURSTASH", ost); - } else if (SvTYPE(sv) == SVt_PVAV && AvPAD_NAMELIST(sv)) { - Perl_dump_indent(aTHX_ level, file, " MAXNAMED = %"UVuf"\n", - (UV)PadnamelistMAXNAMED(sv)); - } else { - if (SvMAGIC(sv)) + if (SvMAGIC(sv)) do_magic_dump(level, file, SvMAGIC(sv), nest+1, maxnest, dumpops, pvlim); - } if (SvSTASH(sv)) do_hv_dump(level, file, " STASH", SvSTASH(sv)); @@ -1667,10 +1660,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo PerlIO_putc(file, '\n'); Perl_dump_indent(aTHX_ level, file, " FILL = %"IVdf"\n", (IV)AvFILLp(sv)); Perl_dump_indent(aTHX_ level, file, " MAX = %"IVdf"\n", (IV)AvMAX(sv)); - /* arylen is stored in magic, and padnamelists use SvMAGIC for - something else. */ - if (!AvPAD_NAMELIST(sv)) - Perl_dump_indent(aTHX_ level, file, " ARYLEN = 0x%"UVxf"\n", + Perl_dump_indent(aTHX_ level, file, " ARYLEN = 0x%"UVxf"\n", SvMAGIC(sv) ? PTR2UV(AvARYLEN(sv)) : 0); sv_setpvs(d, ""); if (AvREAL(sv)) sv_catpv(d, ",REAL"); @@ -1980,10 +1970,14 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo Perl_dump_indent(aTHX_ level, file, " DEPTH = %"IVdf"\n", (IV)CvDEPTH(sv)); Perl_dump_indent(aTHX_ level, file, " FLAGS = 0x%"UVxf"\n", (UV)CvFLAGS(sv)); Perl_dump_indent(aTHX_ level, file, " OUTSIDE_SEQ = %"UVuf"\n", (UV)CvOUTSIDE_SEQ(sv)); - Perl_dump_indent(aTHX_ level, file, " PADLIST = 0x%"UVxf"\n", PTR2UV(CvPADLIST(sv))); - if (nest < maxnest) { - do_dump_pad(level+1, file, CvPADLIST(sv), 0); + if (!CvISXSUB(sv)) { + Perl_dump_indent(aTHX_ level, file, " PADLIST = 0x%"UVxf"\n", PTR2UV(CvPADLIST(sv))); + if (nest < maxnest) { + do_dump_pad(level+1, file, CvPADLIST(sv), 0); + } } + else + Perl_dump_indent(aTHX_ level, file, " HSCXT = 0x%p\n", CvHSCXT(sv)); { const CV * const outside = CvOUTSIDE(sv); Perl_dump_indent(aTHX_ level, file, " OUTSIDE = 0x%"UVxf" (%s)\n", @@ -2000,7 +1994,8 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo GvNAMEUTF8(CvGV(outside))) : "UNDEFINED")); } - if (nest < maxnest && (CvCLONE(sv) || CvCLONED(sv))) + if (CvOUTSIDE(sv) + && (nest < maxnest && (CvCLONE(sv) || CvCLONED(sv)))) do_sv_dump(level+1, file, MUTABLE_SV(CvOUTSIDE(sv)), nest+1, maxnest, dumpops, pvlim); break; @@ -2240,11 +2235,217 @@ Perl_runops_debug(pTHX) return 0; } + +/* print the names of the n lexical vars starting at pad offset off */ + +void +S_deb_padvar(pTHX_ PADOFFSET off, int n, bool paren) +{ + PADNAME *sv; + CV * const cv = deb_curcv(cxstack_ix); + PADNAMELIST *comppad = NULL; + int i; + + if (cv) { + PADLIST * const padlist = CvPADLIST(cv); + comppad = PadlistNAMES(padlist); + } + if (paren) + PerlIO_printf(Perl_debug_log, "("); + for (i = 0; i < n; i++) { + if (comppad && (sv = padnamelist_fetch(comppad, off + i))) + PerlIO_printf(Perl_debug_log, "%"PNf, PNfARG(sv)); + else + PerlIO_printf(Perl_debug_log, "[%"UVuf"]", + (UV)(off+i)); + if (i < n - 1) + PerlIO_printf(Perl_debug_log, ","); + } + if (paren) + PerlIO_printf(Perl_debug_log, ")"); +} + + +/* append to the out SV, the name of the lexical at offset off in the CV + * cv */ + +static void +S_append_padvar(pTHX_ PADOFFSET off, CV *cv, SV *out, int n, + bool paren, bool is_scalar) +{ + PADNAME *sv; + PADNAMELIST *namepad = NULL; + int i; + + if (cv) { + PADLIST * const padlist = CvPADLIST(cv); + namepad = PadlistNAMES(padlist); + } + + if (paren) + sv_catpvs_nomg(out, "("); + for (i = 0; i < n; i++) { + if (namepad && (sv = padnamelist_fetch(namepad, off + i))) + { + STRLEN cur = SvCUR(out); + Perl_sv_catpvf(aTHX_ out, "[%"UTF8f, + UTF8fARG(1, PadnameLEN(sv) - 1, + PadnamePV(sv) + 1)); + if (is_scalar) + SvPVX(out)[cur] = '$'; + } + else + Perl_sv_catpvf(aTHX_ out, "[%"UVuf"]", (UV)(off+i)); + if (i < n - 1) + sv_catpvs_nomg(out, ","); + } + if (paren) + sv_catpvs_nomg(out, "("); +} + + +static void +S_append_gv_name(pTHX_ GV *gv, SV *out) +{ + SV *sv; + if (!gv) { + sv_catpvs_nomg(out, ""); + return; + } + sv = newSV(0); + gv_fullname4(sv, gv, NULL, FALSE); + Perl_sv_catpvf(aTHX_ out, "%c%-p", '$', sv); + SvREFCNT_dec_NN(sv); +} + +#ifdef USE_ITHREADS +# define ITEM_SV(item) *av_fetch(comppad, (item)->pad_offset, FALSE); +#else +# define ITEM_SV(item) UNOP_AUX_item_sv(item) +#endif + + +/* return a temporary SV containing a stringified representation of + * the op_aux field of a UNOP_AUX op, associated with CV cv + */ + +SV* +Perl_unop_aux_stringify(pTHX_ const OP *o, CV *cv) +{ + UNOP_AUX_item *items = cUNOP_AUXo->op_aux; + UV actions = items->uv; + SV *sv; + bool last = 0; + bool is_hash = FALSE; + int derefs = 0; + SV *out = newSVpvn_flags("",0,SVs_TEMP); +#ifdef USE_ITHREADS + PADLIST * const padlist = CvPADLIST(cv); + PAD *comppad = PadlistARRAY(padlist)[1]; +#endif + + PERL_ARGS_ASSERT_UNOP_AUX_STRINGIFY; + + while (!last) { + switch (actions & MDEREF_ACTION_MASK) { + + case MDEREF_reload: + actions = (++items)->uv; + continue; + + case MDEREF_HV_padhv_helem: + is_hash = TRUE; + case MDEREF_AV_padav_aelem: + derefs = 1; + S_append_padvar(aTHX_ (++items)->pad_offset, cv, out, 1, 0, 1); + goto do_elem; + + case MDEREF_HV_gvhv_helem: + is_hash = TRUE; + case MDEREF_AV_gvav_aelem: + derefs = 1; + sv = ITEM_SV(++items); + S_append_gv_name(aTHX_ (GV*)sv, out); + goto do_elem; + + case MDEREF_HV_gvsv_vivify_rv2hv_helem: + is_hash = TRUE; + case MDEREF_AV_gvsv_vivify_rv2av_aelem: + sv = ITEM_SV(++items); + S_append_gv_name(aTHX_ (GV*)sv, out); + goto do_vivify_rv2xv_elem; + + case MDEREF_HV_padsv_vivify_rv2hv_helem: + is_hash = TRUE; + case MDEREF_AV_padsv_vivify_rv2av_aelem: + S_append_padvar(aTHX_ (++items)->pad_offset, cv, out, 1, 0, 1); + goto do_vivify_rv2xv_elem; + + case MDEREF_HV_pop_rv2hv_helem: + case MDEREF_HV_vivify_rv2hv_helem: + is_hash = TRUE; + do_vivify_rv2xv_elem: + case MDEREF_AV_pop_rv2av_aelem: + case MDEREF_AV_vivify_rv2av_aelem: + if (!derefs++) + sv_catpvs_nomg(out, "->"); + do_elem: + if ((actions & MDEREF_INDEX_MASK)== MDEREF_INDEX_none) { + sv_catpvs_nomg(out, "->"); + last = 1; + break; + } + + sv_catpvn_nomg(out, (is_hash ? "{" : "["), 1); + switch (actions & MDEREF_INDEX_MASK) { + case MDEREF_INDEX_const: + if (is_hash) { + STRLEN cur; + char *s; + sv = ITEM_SV(++items); + s = SvPV(sv, cur); + pv_pretty(out, s, cur, 30, + NULL, NULL, + (PERL_PV_PRETTY_NOCLEAR + |PERL_PV_PRETTY_QUOTE + |PERL_PV_PRETTY_ELLIPSES)); + } + else + Perl_sv_catpvf(aTHX_ out, "%"IVdf, (++items)->iv); + break; + case MDEREF_INDEX_padsv: + S_append_padvar(aTHX_ (++items)->pad_offset, cv, out, 1, 0, 1); + break; + case MDEREF_INDEX_gvsv: + sv = ITEM_SV(++items); + S_append_gv_name(aTHX_ (GV*)sv, out); + break; + } + sv_catpvn_nomg(out, (is_hash ? "}" : "]"), 1); + + if (actions & MDEREF_FLAG_last) + last = 1; + is_hash = FALSE; + + break; + + default: + PerlIO_printf(Perl_debug_log, "UNKNOWN(%d)", + (int)(actions & MDEREF_ACTION_MASK)); + last = 1; + break; + + } /* switch */ + + actions >>= MDEREF_SHIFT; + } /* while */ + return out; +} + + I32 Perl_debop(pTHX_ const OP *o) { - int count; - PERL_ARGS_ASSERT_DEBOP; if (CopSTASH_eq(PL_curcop, PL_debstash) && !DEBUG_J_TEST_) @@ -2286,35 +2487,17 @@ Perl_debop(pTHX_ const OP *o) case OP_PADSV: case OP_PADAV: case OP_PADHV: - count = 1; - goto dump_padop; + S_deb_padvar(aTHX_ o->op_targ, 1, 1); + break; + case OP_PADRANGE: - count = o->op_private & OPpPADRANGE_COUNTMASK; - dump_padop: - /* print the lexical's name */ - { - CV * const cv = deb_curcv(cxstack_ix); - SV *sv; - PAD * comppad = NULL; - int i; - - if (cv) { - PADLIST * const padlist = CvPADLIST(cv); - comppad = *PadlistARRAY(padlist); - } - PerlIO_printf(Perl_debug_log, "("); - for (i = 0; i < count; i++) { - if (comppad && - (sv = *av_fetch(comppad, o->op_targ + i, FALSE))) - PerlIO_printf(Perl_debug_log, "%s", SvPV_nolen_const(sv)); - else - PerlIO_printf(Perl_debug_log, "[%"UVuf"]", - (UV)o->op_targ+i); - if (i < count-1) - PerlIO_printf(Perl_debug_log, ","); - } - PerlIO_printf(Perl_debug_log, ")"); - } + S_deb_padvar(aTHX_ o->op_targ, + o->op_private & OPpPADRANGE_COUNTMASK, 1); + break; + + case OP_MULTIDEREF: + PerlIO_printf(Perl_debug_log, "(%-p)", + unop_aux_stringify(o, deb_curcv(cxstack_ix))); break; default: