This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[REPOST] [PATCH] Remove superfluous counter in threads
[perl5.git] / regcomp.c
index e38a572..ce24f44 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -79,7 +79,7 @@
  ****    Alterations to Henry's code are...
  ****
  ****    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.
@@ -282,27 +282,6 @@ static const scan_data_t zero_scan_data =
 } STMT_END
 
 /*
- * Calls SAVEDESTRUCTOR_X if needed, then calls Perl_croak with the given
- * args. Show regex, up to a maximum length. If it's too long, chop and add
- * "...".
- */
-#define        FAIL2(pat,msg) STMT_START {                                     \
-    const char *ellipses = "";                                         \
-    IV len = RExC_end - RExC_precomp;                                  \
-                                                                       \
-    if (!SIZE_ONLY)                                                    \
-       SAVEDESTRUCTOR_X(clear_re,(void*)RExC_rx);                      \
-    if (len > RegexLengthToShowInErrorMessages) {                      \
-       /* chop 10 shorter than the max, to ensure meaning of "..." */  \
-       len = RegexLengthToShowInErrorMessages - 10;                    \
-       ellipses = "...";                                               \
-    }                                                                  \
-    S_re_croak2(aTHX_ pat, " in regex m/%.*s%s/",                      \
-           msg, (int)len, RExC_precomp, ellipses);                     \
-} STMT_END
-
-
-/*
  * Simple_vFAIL -- like FAIL, but marks the current location in the scan
  */
 #define        Simple_vFAIL(m) STMT_START {                                    \
@@ -425,7 +404,7 @@ static const scan_data_t zero_scan_data =
        MJD_OFFSET_DEBUG(("** (%d) offset of node %d is %d.\n",         \
                __LINE__, (node), (byte)));                             \
        if((node) < 0) {                                                \
-           Perl_croak(aTHX_ "value of node is %d in Offset macro", node); \
+           Perl_croak(aTHX_ "value of node is %d in Offset macro", (int)(node)); \
        } else {                                                        \
            RExC_offsets[2*(node)-1] = (byte);                          \
        }                                                               \
@@ -439,9 +418,9 @@ static const scan_data_t zero_scan_data =
 #define Set_Node_Length_To_R(node,len) STMT_START {                    \
     if (! SIZE_ONLY) {                                                 \
        MJD_OFFSET_DEBUG(("** (%d) size of node %d is %d.\n",           \
-               __LINE__, (node), (len)));                              \
+               __LINE__, (int)(node), (int)(len)));                    \
        if((node) < 0) {                                                \
-           Perl_croak(aTHX_ "value of node is %d in Length macro", node); \
+           Perl_croak(aTHX_ "value of node is %d in Length macro", (int)(node)); \
        } else {                                                        \
            RExC_offsets[2*(node)] = (len);                             \
        }                                                               \
@@ -465,7 +444,7 @@ static void clear_re(pTHX_ void *r);
    floating substrings if needed. */
 
 STATIC void
-S_scan_commit(pTHX_ RExC_state_t *pRExC_state, scan_data_t *data)
+S_scan_commit(pTHX_ const RExC_state_t *pRExC_state, scan_data_t *data)
 {
     const STRLEN l = CHR_SVLEN(data->last_found);
     const STRLEN old_l = CHR_SVLEN(*data->longest);
@@ -497,10 +476,11 @@ S_scan_commit(pTHX_ RExC_state_t *pRExC_state, scan_data_t *data)
     SvCUR_set(data->last_found, 0);
     {
        SV * const sv = data->last_found;
-       MAGIC * const mg =
-           SvUTF8(sv) && SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_utf8) : NULL;
-       if (mg && mg->mg_len > 0)
-           mg->mg_len = 0;
+       if (SvUTF8(sv) && SvMAGICAL(sv)) {
+           MAGIC * const mg = mg_find(sv, PERL_MAGIC_utf8);
+           if (mg)
+               mg->mg_len = 0;
+       }
     }
     data->last_end = -1;
     data->flags &= ~SF_BEFORE_EOL;
@@ -508,7 +488,7 @@ S_scan_commit(pTHX_ RExC_state_t *pRExC_state, scan_data_t *data)
 
 /* Can match anything (initialization) */
 STATIC void
-S_cl_anything(pTHX_ RExC_state_t *pRExC_state, struct regnode_charclass_class *cl)
+S_cl_anything(const RExC_state_t *pRExC_state, struct regnode_charclass_class *cl)
 {
     ANYOF_CLASS_ZERO(cl);
     ANYOF_BITMAP_SETALL(cl);
@@ -519,7 +499,7 @@ S_cl_anything(pTHX_ RExC_state_t *pRExC_state, struct regnode_charclass_class *c
 
 /* Can match anything (initialization) */
 STATIC int
-S_cl_is_anything(pTHX_ const struct regnode_charclass_class *cl)
+S_cl_is_anything(const struct regnode_charclass_class *cl)
 {
     int value;
 
@@ -535,7 +515,7 @@ S_cl_is_anything(pTHX_ const struct regnode_charclass_class *cl)
 
 /* Can match anything (initialization) */
 STATIC void
-S_cl_init(pTHX_ RExC_state_t *pRExC_state, struct regnode_charclass_class *cl)
+S_cl_init(const RExC_state_t *pRExC_state, struct regnode_charclass_class *cl)
 {
     Zero(cl, 1, struct regnode_charclass_class);
     cl->type = ANYOF;
@@ -543,7 +523,7 @@ S_cl_init(pTHX_ RExC_state_t *pRExC_state, struct regnode_charclass_class *cl)
 }
 
 STATIC void
-S_cl_init_zero(pTHX_ RExC_state_t *pRExC_state, struct regnode_charclass_class *cl)
+S_cl_init_zero(const RExC_state_t *pRExC_state, struct regnode_charclass_class *cl)
 {
     Zero(cl, 1, struct regnode_charclass_class);
     cl->type = ANYOF;
@@ -555,7 +535,7 @@ S_cl_init_zero(pTHX_ RExC_state_t *pRExC_state, struct regnode_charclass_class *
 /* 'And' a given class with another one.  Can create false positives */
 /* We assume that cl is not inverted */
 STATIC void
-S_cl_and(pTHX_ struct regnode_charclass_class *cl,
+S_cl_and(struct regnode_charclass_class *cl,
        const struct regnode_charclass_class *and_with)
 {
     if (!(and_with->flags & ANYOF_CLASS)
@@ -592,7 +572,7 @@ S_cl_and(pTHX_ struct regnode_charclass_class *cl,
 /* 'OR' a given class with another one.  Can create false positives */
 /* We assume that cl is not inverted */
 STATIC void
-S_cl_or(pTHX_ RExC_state_t *pRExC_state, struct regnode_charclass_class *cl, const struct regnode_charclass_class *or_with)
+S_cl_or(const RExC_state_t *pRExC_state, struct regnode_charclass_class *cl, const struct regnode_charclass_class *or_with)
 {
     if (or_with->flags & ANYOF_INVERT) {
        /* We do not use
@@ -765,7 +745,7 @@ and would end up looking like:
     DEBUG_TRIE_COMPILE_r({                                                 \
        SV *tmp;                                                           \
        if ( UTF ) {                                                       \
-           tmp = newSVpvn( "", 0 );                                       \
+           tmp = newSVpvs( "" );                                          \
            pv_uni_display( tmp, uc, len, 60, UNI_DISPLAY_REGEX );         \
        } else {                                                           \
            tmp = Perl_newSVpvf_nocontext( "%c", (int)uvc );               \
@@ -827,7 +807,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
     /* first pass, loop through and scan words */
     reg_trie_data *trie;
     regnode *cur;
-    const U32 uniflags = ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY;
+    const U32 uniflags = UTF8_ALLOW_DEFAULT;
     STRLEN len = 0;
     UV uvc = 0;
     U16 curword = 0;
@@ -886,7 +866,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
 
 
     for ( cur = first ; cur < last ; cur = regnext( cur ) ) {
-        regnode *noper = NEXTOPER( cur );
+        regnode * const noper = NEXTOPER( cur );
         const U8 *uc = (U8*)STRING( noper );
         const U8 * const e  = uc + STR_LEN( noper );
         STRLEN foldlen = 0;
@@ -974,72 +954,70 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
 
         for ( cur = first ; cur < last ; cur = regnext( cur ) ) {
 
-        regnode *noper   = NEXTOPER( cur );
-        U8 *uc           = (U8*)STRING( noper );
-        const U8 * const e = uc + STR_LEN( noper );
-        U32 state        = 1;         /* required init */
-        U16 charid       = 0;         /* sanity init */
-        U8 *scan         = (U8*)NULL; /* sanity init */
-        STRLEN foldlen   = 0;         /* required init */
-        U8 foldbuf[ UTF8_MAXBYTES_CASE + 1 ];
-
-
-        for ( ; uc < e ; uc += len ) {
-
-            TRIE_READ_CHAR;
-
-            if ( uvc < 256 ) {
-                charid = trie->charmap[ uvc ];
-            } else {
-                SV** svpp=(SV**)NULL;
-                svpp = hv_fetch( trie->widecharmap, (char*)&uvc, sizeof( UV ), 0);
-                if ( !svpp ) {
-                    charid = 0;
-                } else {
-                    charid=(U16)SvIV( *svpp );
-                }
-            }
-            if ( charid ) {
+           regnode * const noper = NEXTOPER( cur );
+           U8 *uc           = (U8*)STRING( noper );
+           const U8 * const e = uc + STR_LEN( noper );
+           U32 state        = 1;         /* required init */
+           U16 charid       = 0;         /* sanity init */
+           U8 *scan         = (U8*)NULL; /* sanity init */
+           STRLEN foldlen   = 0;         /* required init */
+           U8 foldbuf[ UTF8_MAXBYTES_CASE + 1 ];
+
+           for ( ; uc < e ; uc += len ) {
+
+               TRIE_READ_CHAR;
+
+               if ( uvc < 256 ) {
+                   charid = trie->charmap[ uvc ];
+               } else {
+                   SV** const svpp = hv_fetch( trie->widecharmap, (char*)&uvc, sizeof( UV ), 0);
+                   if ( !svpp ) {
+                       charid = 0;
+                   } else {
+                       charid=(U16)SvIV( *svpp );
+                   }
+               }
+               if ( charid ) {
 
-                U16 check;
-                U32 newstate = 0;
+                   U16 check;
+                   U32 newstate = 0;
 
-                charid--;
-                if ( !trie->states[ state ].trans.list ) {
-                    TRIE_LIST_NEW( state );
-                }
-                for ( check = 1; check <= TRIE_LIST_USED( state ); check++ ) {
-                    if ( TRIE_LIST_ITEM( state, check ).forid == charid ) {
-                        newstate = TRIE_LIST_ITEM( state, check ).newstate;
-                        break;
-                    }
-               }
-               if ( ! newstate ) {
-                   newstate = next_alloc++;
-                   TRIE_LIST_PUSH( state, charid, newstate );
-                   transcount++;
+                   charid--;
+                   if ( !trie->states[ state ].trans.list ) {
+                       TRIE_LIST_NEW( state );
+                   }
+                   for ( check = 1; check <= TRIE_LIST_USED( state ); check++ ) {
+                       if ( TRIE_LIST_ITEM( state, check ).forid == charid ) {
+                           newstate = TRIE_LIST_ITEM( state, check ).newstate;
+                           break;
+                       }
+                   }
+                   if ( ! newstate ) {
+                       newstate = next_alloc++;
+                       TRIE_LIST_PUSH( state, charid, newstate );
+                       transcount++;
+                   }
+                   state = newstate;
+               } else {
+                   Perl_croak( aTHX_ "panic! In trie construction, no char mapping for %"IVdf, uvc );
                }
-               state = newstate;
-            } else {
-                Perl_croak( aTHX_ "panic! In trie construction, no char mapping for %"IVdf, uvc );
-            }
-            /* charid is now 0 if we dont know the char read, or nonzero if we do */
-        }
+               /* charid is now 0 if we dont know the char read, or nonzero if we do */
+           }
 
-        if ( !trie->states[ state ].wordnum ) {
-            /* we havent inserted this word into the structure yet. */
-            trie->states[ state ].wordnum = ++curword;
+           if ( !trie->states[ state ].wordnum ) {
+               /* we havent inserted this word into the structure yet. */
+               trie->states[ state ].wordnum = ++curword;
 
-            DEBUG_r({
-                /* store the word for dumping */
-                SV* tmp = newSVpvn( STRING( noper ), STR_LEN( noper ) );
-                if ( UTF ) SvUTF8_on( tmp );
-                av_push( trie->words, tmp );
-            });
+               DEBUG_r({
+                   /* store the word for dumping */
+                   SV* tmp = newSVpvn( STRING( noper ), STR_LEN( noper ) );
+                   if ( UTF ) SvUTF8_on( tmp );
+                   av_push( trie->words, tmp );
+               });
 
-        } else {
-            /* Its a dupe. So ignore it. */
-        }
+           } else {
+               /*EMPTY*/;   /* It's a dupe. So ignore it. */
+           }
 
         } /* end second pass */
 
@@ -1100,11 +1078,12 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
                    U16 idx;
 
                     for( idx = 2 ; idx <= TRIE_LIST_USED( state ) ; idx++ ) {
-                        if ( TRIE_LIST_ITEM( state, idx).forid < minid ) {
-                            minid=TRIE_LIST_ITEM( state, idx).forid;
-                        } else if ( TRIE_LIST_ITEM( state, idx).forid > maxid ) {
-                            maxid=TRIE_LIST_ITEM( state, idx).forid;
-                        }
+                       const U16 forid = TRIE_LIST_ITEM( state, idx).forid;
+                       if ( forid < minid ) {
+                           minid=forid;
+                       } else if ( forid > maxid ) {
+                           maxid=forid;
+                       }
                     }
                     if ( transcount < tp + maxid - minid + 1) {
                         transcount *= 2;
@@ -1131,7 +1110,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
                         }
                     } else {
                         for ( idx=1; idx <= TRIE_LIST_USED( state ) ; idx++ ) {
-                            U32 tid = base -  trie->uniquecharcount + TRIE_LIST_ITEM( state, idx ).forid;
+                            const U32 tid = base -  trie->uniquecharcount + TRIE_LIST_ITEM( state, idx ).forid;
                             trie->trans[ tid ].next = TRIE_LIST_ITEM( state, idx ).newstate;
                             trie->trans[ tid ].check = state;
                         }
@@ -1192,7 +1171,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
 
         for ( cur = first ; cur < last ; cur = regnext( cur ) ) {
 
-            regnode *noper   = NEXTOPER( cur );
+           regnode * const noper   = NEXTOPER( cur );
            const U8 *uc     = (U8*)STRING( noper );
            const U8 * const e = uc + STR_LEN( noper );
 
@@ -1213,13 +1192,8 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
                 if ( uvc < 256 ) {
                     charid = trie->charmap[ uvc ];
                 } else {
-                    SV** svpp=(SV**)NULL;
-                    svpp = hv_fetch( trie->widecharmap, (char*)&uvc, sizeof( UV ), 0);
-                    if ( !svpp ) {
-                        charid = 0;
-                    } else {
-                        charid=(U16)SvIV( *svpp );
-                    }
+                   SV* const * const svpp = hv_fetch( trie->widecharmap, (char*)&uvc, sizeof( UV ), 0);
+                   charid = svpp ? (U16)SvIV(*svpp) : 0;
                 }
                 if ( charid ) {
                     charid--;
@@ -1248,7 +1222,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
                 });
 
             } else {
-                /* Its a dupe. So ignore it. */
+               /*EMPTY*/;  /* Its a dupe. So ignore it. */
             }
 
         } /* end second pass */
@@ -1540,11 +1514,13 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
 
 
 STATIC I32
-S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32 flags, U32 depth)
+S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap,
+                       regnode *last, scan_data_t *data, U32 flags, U32 depth)
                        /* scanp: Start here (read-write). */
                        /* deltap: Write maxlen-minlen here. */
                        /* last: Stop before this one. */
 {
+    dVAR;
     I32 min = 0, pars = 0, code;
     regnode *scan = *scanp, *next;
     I32 delta = 0;
@@ -1560,8 +1536,8 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
     while (scan && OP(scan) != END && scan < last) {
        /* Peephole optimizer: */
        DEBUG_OPTIMISE_r({
-         SV *mysv=sv_newmortal();
-         regprop( mysv, scan);
+         SV * const mysv=sv_newmortal();
+         regprop(RExC_rx, mysv, scan);
          PerlIO_printf(Perl_debug_log, "%*speep: %s (0x%08"UVXf")\n",
            (int)depth*2, "", SvPV_nolen_const(mysv), PTR2UV(scan));
        });
@@ -1594,7 +1570,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                }
                else if (stringok) {
                    const int oldl = STR_LEN(scan);
-                   regnode *nnext = regnext(n);
+                   regnode * const nnext = regnext(n);
 
                    if (oldl + STR_LEN(n) > U8_MAX)
                        break;
@@ -1639,9 +1615,10 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
    another valid sequence of UTF-8 bytes.
 
 */
-                char *s0 = STRING(scan), *s, *t;
-                char *s1 = s0 + STR_LEN(scan) - 1, *s2 = s1 - 4;
-                const char * const t0 = "\xcc\x88\xcc\x81";
+                char * const s0 = STRING(scan), *s, *t;
+                char * const s1 = s0 + STR_LEN(scan) - 1;
+                char * const s2 = s1 - 4;
+                const char t0[] = "\xcc\x88\xcc\x81";
                 const char * const t1 = t0 + 3;
 
                 for (s = s0 + 2;
@@ -1702,7 +1679,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
            if (OP(next) == code || code == IFTHEN || code == SUSPEND) {
                I32 max1 = 0, min1 = I32_MAX, num = 0;
                struct regnode_charclass_class accum;
-               regnode *startbranch=scan;
+               regnode * const startbranch=scan;
                
                if (flags & SCF_DO_SUBSTR) /* XXXX Add !SUSPEND? */
                    scan_commit(pRExC_state, data); /* Cannot merge strings after this. */
@@ -1839,7 +1816,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                         U32 count=0;
 
 #ifdef DEBUGGING
-                        SV *mysv = sv_newmortal();       /* for dumping */
+                        SV * const mysv = sv_newmortal();       /* for dumping */
 #endif
                         /* var tail is used because there may be a TAIL
                            regop in the way. Ie, the exacts will point to the
@@ -1855,7 +1832,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                         }
 
                         DEBUG_OPTIMISE_r({
-                            regprop( mysv, tail );
+                            regprop(RExC_rx, mysv, tail );
                             PerlIO_printf( Perl_debug_log, "%*s%s%s%s\n",
                                 (int)depth * 2 + 2, "", "Tail node is:", SvPV_nolen_const( mysv ),
                                 (RExC_seen_evals) ? "[EVAL]" : ""
@@ -1888,20 +1865,20 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
 
                         /* dont use tail as the end marker for this traverse */
                         for ( cur = startbranch ; cur != scan ; cur = regnext( cur ) ) {
-                            regnode *noper = NEXTOPER( cur );
-                            regnode *noper_next = regnext( noper );
+                            regnode * const noper = NEXTOPER( cur );
+                            regnode * const noper_next = regnext( noper );
 
                             DEBUG_OPTIMISE_r({
-                                regprop( mysv, cur);
+                                regprop(RExC_rx, mysv, cur);
                                 PerlIO_printf( Perl_debug_log, "%*s%s",
                                    (int)depth * 2 + 2,"  ", SvPV_nolen_const( mysv ) );
 
-                                regprop( mysv, noper);
+                                regprop(RExC_rx, mysv, noper);
                                 PerlIO_printf( Perl_debug_log, " -> %s",
                                     SvPV_nolen_const(mysv));
 
                                 if ( noper_next ) {
-                                  regprop( mysv, noper_next );
+                                  regprop(RExC_rx, mysv, noper_next );
                                   PerlIO_printf( Perl_debug_log,"\t=> %s\t",
                                     SvPV_nolen_const(mysv));
                                 }
@@ -1919,20 +1896,20 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                                 } else {
                                     DEBUG_OPTIMISE_r(
                                         if (!last ) {
-                                            regprop( mysv, first);
+                                            regprop(RExC_rx, mysv, first);
                                             PerlIO_printf( Perl_debug_log, "%*s%s",
                                               (int)depth * 2 + 2, "F:", SvPV_nolen_const( mysv ) );
-                                            regprop( mysv, NEXTOPER(first) );
+                                            regprop(RExC_rx, mysv, NEXTOPER(first) );
                                             PerlIO_printf( Perl_debug_log, " -> %s\n",
                                               SvPV_nolen_const( mysv ) );
                                         }
                                     );
                                     last = cur;
                                     DEBUG_OPTIMISE_r({
-                                        regprop( mysv, cur);
+                                        regprop(RExC_rx, mysv, cur);
                                         PerlIO_printf( Perl_debug_log, "%*s%s",
                                           (int)depth * 2 + 2, "N:", SvPV_nolen_const( mysv ) );
-                                        regprop( mysv, noper );
+                                        regprop(RExC_rx, mysv, noper );
                                         PerlIO_printf( Perl_debug_log, " -> %s\n",
                                           SvPV_nolen_const( mysv ) );
                                     });
@@ -1960,7 +1937,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                             }
                         }
                         DEBUG_OPTIMISE_r({
-                            regprop( mysv, cur);
+                            regprop(RExC_rx, mysv, cur);
                             PerlIO_printf( Perl_debug_log,
                               "%*s%s\t(0x%p,0x%p,0x%p)\n", (int)depth * 2 + 2,
                               "  ", SvPV_nolen_const( mysv ), first, last, cur);
@@ -1984,11 +1961,13 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
        }
        else if (OP(scan) == EXACT) {
            I32 l = STR_LEN(scan);
-           UV uc = *((U8*)STRING(scan));
+           UV uc;
            if (UTF) {
                const U8 * const s = (U8*)STRING(scan);
                l = utf8_length(s, s + l);
                uc = utf8_to_uvchr(s, NULL);
+           } else {
+               uc = *((U8*)STRING(scan));
            }
            min += l;
            if (flags & SCF_DO_SUBSTR) { /* Update longest substr. */
@@ -2000,16 +1979,16 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                        ? I32_MAX : data->pos_min + data->pos_delta;
                }
                sv_catpvn(data->last_found, STRING(scan), STR_LEN(scan));
+               if (UTF)
+                   SvUTF8_on(data->last_found);
                {
-                   SV * sv = data->last_found;
+                   SV * const sv = data->last_found;
                    MAGIC * const mg = SvUTF8(sv) && SvMAGICAL(sv) ?
                        mg_find(sv, PERL_MAGIC_utf8) : NULL;
                    if (mg && mg->mg_len >= 0)
                        mg->mg_len += utf8_length((U8*)STRING(scan),
                                                  (U8*)STRING(scan)+STR_LEN(scan));
                }
-               if (UTF)
-                   SvUTF8_on(data->last_found);
                data->last_end = data->pos_min + l;
                data->pos_min += l; /* As in the first entry. */
                data->flags &= ~SF_BEFORE_EOL;
@@ -2049,15 +2028,17 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
            UV uc = *((U8*)STRING(scan));
 
            /* Search for fixed substrings supports EXACT only. */
-           if (flags & SCF_DO_SUBSTR)
+           if (flags & SCF_DO_SUBSTR) {
+               assert(data);
                scan_commit(pRExC_state, data);
+           }
            if (UTF) {
-               U8 *s = (U8 *)STRING(scan);
+               const U8 * const s = (U8 *)STRING(scan);
                l = utf8_length(s, s + l);
                uc = utf8_to_uvchr(s, NULL);
            }
            min += l;
-           if (data && (flags & SCF_DO_SUBSTR))
+           if (flags & SCF_DO_SUBSTR)
                data->pos_min += l;
            if (flags & SCF_DO_STCLASS_AND) {
                /* Check whether it is compatible with what we know already! */
@@ -2093,7 +2074,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
        else if (strchr((const char*)PL_varies,OP(scan))) {
            I32 mincount, maxcount, minnext, deltanext, fl = 0;
            I32 f = flags, pos_before = 0;
-           regnode *oscan = scan;
+           regnode * const oscan = scan;
            struct regnode_charclass_class this_class;
            struct regnode_charclass_class *oclass = NULL;
            I32 next_is_eval = 0;
@@ -2227,7 +2208,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                      && !deltanext && minnext == 1 ) {
                    /* Try to optimize to CURLYN.  */
                    regnode *nxt = NEXTOPER(oscan) + EXTRA_STEP_2ARGS;
-                   regnode *nxt1 = nxt;
+                   regnode * const nxt1 = nxt;
 #ifdef DEBUGGING
                    regnode *nxt2;
 #endif
@@ -2333,7 +2314,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                if (data && fl & (SF_HAS_PAR|SF_IN_PAR))
                    pars++;
                if (flags & SCF_DO_SUBSTR) {
-                   SV *last_str = Nullsv;
+                   SV *last_str = NULL;
                    int counted = mincount != 0;
 
                    if (data->last_end > 0 && mincount != 0) { /* Ends with a string. */
@@ -2356,7 +2337,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                        I32 b = pos_before >= data->last_start_min
                            ? pos_before : data->last_start_min;
                        STRLEN l;
-                       const char *s = SvPV_const(data->last_found, l);
+                       const char * const s = SvPV_const(data->last_found, l);
                        I32 old = b - data->last_start_min;
 #endif
 
@@ -2405,7 +2386,13 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                            the group.  */
                        scan_commit(pRExC_state,data);
                        if (mincount && last_str) {
-                           sv_setsv(data->last_found, last_str);
+                           SV * const sv = data->last_found;
+                           MAGIC * const mg = SvUTF8(sv) && SvMAGICAL(sv) ?
+                               mg_find(sv, PERL_MAGIC_utf8) : NULL;
+
+                           if (mg)
+                               mg->mg_len = -1;
+                           sv_setsv(sv, last_str);
                            data->last_end = data->pos_min;
                            data->last_start_min =
                                data->pos_min - CHR_SVLEN(last_str);
@@ -2747,7 +2734,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
 }
 
 STATIC I32
-S_add_data(pTHX_ RExC_state_t *pRExC_state, I32 n, const char *s)
+S_add_data(RExC_state_t *pRExC_state, I32 n, const char *s)
 {
     if (RExC_rx->data) {
        Renewc(RExC_rx->data,
@@ -2769,6 +2756,7 @@ S_add_data(pTHX_ RExC_state_t *pRExC_state, I32 n, const char *s)
 void
 Perl_reginitcolors(pTHX)
 {
+    dVAR;
     const char * const s = PerlEnv_getenv("PERL_RE_COLORS");
     if (s) {
        char *t = savepv(s);
@@ -2810,6 +2798,7 @@ Perl_reginitcolors(pTHX)
 regexp *
 Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
 {
+    dVAR;
     register regexp *r;
     regnode *scan;
     regnode *first;
@@ -2857,7 +2846,7 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
     REGC((U8)REG_MAGIC, (char*)RExC_emit);
 #endif
     if (reg(pRExC_state, 0, &flags) == NULL) {
-       RExC_precomp = Nullch;
+       RExC_precomp = NULL;
        return(NULL);
     }
     DEBUG_COMPILE_r(PerlIO_printf(Perl_debug_log, "size %"IVdf" ", (IV)RExC_size));
@@ -2886,10 +2875,11 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
     r->precomp = savepvn(RExC_precomp, r->prelen);
     r->subbeg = NULL;
 #ifdef PERL_OLD_COPY_ON_WRITE
-    r->saved_copy = Nullsv;
+    r->saved_copy = NULL;
 #endif
     r->reganch = pm->op_pmflags & PMf_COMPILETIME;
     r->nparens = RExC_npar - 1;        /* set early to validate backrefs */
+    r->lastparen = 0;                  /* mg.c reads this.  */
 
     r->substrs = 0;                    /* Useful during FAIL. */
     r->startp = 0;                     /* Useful during FAIL. */
@@ -2965,7 +2955,7 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
       again:
        if (PL_regkind[(U8)OP(first)] == EXACT) {
            if (OP(first) == EXACT)
-                     /* Empty, get anchored substr later. */
+               /*EMPTY*/;      /* Empty, get anchored substr later. */
            else if ((OP(first) == EXACTF || OP(first) == EXACTFL))
                r->regstclass = first;
        }
@@ -3022,9 +3012,9 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
        */
        minlen = 0;
 
-       data.longest_fixed = newSVpvn("",0);
-       data.longest_float = newSVpvn("",0);
-       data.last_found = newSVpvn("",0);
+       data.longest_fixed = newSVpvs("");
+       data.longest_float = newSVpvs("");
+       data.last_found = newSVpvs("");
        data.longest = &(data.longest_fixed);
        first = scan;
        if (!r->regstclass) {
@@ -3059,10 +3049,10 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
 
            if (SvUTF8(data.longest_float)) {
                r->float_utf8 = data.longest_float;
-               r->float_substr = Nullsv;
+               r->float_substr = NULL;
            } else {
                r->float_substr = data.longest_float;
-               r->float_utf8 = Nullsv;
+               r->float_utf8 = NULL;
            }
            r->float_min_offset = data.offset_float_min;
            r->float_max_offset = data.offset_float_max;
@@ -3073,7 +3063,7 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
        }
        else {
          remove_float:
-           r->float_substr = r->float_utf8 = Nullsv;
+           r->float_substr = r->float_utf8 = NULL;
            SvREFCNT_dec(data.longest_float);
            longest_float_length = 0;
        }
@@ -3087,10 +3077,10 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
 
            if (SvUTF8(data.longest_fixed)) {
                r->anchored_utf8 = data.longest_fixed;
-               r->anchored_substr = Nullsv;
+               r->anchored_substr = NULL;
            } else {
                r->anchored_substr = data.longest_fixed;
-               r->anchored_utf8 = Nullsv;
+               r->anchored_utf8 = NULL;
            }
            r->anchored_offset = data.offset_fixed;
            t = (data.flags & SF_FIX_BEFORE_EOL /* Can't have SEOL and MULTI */
@@ -3099,7 +3089,7 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
            fbm_compile(data.longest_fixed, t ? FBMcf_TAIL : 0);
        }
        else {
-           r->anchored_substr = r->anchored_utf8 = Nullsv;
+           r->anchored_substr = r->anchored_utf8 = NULL;
            SvREFCNT_dec(data.longest_fixed);
            longest_fixed_length = 0;
        }
@@ -3120,9 +3110,8 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
                       struct regnode_charclass_class);
            r->regstclass = (regnode*)RExC_rx->data->data[n];
            r->reganch &= ~ROPT_SKIP;   /* Used in find_byclass(). */
-           PL_regdata = r->data; /* for regprop() */
            DEBUG_COMPILE_r({ SV *sv = sv_newmortal();
-                     regprop(sv, (regnode*)data.start_class);
+                     regprop(r, sv, (regnode*)data.start_class);
                      PerlIO_printf(Perl_debug_log,
                                    "synthetic stclass \"%s\".\n",
                                    SvPVX_const(sv));});
@@ -3163,7 +3152,7 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
        data.last_closep = &last_close;
        minlen = study_chunk(pRExC_state, &scan, &fake, scan + RExC_size, &data, SCF_DO_STCLASS_AND|SCF_WHILEM_VISITED_POS,0);
        r->check_substr = r->check_utf8 = r->anchored_substr = r->anchored_utf8
-               = r->float_substr = r->float_utf8 = Nullsv;
+               = r->float_substr = r->float_utf8 = NULL;
        if (!(data.start_class->flags & ANYOF_EOS)
            && !cl_is_anything(data.start_class))
        {
@@ -3177,7 +3166,7 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
            r->regstclass = (regnode*)RExC_rx->data->data[n];
            r->reganch &= ~ROPT_SKIP;   /* Used in find_byclass(). */
            DEBUG_COMPILE_r({ SV* sv = sv_newmortal();
-                     regprop(sv, (regnode*)data.start_class);
+                     regprop(r, sv, (regnode*)data.start_class);
                      PerlIO_printf(Perl_debug_log,
                                    "synthetic stclass \"%s\".\n",
                                    SvPVX_const(sv));});
@@ -3195,7 +3184,6 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
        r->reganch |= ROPT_CANY_SEEN;
     Newxz(r->startp, RExC_npar, I32);
     Newxz(r->endp, RExC_npar, I32);
-    PL_regdata = r->data; /* for regprop() */
     DEBUG_COMPILE_r(regdump(r));
     return(r);
 }
@@ -3217,22 +3205,24 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
     register regnode *ret;             /* Will be the head of the group. */
     register regnode *br;
     register regnode *lastbr;
-    register regnode *ender = 0;
+    register regnode *ender = NULL;
     register I32 parno = 0;
-    I32 flags, oregflags = RExC_flags, have_branch = 0, open = 0;
+    I32 flags;
+    const I32 oregflags = RExC_flags;
+    bool have_branch = 0;
+    bool is_open = 0;
 
     /* for (?g), (?gc), and (?o) warnings; warning
        about (?c) will warn about (?g) -- japhy    */
 
-    I32 wastedflags = 0x00,
-        wasted_o    = 0x01,
-        wasted_g    = 0x02,
-        wasted_gc   = 0x02 | 0x04,
-        wasted_c    = 0x04;
+#define WASTED_O  0x01
+#define WASTED_G  0x02
+#define WASTED_C  0x04
+#define WASTED_GC (0x02|0x04)
+    I32 wastedflags = 0x00;
 
     char * parse_start = RExC_parse; /* MJD */
     char * const oregcomp_parse = RExC_parse;
-    char c;
 
     *flagp = 0;                                /* Tentatively. */
 
@@ -3242,7 +3232,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
        if (*RExC_parse == '?') { /* (?...) */
            U32 posflags = 0, negflags = 0;
            U32 *flagsp = &posflags;
-           int logical = 0;
+           bool is_logical = 0;
            const char * const seqstart = RExC_parse;
 
            RExC_parse++;
@@ -3279,7 +3269,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
                    vWARNdep(RExC_parse, "(?p{}) is deprecated - use (??{})");
                /* FALL THROUGH*/
            case '?':           /* (??...) */
-               logical = 1;
+               is_logical = 1;
                if (*RExC_parse != '{')
                    goto unknown;
                paren = *RExC_parse++;
@@ -3289,32 +3279,28 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
                I32 count = 1, n = 0;
                char c;
                char *s = RExC_parse;
-               SV *sv;
-               OP_4tree *sop, *rop;
 
                RExC_seen_zerolen++;
                RExC_seen |= REG_SEEN_EVAL;
                while (count && (c = *RExC_parse)) {
-                   if (c == '\\' && RExC_parse[1])
-                       RExC_parse++;
+                   if (c == '\\') {
+                       if (RExC_parse[1])
+                           RExC_parse++;
+                   }
                    else if (c == '{')
                        count++;
                    else if (c == '}')
                        count--;
                    RExC_parse++;
                }
-               if (*RExC_parse != ')')
-               {
+               if (*RExC_parse != ')') {
                    RExC_parse = s;             
                    vFAIL("Sequence (?{...}) not terminated or not {}-balanced");
                }
                if (!SIZE_ONLY) {
                    PAD *pad;
-               
-                   if (RExC_parse - 1 - s)
-                       sv = newSVpvn(s, RExC_parse - 1 - s);
-                   else
-                       sv = newSVpvn("", 0);
+                   OP_4tree *sop, *rop;
+                   SV * const sv = newSVpvn(s, RExC_parse - 1 - s);
 
                    ENTER;
                    Perl_save_re_context(aTHX);
@@ -3343,7 +3329,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
                }
 
                nextchar(pRExC_state);
-               if (logical) {
+               if (is_logical) {
                    ret = reg_node(pRExC_state, LOGICAL);
                    if (!SIZE_ONLY)
                        ret->flags = 2;
@@ -3373,6 +3359,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
                }
                else if (RExC_parse[0] >= '1' && RExC_parse[0] <= '9' ) {
                     /* (?(1)...) */
+                   char c;
                    parno = atoi(RExC_parse++);
 
                    while (isDIGIT(*RExC_parse))
@@ -3430,7 +3417,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
 
                    if (*RExC_parse == 'o' || *RExC_parse == 'g') {
                        if (SIZE_ONLY && ckWARN(WARN_REGEXP)) {
-                           I32 wflagbit = *RExC_parse == 'o' ? wasted_o : wasted_g;
+                           const I32 wflagbit = *RExC_parse == 'o' ? WASTED_O : WASTED_G;
                            if (! (wastedflags & wflagbit) ) {
                                wastedflags |= wflagbit;
                                vWARN5(
@@ -3446,8 +3433,8 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
                    }
                    else if (*RExC_parse == 'c') {
                        if (SIZE_ONLY && ckWARN(WARN_REGEXP)) {
-                           if (! (wastedflags & wasted_c) ) {
-                               wastedflags |= wasted_gc;
+                           if (! (wastedflags & WASTED_C) ) {
+                               wastedflags |= WASTED_GC;
                                vWARN3(
                                    RExC_parse + 1,
                                    "Useless (%sc) - %suse /gc modifier",
@@ -3490,7 +3477,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
            ret = reganode(pRExC_state, OPEN, parno);
             Set_Node_Length(ret, 1); /* MJD */
             Set_Node_Offset(ret, RExC_parse); /* MJD */
-           open = 1;
+           is_open = 1;
        }
     }
     else                        /* ! paren */
@@ -3519,7 +3506,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
     else if (paren == ':') {
        *flagp |= flags&SIMPLE;
     }
-    if (open) {                                /* Starts with OPEN. */
+    if (is_open) {                             /* Starts with OPEN. */
        regtail(pRExC_state, ret, br);          /* OPEN -> first. */
     }
     else if (paren != '?')             /* Not Conditional */
@@ -3626,6 +3613,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
 STATIC regnode *
 S_regbranch(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, I32 first)
 {
+    dVAR;
     register regnode *ret;
     register regnode *chain = NULL;
     register regnode *latest;
@@ -3678,7 +3666,7 @@ S_regbranch(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, I32 first)
        *flagp |= flags&SIMPLE;
     }
 
-    return(ret);
+    return ret;
 }
 
 /*
@@ -3693,6 +3681,7 @@ S_regbranch(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, I32 first)
 STATIC regnode *
 S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp)
 {
+    dVAR;
     register regnode *ret;
     register char op;
     register char *next;
@@ -3715,7 +3704,7 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp)
     if (op == '{' && regcurly(RExC_parse)) {
         parse_start = RExC_parse; /* MJD */
        next = RExC_parse + 1;
-       maxpos = Nullch;
+       maxpos = NULL;
        while (isDIGIT(*next) || *next == ',') {
            if (*next == ',') {
                if (maxpos)
@@ -3841,7 +3830,7 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp)
     if (!SIZE_ONLY && !(flags&HASWIDTH) && max > REG_INFTY/3 && ckWARN(WARN_REGEXP)) {
        vWARN3(RExC_parse,
               "%.*s matches null string many times",
-              RExC_parse - origparse,
+              (int)(RExC_parse >= origparse ? RExC_parse - origparse : 0),
               origparse);
     }
 
@@ -3870,7 +3859,8 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp)
 STATIC regnode *
 S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp)
 {
-    register regnode *ret = 0;
+    dVAR;
+    register regnode *ret = NULL;
     I32 flags;
     char *parse_start = RExC_parse;
 
@@ -4285,7 +4275,7 @@ tryagain:
                    if (UTF8_IS_START(*p) && UTF) {
                        STRLEN numlen;
                        ender = utf8n_to_uvchr((U8*)p, RExC_end - p,
-                                              &numlen, 0);
+                                              &numlen, UTF8_ALLOW_DEFAULT);
                        p += numlen;
                    }
                    else
@@ -4430,7 +4420,7 @@ tryagain:
 }
 
 STATIC char *
-S_regwhite(pTHX_ char *p, const char *e)
+S_regwhite(char *p, const char *e)
 {
     while (p < e) {
        if (isSPACE(*p))
@@ -4459,13 +4449,14 @@ S_regwhite(pTHX_ char *p, const char *e)
 STATIC I32
 S_regpposixcc(pTHX_ RExC_state_t *pRExC_state, I32 value)
 {
+    dVAR;
     I32 namedclass = OOB_NAMEDCLASS;
 
     if (value == '[' && RExC_parse + 1 < RExC_end &&
        /* I smell either [: or [= or [. -- POSIX has been here, right? */
        POSIXCC(UCHARAT(RExC_parse))) {
        const char c = UCHARAT(RExC_parse);
-       char* s = RExC_parse++;
+       char* const s = RExC_parse++;
        
        while (RExC_parse < RExC_end && UCHARAT(RExC_parse) != c)
            RExC_parse++;
@@ -4618,6 +4609,7 @@ S_regpposixcc(pTHX_ RExC_state_t *pRExC_state, I32 value)
 STATIC void
 S_checkposixcc(pTHX_ RExC_state_t *pRExC_state)
 {
+    dVAR;
     if (!SIZE_ONLY && POSIXCC(UCHARAT(RExC_parse))) {
        const char *s = RExC_parse;
        const char  c = *s++;
@@ -4645,6 +4637,7 @@ S_checkposixcc(pTHX_ RExC_state_t *pRExC_state)
 STATIC regnode *
 S_regclass(pTHX_ RExC_state_t *pRExC_state)
 {
+    dVAR;
     register UV value;
     register UV nextvalue;
     register IV prevvalue = OOB_UNICODE;
@@ -4652,13 +4645,13 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
     register regnode *ret;
     STRLEN numlen;
     IV namedclass;
-    char *rangebegin = 0;
+    char *rangebegin = NULL;
     bool need_class = 0;
-    SV *listsv = Nullsv;
+    SV *listsv = NULL;
     register char *e;
     UV n;
     bool optimize_invert   = TRUE;
-    AV* unicode_alternate  = 0;
+    AV* unicode_alternate  = NULL;
 #ifdef EBCDIC
     UV literal_endpoint = 0;
 #endif
@@ -4675,8 +4668,10 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
            ANYOF_FLAGS(ret) |= ANYOF_INVERT;
     }
 
-    if (SIZE_ONLY)
+    if (SIZE_ONLY) {
        RExC_size += ANYOF_SKIP;
+       listsv = &PL_sv_undef; /* For code scanners: listsv always non-NULL. */
+    }
     else {
        RExC_emit += ANYOF_SKIP;
        if (FOLD)
@@ -4684,7 +4679,7 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
        if (LOC)
            ANYOF_FLAGS(ret) |= ANYOF_LOCALE;
        ANYOF_BITMAP_ZERO(ret);
-       listsv = newSVpvn("# comment\n", 10);
+       listsv = newSVpvs("# comment\n");
     }
 
     nextvalue = RExC_parse < RExC_end ? UCHARAT(RExC_parse) : 0;
@@ -4707,7 +4702,7 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
        if (UTF) {
            value = utf8n_to_uvchr((U8*)RExC_parse,
                                   RExC_end - RExC_parse,
-                                  &numlen, 0);
+                                  &numlen, UTF8_ALLOW_DEFAULT);
            RExC_parse += numlen;
        }
        else
@@ -4719,7 +4714,7 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
            if (UTF) {
                value = utf8n_to_uvchr((U8*)RExC_parse,
                                   RExC_end - RExC_parse,
-                                  &numlen, 0);
+                                  &numlen, UTF8_ALLOW_DEFAULT);
                RExC_parse += numlen;
            }
            else
@@ -4767,12 +4762,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                              n--;
                         }
                    }
-                   if (value == 'p')
-                        Perl_sv_catpvf(aTHX_ listsv,
-                                       "+utf8::%.*s\n", (int)n, RExC_parse);
-                   else
-                        Perl_sv_catpvf(aTHX_ listsv,
-                                       "!utf8::%.*s\n", (int)n, RExC_parse);
+                   Perl_sv_catpvf(aTHX_ listsv, "%cutf8::%.*s\n",
+                       (value=='p' ? '+' : '!'), (int)n, RExC_parse);
                }
                RExC_parse = e + 1;
                ANYOF_FLAGS(ret) |= ANYOF_UNICODE;
@@ -4840,12 +4831,14 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
            /* a bad range like a-\d, a-[:digit:] ? */
            if (range) {
                if (!SIZE_ONLY) {
-                   if (ckWARN(WARN_REGEXP))
+                   if (ckWARN(WARN_REGEXP)) {
+                       const int w =
+                           RExC_parse >= rangebegin ?
+                           RExC_parse - rangebegin : 0;
                        vWARN4(RExC_parse,
                               "False [] range \"%*.*s\"",
-                              RExC_parse - rangebegin,
-                              RExC_parse - rangebegin,
-                              rangebegin);
+                              w, w, rangebegin);
+                   }
                    if (prevvalue < 256) {
                        ANYOF_BITMAP_SET(ret, prevvalue);
                        ANYOF_BITMAP_SET(ret, '-');
@@ -5234,10 +5227,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
 
        if (range) {
            if (prevvalue > (IV)value) /* b-a */ {
-               Simple_vFAIL4("Invalid [] range \"%*.*s\"",
-                             RExC_parse - rangebegin,
-                             RExC_parse - rangebegin,
-                             rangebegin);
+               const int w = RExC_parse - rangebegin;
+               Simple_vFAIL4("Invalid [] range \"%*.*s\"", w, w, rangebegin);
                range = 0; /* not a valid range */
            }
        }
@@ -5249,12 +5240,14 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
 
                /* a bad range like \w-, [:word:]- ? */
                if (namedclass > OOB_NAMEDCLASS) {
-                   if (ckWARN(WARN_REGEXP))
+                   if (ckWARN(WARN_REGEXP)) {
+                       const int w =
+                           RExC_parse >= rangebegin ?
+                           RExC_parse - rangebegin : 0;
                        vWARN4(RExC_parse,
                               "False [] range \"%*.*s\"",
-                              RExC_parse - rangebegin,
-                              RExC_parse - rangebegin,
-                              rangebegin);
+                              w, w, rangebegin);
+                   }
                    if (!SIZE_ONLY)
                        ANYOF_BITMAP_SET(ret, '-');
                } else
@@ -5397,7 +5390,7 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
     }
 
     if (!SIZE_ONLY) {
-       AV *av = newAV();
+       AV * const av = newAV();
        SV *rv;
 
        /* The 0th element stores the character class description
@@ -5421,7 +5414,7 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
 STATIC char*
 S_nextchar(pTHX_ RExC_state_t *pRExC_state)
 {
-    char* retval = RExC_parse++;
+    char* const retval = RExC_parse++;
 
     for (;;) {
        if (*RExC_parse == '(' && RExC_parse[1] == '?' &&
@@ -5455,6 +5448,7 @@ S_nextchar(pTHX_ RExC_state_t *pRExC_state)
 STATIC regnode *                       /* Location. */
 S_reg_node(pTHX_ RExC_state_t *pRExC_state, U8 op)
 {
+    dVAR;
     register regnode *ptr;
     regnode * const ret = RExC_emit;
 
@@ -5490,6 +5484,7 @@ S_reg_node(pTHX_ RExC_state_t *pRExC_state, U8 op)
 STATIC regnode *                       /* Location. */
 S_reganode(pTHX_ RExC_state_t *pRExC_state, U8 op, U32 arg)
 {
+    dVAR;
     register regnode *ptr;
     regnode * const ret = RExC_emit;
 
@@ -5526,6 +5521,7 @@ S_reganode(pTHX_ RExC_state_t *pRExC_state, U8 op, U32 arg)
 STATIC void
 S_reguni(pTHX_ const RExC_state_t *pRExC_state, UV uv, char* s, STRLEN* lenp)
 {
+    dVAR;
     *lenp = SIZE_ONLY ? UNISKIP(uv) : (uvchr_to_utf8((U8*)s, uv) - (U8*)s);
 }
 
@@ -5537,6 +5533,7 @@ S_reguni(pTHX_ const RExC_state_t *pRExC_state, UV uv, char* s, STRLEN* lenp)
 STATIC void
 S_reginsert(pTHX_ RExC_state_t *pRExC_state, U8 op, regnode *opnd)
 {
+    dVAR;
     register regnode *src;
     register regnode *dst;
     register regnode *place;
@@ -5592,9 +5589,11 @@ S_reginsert(pTHX_ RExC_state_t *pRExC_state, U8 op, regnode *opnd)
 /*
 - regtail - set the next-pointer at the end of a node chain of p to val.
 */
+/* TODO: All three parms should be const */
 STATIC void
-S_regtail(pTHX_ RExC_state_t *pRExC_state, regnode *p, regnode *val)
+S_regtail(pTHX_ const RExC_state_t *pRExC_state, regnode *p, const regnode *val)
 {
+    dVAR;
     register regnode *scan;
 
     if (SIZE_ONLY)
@@ -5620,9 +5619,11 @@ S_regtail(pTHX_ RExC_state_t *pRExC_state, regnode *p, regnode *val)
 /*
 - regoptail - regtail on operand of first argument; nop if operandless
 */
+/* TODO: All three parms should be const */
 STATIC void
-S_regoptail(pTHX_ RExC_state_t *pRExC_state, regnode *p, regnode *val)
+S_regoptail(pTHX_ const RExC_state_t *pRExC_state, regnode *p, const regnode *val)
 {
+    dVAR;
     /* "Operandless" and "op != BRANCH" are synonymous in practice. */
     if (p == NULL || SIZE_ONLY)
        return;
@@ -5640,7 +5641,7 @@ S_regoptail(pTHX_ RExC_state_t *pRExC_state, regnode *p, regnode *val)
  - regcurly - a little FSA that accepts {\d+,?\d*}
  */
 STATIC I32
-S_regcurly(pTHX_ register const char *s)
+S_regcurly(register const char *s)
 {
     if (*s++ != '{')
        return FALSE;
@@ -5662,12 +5663,13 @@ S_regcurly(pTHX_ register const char *s)
  - regdump - dump a regexp onto Perl_debug_log in vaguely comprehensible form
  */
 void
-Perl_regdump(pTHX_ regexp *r)
+Perl_regdump(pTHX_ const regexp *r)
 {
 #ifdef DEBUGGING
-    SV *sv = sv_newmortal();
+    dVAR;
+    SV * const sv = sv_newmortal();
 
-    (void)dumpuntil(r->program, r->program + 1, NULL, sv, 0);
+    (void)dumpuntil(r, r->program, r->program + 1, NULL, sv, 0);
 
     /* Header fields of interest. */
     if (r->anchored_substr)
@@ -5719,7 +5721,7 @@ Perl_regdump(pTHX_ regexp *r)
        PerlIO_printf(Perl_debug_log, ") ");
 
     if (r->regstclass) {
-       regprop(sv, r->regstclass);
+       regprop(r, sv, r->regstclass);
        PerlIO_printf(Perl_debug_log, "stclass \"%s\" ", SvPVX_const(sv));
     }
     if (r->reganch & ROPT_ANCH) {
@@ -5756,6 +5758,9 @@ Perl_regdump(pTHX_ regexp *r)
            PerlIO_printf(Perl_debug_log, "\n");
         });
     }
+#else
+    PERL_UNUSED_CONTEXT;
+    PERL_UNUSED_ARG(r);
 #endif /* DEBUGGING */
 }
 
@@ -5763,9 +5768,10 @@ Perl_regdump(pTHX_ regexp *r)
 - regprop - printable representation of opcode
 */
 void
-Perl_regprop(pTHX_ SV *sv, const regnode *o)
+Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o)
 {
 #ifdef DEBUGGING
+    dVAR;
     register int k;
 
     sv_setpvn(sv, "", 0);
@@ -5778,12 +5784,12 @@ Perl_regprop(pTHX_ SV *sv, const regnode *o)
     k = PL_regkind[(U8)OP(o)];
 
     if (k == EXACT) {
-        SV *dsv = sv_2mortal(newSVpvn("", 0));
+       SV * const dsv = sv_2mortal(newSVpvs(""));
        /* Using is_utf8_string() is a crude hack but it may
         * be the best for now since we have no flag "this EXACTish
         * node was UTF-8" --jhi */
        const bool do_utf8 = is_utf8_string((U8*)STRING(o), STR_LEN(o));
-       const char *s = do_utf8 ?
+       const char * const s = do_utf8 ?
          pv_uni_display(dsv, (U8*)STRING(o), STR_LEN(o), 60,
                         UNI_DISPLAY_REGEX) :
          STRING(o);
@@ -5794,17 +5800,10 @@ Perl_regprop(pTHX_ SV *sv, const regnode *o)
                       PL_colors[0],
                       len, s,
                       PL_colors[1]);
-    } else if (k == TRIE) {/*
-       this isn't always safe, as Pl_regdata may not be for this regex yet
-       (depending on where its called from) so its being moved to dumpuntil
-       I32 n = ARG(o);
-       reg_trie_data *trie=(reg_trie_data*)PL_regdata->data[n];
-       Perl_sv_catpvf(aTHX_ sv, " (W:%d L:%d C:%d S:%d)",
-                      trie->wordcount,
-                      trie->charcount,
-                      trie->uniquecharcount,
-                      trie->laststate);
-       */
+    } else if (k == TRIE) {
+       /*EMPTY*/;
+       /* print the details od the trie in dumpuntil instead, as
+        * prog->data isn't available here */
     } else if (k == CURLY) {
        if (OP(o) == CURLYM || OP(o) == CURLYN || OP(o) == CURLYX)
            Perl_sv_catpvf(aTHX_ sv, "[%d]", o->flags); /* Parenth number */
@@ -5818,9 +5817,10 @@ Perl_regprop(pTHX_ SV *sv, const regnode *o)
        Perl_sv_catpvf(aTHX_ sv, "[%d]", o->flags);     /* 2: embedded, otherwise 1 */
     else if (k == ANYOF) {
        int i, rangestart = -1;
-       U8 flags = ANYOF_FLAGS(o);
-       const char * const anyofs[] = { /* Should be synchronized with
-                                        * ANYOF_ #xdefines in regcomp.h */
+       const U8 flags = ANYOF_FLAGS(o);
+
+       /* Should be synchronized with * ANYOF_ #xdefines in regcomp.h */
+       static const char * const anyofs[] = {
            "\\w",
            "\\W",
            "\\s",
@@ -5854,12 +5854,12 @@ Perl_regprop(pTHX_ SV *sv, const regnode *o)
        };
 
        if (flags & ANYOF_LOCALE)
-           sv_catpv(sv, "{loc}");
+           sv_catpvs(sv, "{loc}");
        if (flags & ANYOF_FOLD)
-           sv_catpv(sv, "{i}");
+           sv_catpvs(sv, "{i}");
        Perl_sv_catpvf(aTHX_ sv, "[%s", PL_colors[0]);
        if (flags & ANYOF_INVERT)
-           sv_catpv(sv, "^");
+           sv_catpvs(sv, "^");
        for (i = 0; i <= 256; i++) {
            if (i < 256 && ANYOF_BITMAP_TEST(o,i)) {
                if (rangestart == -1)
@@ -5870,7 +5870,7 @@ Perl_regprop(pTHX_ SV *sv, const regnode *o)
                        put_byte(sv, rangestart);
                else {
                    put_byte(sv, rangestart);
-                   sv_catpv(sv, "-");
+                   sv_catpvs(sv, "-");
                    put_byte(sv, i - 1);
                }
                rangestart = -1;
@@ -5883,13 +5883,13 @@ Perl_regprop(pTHX_ SV *sv, const regnode *o)
                    sv_catpv(sv, anyofs[i]);
 
        if (flags & ANYOF_UNICODE)
-           sv_catpv(sv, "{unicode}");
+           sv_catpvs(sv, "{unicode}");
        else if (flags & ANYOF_UNICODE_ALL)
-           sv_catpv(sv, "{unicode_all}");
+           sv_catpvs(sv, "{unicode_all}");
 
        {
            SV *lv;
-           SV *sw = regclass_swash(o, FALSE, &lv, 0);
+           SV * const sw = regclass_swash(prog, o, FALSE, &lv, 0);
        
            if (lv) {
                if (sw) {
@@ -5902,37 +5902,38 @@ Perl_regprop(pTHX_ SV *sv, const regnode *o)
                            if (rangestart == -1)
                                rangestart = i;
                        } else if (rangestart != -1) {
-                           U8 *p;
-                       
                            if (i <= rangestart + 3)
                                for (; rangestart < i; rangestart++) {
-                                   U8 *e;
-                                   for(e = uvchr_to_utf8(s, rangestart), p = s; p < e; p++)
+                                   const U8 * const e = uvchr_to_utf8(s,rangestart);
+                                   U8 *p;
+                                   for(p = s; p < e; p++)
                                        put_byte(sv, *p);
                                }
                            else {
-                               U8 *e;
-                               for (e = uvchr_to_utf8(s, rangestart), p = s; p < e; p++)
+                               const U8 *e = uvchr_to_utf8(s,rangestart);
+                               U8 *p;
+                               for (p = s; p < e; p++)
                                    put_byte(sv, *p);
-                               sv_catpv(sv, "-");
-                               for (e = uvchr_to_utf8(s, i - 1), p = s; p < e; p++)
+                               sv_catpvs(sv, "-");
+                               e = uvchr_to_utf8(s, i-1);
+                               for (p = s; p < e; p++)
                                    put_byte(sv, *p);
                                }
                                rangestart = -1;
                            }
                        }
                        
-                   sv_catpv(sv, "..."); /* et cetera */
+                   sv_catpvs(sv, "..."); /* et cetera */
                }
 
                {
                    char *s = savesvpv(lv);
-                   char *origs = s;
+                   char * const origs = s;
                
                    while(*s && *s != '\n') s++;
                
                    if (*s == '\n') {
-                       const char *t = ++s;
+                       const char * const t = ++s;
                        
                        while (*s) {
                            if (*s == '\n')
@@ -5954,16 +5955,23 @@ Perl_regprop(pTHX_ SV *sv, const regnode *o)
     }
     else if (k == BRANCHJ && (OP(o) == UNLESSM || OP(o) == IFMATCH))
        Perl_sv_catpvf(aTHX_ sv, "[-%d]", o->flags);
+#else
+    PERL_UNUSED_CONTEXT;
+    PERL_UNUSED_ARG(sv);
+    PERL_UNUSED_ARG(o);
 #endif /* DEBUGGING */
 }
 
 SV *
 Perl_re_intuit_string(pTHX_ regexp *prog)
 {                              /* Assume that RE_INTUIT is set */
+    dVAR;
     GET_RE_DEBUG_FLAGS_DECL;
+    PERL_UNUSED_CONTEXT;
+
     DEBUG_COMPILE_r(
        {
-           const char *s = SvPV_nolen_const(prog->check_substr
+           const char * const s = SvPV_nolen_const(prog->check_substr
                      ? prog->check_substr : prog->check_utf8);
 
            if (!PL_colorset) reginitcolors();
@@ -5985,15 +5993,14 @@ Perl_pregfree(pTHX_ struct regexp *r)
 {
     dVAR;
 #ifdef DEBUGGING
-    SV *dsv = PERL_DEBUG_PAD_ZERO(0);
-    SV *re_debug_flags=get_sv(RE_DEBUG_FLAGS,0);
+    SV * const dsv = PERL_DEBUG_PAD_ZERO(0);
 #endif
-
+    GET_RE_DEBUG_FLAGS_DECL;
 
     if (!r || (--r->refcnt > 0))
        return;
     DEBUG_r(if (re_debug_flags && (SvIV(re_debug_flags) & RE_DEBUG_COMPILE)) {
-        const char *s = (r->reganch & ROPT_UTF8)
+        const char * const s = (r->reganch & ROPT_UTF8)
             ? pv_uni_display(dsv, (U8*)r->precomp, r->prelen, 60, UNI_DISPLAY_REGEX)
             : pv_display(dsv, r->precomp, r->prelen, 0, 60);
         const int len = SvCUR(dsv);
@@ -6050,8 +6057,7 @@ Perl_pregfree(pTHX_ struct regexp *r)
                    Perl_croak(aTHX_ "panic: pregfree comppad");
                PAD_SAVE_LOCAL(old_comppad,
                    /* Watch out for global destruction's random ordering. */
-                   (SvTYPE(new_comppad) == SVt_PVAV) ?
-                               new_comppad : Null(PAD *)
+                   (SvTYPE(new_comppad) == SVt_PVAV) ? new_comppad : NULL
                );
                OP_REFCNT_LOCK;
                refcnt = OpREFCNT_dec((OP_4tree*)r->data->data[n]);
@@ -6067,10 +6073,10 @@ Perl_pregfree(pTHX_ struct regexp *r)
                break;
            case 't':
                    {
-                       reg_trie_data *trie=(reg_trie_data*)r->data->data[n];
+                       reg_trie_data * const trie=(reg_trie_data*)r->data->data[n];
                        U32 refcount;
                        OP_REFCNT_LOCK;
-                       refcount = trie->refcount--;
+                       refcount = --trie->refcount;
                        OP_REFCNT_UNLOCK;
                        if ( !refcount ) {
                            Safefree(trie->charmap);
@@ -6106,6 +6112,7 @@ Perl_pregfree(pTHX_ struct regexp *r)
 regnode *
 Perl_regnext(pTHX_ register regnode *p)
 {
+    dVAR;
     register I32 offset;
 
     if (p == &PL_regdummy)
@@ -6157,80 +6164,56 @@ S_re_croak2(pTHX_ const char* pat1,const char* pat2,...)
 void
 Perl_save_re_context(pTHX)
 {
-    SAVEI32(PL_reg_flags);             /* from regexec.c */
-    SAVEPPTR(PL_bostr);
-    SAVEPPTR(PL_reginput);             /* String-input pointer. */
-    SAVEPPTR(PL_regbol);               /* Beginning of input, for ^ check. */
-    SAVEPPTR(PL_regeol);               /* End of input, for $ check. */
-    SAVEVPTR(PL_regstartp);            /* Pointer to startp array. */
-    SAVEVPTR(PL_regendp);              /* Ditto for endp. */
-    SAVEVPTR(PL_reglastparen);         /* Similarly for lastparen. */
-    SAVEVPTR(PL_reglastcloseparen);    /* Similarly for lastcloseparen. */
-    SAVEPPTR(PL_regtill);              /* How far we are required to go. */
-    SAVEGENERICPV(PL_reg_start_tmp);           /* from regexec.c */
+    dVAR;
+
+    struct re_save_state *state;
+
+    SAVEVPTR(PL_curcop);
+    SSGROW(SAVESTACK_ALLOC_FOR_RE_SAVE_STATE + 1);
+
+    state = (struct re_save_state *)(PL_savestack + PL_savestack_ix);
+    PL_savestack_ix += SAVESTACK_ALLOC_FOR_RE_SAVE_STATE;
+    SSPUSHINT(SAVEt_RE_STATE);
+
+    Copy(&PL_reg_state, state, 1, struct re_save_state);
+
     PL_reg_start_tmp = 0;
-    SAVEI32(PL_reg_start_tmpl);                /* from regexec.c */
     PL_reg_start_tmpl = 0;
-    SAVEVPTR(PL_regdata);
-    SAVEI32(PL_reg_eval_set);          /* from regexec.c */
-    SAVEI32(PL_regnarrate);            /* from regexec.c */
-    SAVEVPTR(PL_regprogram);           /* from regexec.c */
-    SAVEINT(PL_regindent);             /* from regexec.c */
-    SAVEVPTR(PL_regcc);                        /* from regexec.c */
-    SAVEVPTR(PL_curcop);
-    SAVEVPTR(PL_reg_call_cc);          /* from regexec.c */
-    SAVEVPTR(PL_reg_re);               /* from regexec.c */
-    SAVEPPTR(PL_reg_ganch);            /* from regexec.c */
-    SAVESPTR(PL_reg_sv);               /* from regexec.c */
-    SAVEBOOL(PL_reg_match_utf8);       /* from regexec.c */
-    SAVEVPTR(PL_reg_magic);            /* from regexec.c */
-    SAVEI32(PL_reg_oldpos);                    /* from regexec.c */
-    SAVEVPTR(PL_reg_oldcurpm);         /* from regexec.c */
-    SAVEVPTR(PL_reg_curpm);            /* from regexec.c */
-    SAVEPPTR(PL_reg_oldsaved);         /* old saved substr during match */
-    PL_reg_oldsaved = Nullch;
-    SAVEI32(PL_reg_oldsavedlen);       /* old length of saved substr during match */
+    PL_reg_oldsaved = NULL;
     PL_reg_oldsavedlen = 0;
-#ifdef PERL_OLD_COPY_ON_WRITE
-    SAVESPTR(PL_nrs);
-    PL_nrs = Nullsv;
-#endif
-    SAVEI32(PL_reg_maxiter);           /* max wait until caching pos */
     PL_reg_maxiter = 0;
-    SAVEI32(PL_reg_leftiter);          /* wait until caching pos */
     PL_reg_leftiter = 0;
-    SAVEGENERICPV(PL_reg_poscache);    /* cache of pos of WHILEM */
-    PL_reg_poscache = Nullch;
-    SAVEI32(PL_reg_poscache_size);     /* size of pos cache of WHILEM */
+    PL_reg_poscache = NULL;
     PL_reg_poscache_size = 0;
-    SAVEPPTR(PL_regprecomp);           /* uncompiled string. */
-    SAVEI32(PL_regnpar);               /* () count. */
-    SAVEI32(PL_regsize);               /* from regexec.c */
-
-    {
-       /* Save $1..$n (#18107: UTF-8 s/(\w+)/uc($1)/e); AMS 20021106. */
-       REGEXP *rx;
+#ifdef PERL_OLD_COPY_ON_WRITE
+    PL_nrs = NULL;
+#endif
 
-       if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
+    /* Save $1..$n (#18107: UTF-8 s/(\w+)/uc($1)/e); AMS 20021106. */
+    if (PL_curpm) {
+       const REGEXP * const rx = PM_GETRE(PL_curpm);
+       if (rx) {
            U32 i;
            for (i = 1; i <= rx->nparens; i++) {
-               GV *mgv;
                char digits[TYPE_CHARS(long)];
-               sprintf(digits, "%lu", (long)i);
-               if ((mgv = gv_fetchpv(digits, FALSE, SVt_PV)))
-                   save_scalar(mgv);
+               const STRLEN len = my_sprintf(digits, "%lu", (long)i);
+               GV *const *const gvp
+                   = (GV**)hv_fetch(PL_defstash, digits, len, 0);
+
+               if (gvp) {
+                   GV * const gv = *gvp;
+                   if (SvTYPE(gv) == SVt_PVGV && GvSV(gv))
+                       save_scalar(gv);
+               }
            }
        }
     }
-
-#ifdef DEBUGGING
-    SAVEPPTR(PL_reg_starttry);         /* from regexec.c */
-#endif
 }
 
 static void
 clear_re(pTHX_ void *r)
 {
+    dVAR;
     ReREFCNT_dec((regexp *)r);
 }
 
@@ -6248,11 +6231,13 @@ S_put_byte(pTHX_ SV *sv, int c)
 }
 
 
-STATIC regnode *
-S_dumpuntil(pTHX_ regnode *start, regnode *node, regnode *last, SV* sv, I32 l)
+STATIC const regnode *
+S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
+           const regnode *last, SV* sv, I32 l)
 {
+    dVAR;
     register U8 op = EXACT;    /* Arbitrary non-END op. */
-    register regnode *next;
+    register const regnode *next;
 
     while (op != END && (!last || node < last)) {
        /* While that wasn't END last time... */
@@ -6261,11 +6246,11 @@ S_dumpuntil(pTHX_ regnode *start, regnode *node, regnode *last, SV* sv, I32 l)
        op = OP(node);
        if (op == CLOSE)
            l--;        
-       next = regnext(node);
+       next = regnext((regnode *)node);
        /* Where, what. */
        if (OP(node) == OPTIMIZED)
            goto after_print;
-       regprop(sv, node);
+       regprop(r, sv, node);
        PerlIO_printf(Perl_debug_log, "%4"IVdf":%*s%s", (IV)(node - start),
                      (int)(2*l + 1), "", SvPVX_const(sv));
        if (next == NULL)               /* Next ptr. */
@@ -6275,19 +6260,19 @@ S_dumpuntil(pTHX_ regnode *start, regnode *node, regnode *last, SV* sv, I32 l)
        (void)PerlIO_putc(Perl_debug_log, '\n');
       after_print:
        if (PL_regkind[(U8)op] == BRANCHJ) {
-           register regnode *nnode = (OP(next) == LONGJMP
-                                      ? regnext(next)
-                                      : next);
+           register const regnode *nnode = (OP(next) == LONGJMP
+                                            ? regnext((regnode *)next)
+                                            : next);
            if (last && nnode > last)
                nnode = last;
-           node = dumpuntil(start, NEXTOPER(NEXTOPER(node)), nnode, sv, l + 1);
+           node = dumpuntil(r, start, NEXTOPER(NEXTOPER(node)), nnode, sv, l + 1);
        }
        else if (PL_regkind[(U8)op] == BRANCH) {
-           node = dumpuntil(start, NEXTOPER(node), next, sv, l + 1);
+           node = dumpuntil(r, start, NEXTOPER(node), next, sv, l + 1);
        }
        else if ( PL_regkind[(U8)op]  == TRIE ) {
             const I32 n = ARG(node);
-           const reg_trie_data * const trie = (reg_trie_data*)PL_regdata->data[n];
+           const reg_trie_data * const trie = (reg_trie_data*)r->data->data[n];
             const I32 arry_len = av_len(trie->words)+1;
            I32 word_idx;
            PerlIO_printf(Perl_debug_log,
@@ -6301,7 +6286,7 @@ S_dumpuntil(pTHX_ regnode *start, regnode *node, regnode *last, SV* sv, I32 l)
                       node->flags ? " EVAL mode" : "");
 
            for (word_idx=0; word_idx < arry_len; word_idx++) {
-               SV **elem_ptr=av_fetch(trie->words,word_idx,0);
+               SV ** const elem_ptr = av_fetch(trie->words,word_idx,0);
                if (elem_ptr) {
                    PerlIO_printf(Perl_debug_log, "%*s<%s%s%s>\n",
                       (int)(2*(l+4)), "",
@@ -6324,15 +6309,15 @@ S_dumpuntil(pTHX_ regnode *start, regnode *node, regnode *last, SV* sv, I32 l)
 
        }
        else if ( op == CURLY) {   /* "next" might be very big: optimizer */
-           node = dumpuntil(start, NEXTOPER(node) + EXTRA_STEP_2ARGS,
+           node = dumpuntil(r, start, NEXTOPER(node) + EXTRA_STEP_2ARGS,
                             NEXTOPER(node) + EXTRA_STEP_2ARGS + 1, sv, l + 1);
        }
        else if (PL_regkind[(U8)op] == CURLY && op != CURLYX) {
-           node = dumpuntil(start, NEXTOPER(node) + EXTRA_STEP_2ARGS,
+           node = dumpuntil(r, start, NEXTOPER(node) + EXTRA_STEP_2ARGS,
                             next, sv, l + 1);
        }
        else if ( op == PLUS || op == STAR) {
-           node = dumpuntil(start, NEXTOPER(node), NEXTOPER(node) + 1, sv, l + 1);
+           node = dumpuntil(r, start, NEXTOPER(node), NEXTOPER(node) + 1, sv, l + 1);
        }
        else if (op == ANYOF) {
            /* arglen 1 + class block */