This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Use SvTAIL() instead of BmFLAGS(). The core no longer uses BmFLAGS().
[perl5.git] / dump.c
diff --git a/dump.c b/dump.c
index eeb43be..b541aa1 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -232,18 +232,18 @@ if PERL_PV_ESCAPE_UNI_DETECT is set then the input string is scanned
 using C<is_utf8_string()> to determine if it is Unicode.
 
 If PERL_PV_ESCAPE_ALL is set then all input chars will be output
-using C<\x01F1> style escapes, otherwise only chars above 255 will be
-escaped using this style, other non printable chars will use octal or
-common escaped patterns like C<\n>. If PERL_PV_ESCAPE_NOBACKSLASH
-then all chars below 255 will be treated as printable and 
+using C<\x01F1> style escapes, otherwise if PERL_PV_ESCAPE_NONASCII is set, only
+chars above 127 will be escaped using this style; otherwise, only chars above
+255 will be so escaped; other non printable chars will use octal or
+common escaped patterns like C<\n>. Otherwise, if PERL_PV_ESCAPE_NOBACKSLASH
+then all chars below 255 will be treated as printable and
 will be output as literals.
 
 If PERL_PV_ESCAPE_FIRSTCHAR is set then only the first char of the
-string will be escaped, regardles of max. If the string is utf8 and 
-the chars value is >255 then it will be returned as a plain hex 
-sequence. Thus the output will either be a single char, 
-an octal escape sequence, a special escape like C<\n> or a 3 or 
-more digit hex value. 
+string will be escaped, regardless of max. If the output is to be in hex,
+then it will be returned as a plain hex
+sequence. Thus the output will either be a single char,
+an octal escape sequence, a special escape like C<\n> or a hex value.
 
 If PERL_PV_ESCAPE_RE is set then the escape char used will be a '%' and
 not a '\\'. This is because regexes very often contain backslashed
@@ -285,7 +285,10 @@ Perl_pv_escape( pTHX_ SV *dsv, char const * const str,
         const UV u= (isuni) ? utf8_to_uvchr((U8*)pv, &readsize) : (U8)*pv;            
         const U8 c = (U8)u & 0xFF;
         
-        if ( ( u > 255 ) || (flags & PERL_PV_ESCAPE_ALL)) {
+        if ( ( u > 255 )
+         || (flags & PERL_PV_ESCAPE_ALL)
+         || (( u > 127 ) && (flags & PERL_PV_ESCAPE_NONASCII)))
+       {
             if (flags & PERL_PV_ESCAPE_FIRSTCHAR) 
                 chsize = my_snprintf( octbuf, PV_ESCAPE_OCTBUFSIZE, 
                                       "%"UVxf, u);
@@ -318,7 +321,7 @@ Perl_pv_escape( pTHX_ SV *dsv, char const * const str,
                             chsize = 1;
                         break;
                default:
-                        if ( (pv < end) && isDIGIT((U8)*(pv+readsize)) )
+                        if ( (pv+readsize < end) && isDIGIT((U8)*(pv+readsize)) )
                             chsize = my_snprintf( octbuf, PV_ESCAPE_OCTBUFSIZE, 
                                                   "%c%03o", esc, c);
                        else
@@ -361,18 +364,18 @@ If the PERL_PV_PRETTY_QUOTE flag is set then the result will be
 double quoted with any double quotes in the string escaped. Otherwise
 if the PERL_PV_PRETTY_LTGT flag is set then the result be wrapped in
 angle brackets. 
-           
+
 If the PERL_PV_PRETTY_ELLIPSES flag is set and not all characters in
 string were output then an ellipsis C<...> will be appended to the
 string. Note that this happens AFTER it has been quoted.
-           
+
 If start_color is non-null then it will be inserted after the opening
 quote (if there is one) but before the escaped text. If end_color
 is non-null then it will be inserted after the escaped text but before
 any quotes or ellipses.
 
 Returns a pointer to the prettified text as held by dsv.
-           
+
 =cut           
 */
 
@@ -1035,7 +1038,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o)
        }
        else if (S_op_private_to_names(aTHX_ tmpsv, optype, o->op_private)) {
        }
-       else if (PL_check[optype] != MEMBER_TO_FPTR(Perl_ck_ftst)) {
+       else if (PL_check[optype] != Perl_ck_ftst) {
            if (OP_IS_FILETEST_ACCESS(o->op_type) && o->op_private & OPpFT_ACCESS)
                sv_catpv(tmpsv, ",FT_ACCESS");
            if (o->op_private & OPpFT_STACKED)
@@ -1248,6 +1251,7 @@ static const struct { const char type; const char *name; } magic_names[] = {
        { PERL_MAGIC_tied,           "tied(P)" },
        { PERL_MAGIC_sig,            "sig(S)" },
        { PERL_MAGIC_uvar,           "uvar(U)" },
+       { PERL_MAGIC_checkcall,      "checkcall(])" },
        { PERL_MAGIC_overload_elem,  "overload_elem(a)" },
        { PERL_MAGIC_overload_table, "overload_table(c)" },
        { PERL_MAGIC_regdatum,       "regdatum(d)" },
@@ -1351,22 +1355,28 @@ Perl_do_magic_dump(pTHX_ I32 level, PerlIO *file, const MAGIC *mg, I32 nest, I32
            if (mg->mg_type == PERL_MAGIC_envelem &&
                mg->mg_flags & MGf_TAINTEDDIR)
                Perl_dump_indent(aTHX_ level, file, "      TAINTEDDIR\n");
+           if (mg->mg_type == PERL_MAGIC_regex_global &&
+               mg->mg_flags & MGf_MINMATCH)
+               Perl_dump_indent(aTHX_ level, file, "      MINMATCH\n");
            if (mg->mg_flags & MGf_REFCOUNTED)
                Perl_dump_indent(aTHX_ level, file, "      REFCOUNTED\n");
             if (mg->mg_flags & MGf_GSKIP)
                Perl_dump_indent(aTHX_ level, file, "      GSKIP\n");
-           if (mg->mg_type == PERL_MAGIC_regex_global &&
-               mg->mg_flags & MGf_MINMATCH)
-               Perl_dump_indent(aTHX_ level, file, "      MINMATCH\n");
+           if (mg->mg_flags & MGf_COPY)
+               Perl_dump_indent(aTHX_ level, file, "      COPY\n");
+           if (mg->mg_flags & MGf_DUP)
+               Perl_dump_indent(aTHX_ level, file, "      DUP\n");
+           if (mg->mg_flags & MGf_LOCAL)
+               Perl_dump_indent(aTHX_ level, file, "      LOCAL\n");
         }
        if (mg->mg_obj) {
-           Perl_dump_indent(aTHX_ level, file, "    MG_OBJ = 0x%"UVxf"\n", 
+           Perl_dump_indent(aTHX_ level, file, "    MG_OBJ = 0x%"UVxf"\n",
                PTR2UV(mg->mg_obj));
             if (mg->mg_type == PERL_MAGIC_qr) {
                REGEXP* const re = (REGEXP *)mg->mg_obj;
                SV * const dsv = sv_newmortal();
                 const char * const s
-                   = pv_pretty(dsv, RX_WRAPPED(re), RX_WRAPLEN(re), 
+                   = pv_pretty(dsv, RX_WRAPPED(re), RX_WRAPLEN(re),
                     60, NULL, NULL,
                     ( PERL_PV_PRETTY_QUOTE | PERL_PV_ESCAPE_RE | PERL_PV_PRETTY_ELLIPSES |
                     (RX_UTF8(re) ? PERL_PV_ESCAPE_UNI : 0))
@@ -1434,7 +1444,14 @@ Perl_do_hv_dump(pTHX_ I32 level, PerlIO *file, const char *name, HV *sv)
 
     Perl_dump_indent(aTHX_ level, file, "%s = 0x%"UVxf, name, PTR2UV(sv));
     if (sv && (hvname = HvNAME_get(sv)))
-       PerlIO_printf(file, "\t\"%s\"\n", hvname);
+    {
+       /* we have to use pv_display and HvNAMELEN_get() so that we display the real package
+           name which quite legally could contain insane things like tabs, newlines, nulls or
+           other scary crap - this should produce sane results - except maybe for unicode package
+           names - but we will wait for someone to file a bug on that - demerphq */
+        SV * const tmpsv = newSVpvs("");
+        PerlIO_printf(file, "\t%s\n", pv_display(tmpsv, hvname, HvNAMELEN_get(sv), 0, 1024));
+    }
     else
        PerlIO_putc(file, '\n');
 }
@@ -1500,7 +1517,8 @@ const struct flag_to_name cv_flags_names[] = {
     {CVf_LVALUE, "LVALUE,"},
     {CVf_METHOD, "METHOD,"},
     {CVf_WEAKOUTSIDE, "WEAKOUTSIDE,"},
-    {CVf_CVGV_RC, "CVGV_RC,"}
+    {CVf_CVGV_RC, "CVGV_RC,"},
+    {CVf_ISXSUB, "ISXSUB,"}
 };
 
 const struct flag_to_name hv_flags_names[] = {
@@ -1525,6 +1543,37 @@ const struct flag_to_name gp_flags_imported_names[] = {
     {GVf_IMPORTED_CV, " CV"},
 };
 
+const struct flag_to_name regexp_flags_names[] = {
+    {RXf_PMf_MULTILINE,   "PMf_MULTILINE,"},
+    {RXf_PMf_SINGLELINE,  "PMf_SINGLELINE,"},
+    {RXf_PMf_FOLD,        "PMf_FOLD,"},
+    {RXf_PMf_EXTENDED,    "PMf_EXTENDED,"},
+    {RXf_PMf_KEEPCOPY,    "PMf_KEEPCOPY,"},
+    {RXf_ANCH_BOL,        "ANCH_BOL,"},
+    {RXf_ANCH_MBOL,       "ANCH_MBOL,"},
+    {RXf_ANCH_SBOL,       "ANCH_SBOL,"},
+    {RXf_ANCH_GPOS,       "ANCH_GPOS,"},
+    {RXf_GPOS_SEEN,       "GPOS_SEEN,"},
+    {RXf_GPOS_FLOAT,      "GPOS_FLOAT,"},
+    {RXf_LOOKBEHIND_SEEN, "LOOKBEHIND_SEEN,"},
+    {RXf_EVAL_SEEN,       "EVAL_SEEN,"},
+    {RXf_CANY_SEEN,       "CANY_SEEN,"},
+    {RXf_NOSCAN,          "NOSCAN,"},
+    {RXf_CHECK_ALL,       "CHECK_ALL,"},
+    {RXf_MATCH_UTF8,      "MATCH_UTF8,"},
+    {RXf_USE_INTUIT_NOML, "USE_INTUIT_NOML,"},
+    {RXf_USE_INTUIT_ML,   "USE_INTUIT_ML,"},
+    {RXf_INTUIT_TAIL,     "INTUIT_TAIL,"},
+    {RXf_SPLIT,           "SPLIT,"},
+    {RXf_COPY_DONE,       "COPY_DONE,"},
+    {RXf_TAINTED_SEEN,    "TAINTED_SEEN,"},
+    {RXf_TAINTED,         "TAINTED,"},
+    {RXf_START_ONLY,      "START_ONLY,"},
+    {RXf_SKIPWHITE,       "SKIPWHITE,"},
+    {RXf_WHITE,           "WHITE,"},
+    {RXf_NULL,            "NULL,"},
+};
+
 void
 Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bool dumpops, STRLEN pvlim)
 {
@@ -1544,16 +1593,19 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
     flags = SvFLAGS(sv);
     type = SvTYPE(sv);
 
+    /* process general SV flags */
+
     d = Perl_newSVpvf(aTHX_
                   "(0x%"UVxf") at 0x%"UVxf"\n%*s  REFCNT = %"IVdf"\n%*s  FLAGS = (",
                   PTR2UV(SvANY(sv)), PTR2UV(sv),
                   (int)(PL_dumpindent*level), "", (IV)SvREFCNT(sv),
                   (int)(PL_dumpindent*level), "");
 
-    if (!(flags & SVpad_NAME && (type == SVt_PVMG || type == SVt_PVNV))) {
+    if (!((flags & SVpad_NAME) == SVpad_NAME
+         && (type == SVt_PVMG || type == SVt_PVNV))) {
        if (flags & SVs_PADSTALE)       sv_catpv(d, "PADSTALE,");
     }
-    if (!(flags & SVpad_NAME && type == SVt_PVMG)) {
+    if (!((flags & SVpad_NAME) == SVpad_NAME && type == SVt_PVMG)) {
        if (flags & SVs_PADTMP) sv_catpv(d, "PADTMP,");
        if (flags & SVs_PADMY)  sv_catpv(d, "PADMY,");
     }
@@ -1570,11 +1622,12 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                                sv_catpv(d, "SCREAM,");
     }
 
+    /* process type-specific SV flags */
+
     switch (type) {
     case SVt_PVCV:
     case SVt_PVFM:
        append_flags(d, CvFLAGS(sv), cv_flags_names);
-       if (SvCOMPILED(sv))     sv_catpv(d, "COMPILED,");
        break;
     case SVt_PVHV:
        append_flags(d, flags, hv_flags_names);
@@ -1623,18 +1676,23 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
     sv_catpv(d, ")");
     s = SvPVX_const(d);
 
+    /* dump initial SV details */
+
 #ifdef DEBUG_LEAKING_SCALARS
     Perl_dump_indent(aTHX_ level, file,
-       "ALLOCATED at %s:%d %s %s%s; serial %"UVuf"\n",
+       "ALLOCATED at %s:%d %s %s (parent 0x%"UVxf"); serial %"UVuf"\n",
        sv->sv_debug_file ? sv->sv_debug_file : "(unknown)",
        sv->sv_debug_line,
        sv->sv_debug_inpad ? "for" : "by",
        sv->sv_debug_optype ? PL_op_name[sv->sv_debug_optype]: "(none)",
-       sv->sv_debug_cloned ? " (cloned)" : "",
+       PTR2UV(sv->sv_debug_parent),
        sv->sv_debug_serial
     );
 #endif
     Perl_dump_indent(aTHX_ level, file, "SV = ");
+
+    /* Dump SV type */
+
     if (type < SVt_LAST) {
        PerlIO_printf(file, "%s%s\n", svtypenames[type], s);
 
@@ -1647,9 +1705,12 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        SvREFCNT_dec(d);
        return;
     }
+
+    /* Dump general SV fields */
+
     if ((type >= SVt_PVIV && type != SVt_PVAV && type != SVt_PVHV
-        && type != SVt_PVCV && !isGV_with_GP(sv) && type != SVt_PVFM
-        && type != SVt_PVIO && type != SVt_REGEXP)
+        && type != SVt_PVCV && type != SVt_PVFM && type != SVt_PVIO
+        && type != SVt_REGEXP && !isGV_with_GP(sv) && !SvVALID(sv))
        || (type == SVt_IV && !SvROK(sv))) {
        if (SvIsUV(sv)
 #ifdef PERL_OLD_COPY_ON_WRITE
@@ -1667,7 +1728,9 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
 #endif
        PerlIO_putc(file, '\n');
     }
-    if ((type == SVt_PVNV || type == SVt_PVMG) && SvFLAGS(sv) & SVpad_NAME) {
+
+    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",
@@ -1685,15 +1748,18 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
 #endif
        RESTORE_NUMERIC_LOCAL();
     }
+
     if (SvROK(sv)) {
        Perl_dump_indent(aTHX_ level, file, "  RV = 0x%"UVxf"\n", PTR2UV(SvRV(sv)));
        if (nest < maxnest)
            do_sv_dump(level+1, file, SvRV(sv), nest+1, maxnest, dumpops, pvlim);
     }
+
     if (type < SVt_PV) {
        SvREFCNT_dec(d);
        return;
     }
+
     if ((type <= SVt_PVLV && !isGV_with_GP(sv)) || type == SVt_PVFM) {
        if (SvPVX_const(sv)) {
            STRLEN delta;
@@ -1720,12 +1786,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        else
            Perl_dump_indent(aTHX_ level, file, "  PV = 0\n");
     }
-    if (type == SVt_REGEXP) {
-       /* FIXME dumping
-           Perl_dump_indent(aTHX_ level, file, "  REGEXP = 0x%"UVxf"\n",
-                            PTR2UV(((struct regexp *)SvANY(sv))->xrx_regexp));
-       */
-    }
+
     if (type >= SVt_PVMG) {
        if (type == SVt_PVMG && SvPAD_OUR(sv)) {
            HV * const ost = SvOURSTASH(sv);
@@ -1733,11 +1794,14 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                do_hv_dump(level, file, "  OURSTASH", ost);
        } else {
            if (SvMAGIC(sv))
-               do_magic_dump(level, file, SvMAGIC(sv), nest, maxnest, dumpops, pvlim);
+               do_magic_dump(level, file, SvMAGIC(sv), nest+1, maxnest, dumpops, pvlim);
        }
        if (SvSTASH(sv))
            do_hv_dump(level, file, "  STASH", SvSTASH(sv));
     }
+
+    /* Dump type-specific SV fields */
+
     switch (type) {
     case SVt_PVAV:
        Perl_dump_indent(aTHX_ level, file, "  ARRAY = 0x%"UVxf, PTR2UV(AvARRAY(sv)));
@@ -1768,13 +1832,13 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        break;
     case SVt_PVHV:
        Perl_dump_indent(aTHX_ level, file, "  ARRAY = 0x%"UVxf, PTR2UV(HvARRAY(sv)));
-       if (HvARRAY(sv) && HvKEYS(sv)) {
+       if (HvARRAY(sv) && HvUSEDKEYS(sv)) {
            /* Show distribution of HEs in the ARRAY */
            int freq[200];
 #define FREQ_MAX ((int)(sizeof freq / sizeof freq[0] - 1))
            int i;
            int max = 0;
-           U32 pow2 = 2, keys = HvKEYS(sv);
+           U32 pow2 = 2, keys = HvUSEDKEYS(sv);
            NV theoret, sum = 0;
 
            PerlIO_printf(file, "  (");
@@ -1816,13 +1880,13 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
             }
            while ((keys = keys >> 1))
                pow2 = pow2 << 1;
-           theoret = HvKEYS(sv);
+           theoret = HvUSEDKEYS(sv);
            theoret += theoret * (theoret-1)/pow2;
            PerlIO_putc(file, '\n');
            Perl_dump_indent(aTHX_ level, file, "  hash quality = %.1"NVff"%%", theoret/sum*100);
        }
        PerlIO_putc(file, '\n');
-       Perl_dump_indent(aTHX_ level, file, "  KEYS = %"IVdf"\n", (IV)HvKEYS(sv));
+       Perl_dump_indent(aTHX_ level, file, "  KEYS = %"IVdf"\n", (IV)HvUSEDKEYS(sv));
        Perl_dump_indent(aTHX_ level, file, "  FILL = %"IVdf"\n", (IV)HvFILL(sv));
        Perl_dump_indent(aTHX_ level, file, "  MAX = %"IVdf"\n", (IV)HvMAX(sv));
        Perl_dump_indent(aTHX_ level, file, "  RITER = %"IVdf"\n", (IV)HvRITER_get(sv));
@@ -1842,6 +1906,41 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
            AV * const backrefs
                = *Perl_hv_backreferences_p(aTHX_ MUTABLE_HV(sv));
            struct mro_meta * const meta = HvAUX(sv)->xhv_mro_meta;
+           if (HvAUX(sv)->xhv_name_count)
+               Perl_dump_indent(aTHX_
+                level, file, "  NAMECOUNT = %"IVdf"\n",
+                (IV)HvAUX(sv)->xhv_name_count
+               );
+           if (HvAUX(sv)->xhv_name_u.xhvnameu_name && HvENAME_HEK_NN(sv)) {
+               const I32 count = HvAUX(sv)->xhv_name_count;
+               if (count) {
+                   SV * const names = newSVpvs_flags("", SVs_TEMP);
+                   /* The starting point is the first element if count is
+                      positive and the second element if count is negative. */
+                   HEK *const *hekp = HvAUX(sv)->xhv_name_u.xhvnameu_names
+                       + (count < 0 ? 1 : 0);
+                   HEK *const *const endp = HvAUX(sv)->xhv_name_u.xhvnameu_names
+                       + (count < 0 ? -count : count);
+                   while (hekp < endp) {
+                       if (*hekp) {
+                           sv_catpvs(names, ", \"");
+                           sv_catpvn(names, HEK_KEY(*hekp), HEK_LEN(*hekp));
+                           sv_catpvs(names, "\"");
+                       } else {
+                           /* This should never happen. */
+                           sv_catpvs(names, ", (null)");
+                       }
+                       ++hekp;
+                   }
+                   Perl_dump_indent(aTHX_
+                    level, file, "  ENAME = %s\n", SvPV_nolen(names)+2
+                   );
+               }
+               else
+                   Perl_dump_indent(aTHX_
+                    level, file, "  ENAME = \"%s\"\n", HvENAME_get(sv)
+                   );
+           }
            if (backrefs) {
                Perl_dump_indent(aTHX_ level, file, "  BACKREFS = 0x%"UVxf"\n",
                                 PTR2UV(backrefs));
@@ -1914,6 +2013,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
            }
        }
        break;
+
     case SVt_PVCV:
        if (SvPOK(sv)) {
            STRLEN len;
@@ -1977,6 +2077,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        if (nest < maxnest && (CvCLONE(sv) || CvCLONED(sv)))
            do_sv_dump(level+1, file, MUTABLE_SV(CvOUTSIDE(sv)), nest+1, maxnest, dumpops, pvlim);
        break;
+
     case SVt_PVGV:
     case SVt_PVLV:
        if (type == SVt_PVLV) {
@@ -1989,7 +2090,6 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                    dumpops, pvlim);
        }
        if (SvVALID(sv)) {
-           Perl_dump_indent(aTHX_ level, file, "  FLAGS = %u\n", (U8)BmFLAGS(sv));
            Perl_dump_indent(aTHX_ level, file, "  RARE = %u\n", (U8)BmRARE(sv));
            Perl_dump_indent(aTHX_ level, file, "  PREVIOUS = %"UVuf"\n", (UV)BmPREVIOUS(sv));
            Perl_dump_indent(aTHX_ level, file, "  USEFUL = %"IVdf"\n", (IV)BmUSEFUL(sv));
@@ -2061,6 +2161,62 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
             Perl_dump_indent(aTHX_ level, file, "  TYPE = '\\%o'\n", IoTYPE(sv));
        Perl_dump_indent(aTHX_ level, file, "  FLAGS = 0x%"UVxf"\n", (UV)IoFLAGS(sv));
        break;
+    case SVt_REGEXP:
+       {
+           struct regexp * const r = (struct regexp *)SvANY(sv);
+           flags = RX_EXTFLAGS((REGEXP*)sv);
+           sv_setpv(d,"");
+           append_flags(d, flags, regexp_flags_names);
+           if (*(SvEND(d) - 1) == ',') {
+               SvCUR_set(d, SvCUR(d) - 1);
+               SvPVX(d)[SvCUR(d)] = '\0';
+           }
+           Perl_dump_indent(aTHX_ level, file, "  EXTFLAGS = 0x%"UVxf" (%s)\n",
+                               (UV)flags, SvPVX_const(d));
+           Perl_dump_indent(aTHX_ level, file, "  INTFLAGS = 0x%"UVxf"\n",
+                               (UV)(r->intflags));
+           Perl_dump_indent(aTHX_ level, file, "  NPARENS = %"UVuf"\n",
+                               (UV)(r->nparens));
+           Perl_dump_indent(aTHX_ level, file, "  LASTPAREN = %"UVuf"\n",
+                               (UV)(r->lastparen));
+           Perl_dump_indent(aTHX_ level, file, "  LASTCLOSEPAREN = %"UVuf"\n",
+                               (UV)(r->lastcloseparen));
+           Perl_dump_indent(aTHX_ level, file, "  MINLEN = %"IVdf"\n",
+                               (IV)(r->minlen));
+           Perl_dump_indent(aTHX_ level, file, "  MINLENRET = %"IVdf"\n",
+                               (IV)(r->minlenret));
+           Perl_dump_indent(aTHX_ level, file, "  GOFS = %"UVuf"\n",
+                               (UV)(r->gofs));
+           Perl_dump_indent(aTHX_ level, file, "  PRE_PREFIX = %"UVuf"\n",
+                               (UV)(r->pre_prefix));
+           Perl_dump_indent(aTHX_ level, file, "  SEEN_EVALS = %"UVuf"\n",
+                               (UV)(r->seen_evals));
+           Perl_dump_indent(aTHX_ level, file, "  SUBLEN = %"IVdf"\n",
+                               (IV)(r->sublen));
+           if (r->subbeg)
+               Perl_dump_indent(aTHX_ level, file, "  SUBBEG = 0x%"UVxf" %s\n",
+                           PTR2UV(r->subbeg),
+                           pv_display(d, r->subbeg, r->sublen, 50, pvlim));
+           else
+               Perl_dump_indent(aTHX_ level, file, "  SUBBEG = 0x0\n");
+           Perl_dump_indent(aTHX_ level, file, "  ENGINE = 0x%"UVxf"\n",
+                               PTR2UV(r->engine));
+           Perl_dump_indent(aTHX_ level, file, "  MOTHER_RE = 0x%"UVxf"\n",
+                               PTR2UV(r->mother_re));
+           Perl_dump_indent(aTHX_ level, file, "  PAREN_NAMES = 0x%"UVxf"\n",
+                               PTR2UV(r->paren_names));
+           Perl_dump_indent(aTHX_ level, file, "  SUBSTRS = 0x%"UVxf"\n",
+                               PTR2UV(r->substrs));
+           Perl_dump_indent(aTHX_ level, file, "  PPRIVATE = 0x%"UVxf"\n",
+                               PTR2UV(r->pprivate));
+           Perl_dump_indent(aTHX_ level, file, "  OFFS = 0x%"UVxf"\n",
+                               PTR2UV(r->offs));
+#ifdef PERL_OLD_COPY_ON_WRITE
+           Perl_dump_indent(aTHX_ level, file, "  SAVED_COPY = 0x%"UVxf"\n",
+                               PTR2UV(r->saved_copy));
+#endif
+       }
+       break;
     }
     SvREFCNT_dec(d);
 }
@@ -2108,7 +2264,7 @@ Perl_runops_debug(pTHX)
            if (DEBUG_t_TEST_) debop(PL_op);
            if (DEBUG_P_TEST_) debprof(PL_op);
        }
-    } while ((PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX)));
+    } while ((PL_op = PL_op->op_ppaddr(aTHX)));
     DEBUG_l(Perl_deb(aTHX_ "leaving RUNOPS level\n"));
 
     TAINT_NOT;
@@ -2284,12 +2440,13 @@ Perl_xmldump_all(pTHX)
 }
 
 void
-Perl_xmldump_all_perl(pTHX_ bool justperl)
+Perl_xmldump_all_perl(pTHX_ bool justperl PERL_UNUSED_DECL)
 {
     PerlIO_setlinebuf(PL_xmlfp);
     if (PL_main_root)
        op_xmldump(PL_main_root);
-    xmldump_packsubs_perl(PL_defstash, justperl);
+    /* someday we might call this, when it outputs XML: */
+    /* xmldump_packsubs_perl(PL_defstash, justperl); */
     if (PL_xmlfp != (PerlIO*)PerlIO_stdout())
        PerlIO_close(PL_xmlfp);
     PL_xmlfp = 0;
@@ -2388,6 +2545,13 @@ Perl_sv_catxmlsv(pTHX_ SV *dsv, SV *ssv)
 }
 
 char *
+Perl_sv_catxmlpv(pTHX_ SV *dsv, const char *pv, int utf8)
+{
+    PERL_ARGS_ASSERT_SV_CATXMLPV;
+    return sv_catxmlpvn(dsv, pv, strlen(pv), utf8);
+}
+
+char *
 Perl_sv_catxmlpvn(pTHX_ SV *dsv, const char *pv, STRLEN len, int utf8)
 {
     unsigned int c;
@@ -2644,7 +2808,7 @@ Perl_sv_xmlpeek(pTHX_ SV *sv)
        sv_catpv(t, " BIND=\"");
        break;
     case SVt_REGEXP:
-       sv_catpv(t, " ORANGE=\"");
+       sv_catpv(t, " REGEXP=\"");
        break;
     case SVt_PVFM:
        sv_catpv(t, " FM=\"");
@@ -2958,7 +3122,7 @@ Perl_do_op_xmldump(pTHX_ I32 level, PerlIO *file, const OP *o)
            if (o->op_private & OPpHUSH_VMSISH)
                sv_catpv(tmpsv, ",HUSH_VMSISH");
        }
-       else if (PL_check[o->op_type] != MEMBER_TO_FPTR(Perl_ck_ftst)) {
+       else if (PL_check[o->op_type] != Perl_ck_ftst) {
            if (OP_IS_FILETEST_ACCESS(o->op_type) && o->op_private & OPpFT_ACCESS)
                sv_catpv(tmpsv, ",FT_ACCESS");
            if (o->op_private & OPpFT_STACKED)