Use bit instead of node for regex SSC
authorKarl Williamson <public@khwilliamson.com>
Mon, 13 Jan 2014 06:39:43 +0000 (23:39 -0700)
committerKarl Williamson <public@khwilliamson.com>
Wed, 22 Jan 2014 18:45:56 +0000 (11:45 -0700)
The flag bits in regular expression ANYOF nodes are perennially in short
supply.  However there are still plenty of regex nodes possible.  So one
solution to needing to pass more information is to create a node that
encapsulates what is needed.  That is what commit
9aa1e39f96ac28f6ce5d814d9a1eccf1464aba4a did to tell regexec.c that a
particular ANYOF node is for the synthetic start class (SSC).  However
this solution introduces other issues.  If you have to express two
things, then you need a regnode for A, a regnode for B, a regnode for
both A and B, and another regnode for both not A nor B;  With three
things, you need 8 regnodes to express all possible combinations.  This
becomes unwieldy to write code for.  The number of combinations goes way
down if some of them are mutually exclusive.  At the time of that
commit, I thought that a SSC need not ever warn if matching against an
above-Unicode code point.  I was wrong, and that has been corrected
earlier in the 5.19 series.

But it finally came to me how to tell regexec that an ANYOF node is
for the SSC without taking up a flag bit and without requiring a regnode
type.  The 'next_off' field in a regnode tells the engine the offeset in
the regex program to the node it's supposed to go to after processing
this one.  Since the SSC stands alone, its 'next_off' field is unused,
and we can put anything we want in it.  That, however, is not true of
other ANYOF regnodes.  But it turns out that there are certain values
that will never be legitimate in the 'next_off' field in these, and so
this commit uses one of those to signal that this ANYOF field is an SSC.
regnodes come in various sizes, and the offset is in terms of how many
of the smallest ones are there to the next node to look at.  Since ANYOF
nodes are large, the offset is always > 1, and so this commit uses 1 to
indicate an SSC.

pod/perldebguts.pod
regcomp.c
regcomp.h
regcomp.sym
regexec.c
regnodes.h

index 54fc478..9765afb 100644 (file)
@@ -591,7 +591,6 @@ will be lost.
  CANY            no         Match any one byte.
  ANYOF           sv         Match character in (or not in) this class,
                             single char match only
- ANYOF_SYNTHETIC sv         Synthetic start class
 
  POSIXD          none       Some [[:class:]] under /d; the FLAGS field
                             gives which one
index be034a1..775d6ca 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -863,7 +863,7 @@ S_ssc_anything(pTHX_ regnode_ssc *ssc)
 
     PERL_ARGS_ASSERT_SSC_ANYTHING;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     ssc->invlist = sv_2mortal(_new_invlist(2)); /* mortalize so won't leak */
     _append_range_to_invlist(ssc->invlist, 0, UV_MAX);
@@ -883,7 +883,7 @@ S_ssc_is_anything(pTHX_ const regnode_ssc *ssc)
 
     PERL_ARGS_ASSERT_SSC_IS_ANYTHING;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     if (! (ANYOF_FLAGS(ssc) & ANYOF_EMPTY_STRING)) {
         return FALSE;
@@ -923,7 +923,7 @@ S_ssc_init(pTHX_ const RExC_state_t *pRExC_state, regnode_ssc *ssc)
     PERL_ARGS_ASSERT_SSC_INIT;
 
     Zero(ssc, 1, regnode_ssc);
-    OP(ssc) = ANYOF_SYNTHETIC;
+    set_ANYOF_SYNTHETIC(ssc);
     ARG_SET(ssc, ANYOF_NONBITMAP_EMPTY);
     ssc_anything(ssc);
 
@@ -959,7 +959,7 @@ S_ssc_is_cp_posixl_init(pTHX_ const RExC_state_t *pRExC_state,
 
     PERL_ARGS_ASSERT_SSC_IS_CP_POSIXL_INIT;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     invlist_iterinit(ssc->invlist);
     ret = invlist_iternext(ssc->invlist, &start, &end)
@@ -1105,11 +1105,11 @@ S_ssc_and(pTHX_ const RExC_state_t *pRExC_state, regnode_ssc *ssc,
 
     PERL_ARGS_ASSERT_SSC_AND;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     /* 'and_with' is used as-is if it too is an SSC; otherwise have to extract
      * the code point inversion list and just the relevant flags */
-    if (OP(and_with) == ANYOF_SYNTHETIC) {
+    if (is_ANYOF_SYNTHETIC(and_with)) {
         anded_cp_list = and_with->invlist;
         anded_flags = ANYOF_FLAGS(and_with);
 
@@ -1172,7 +1172,7 @@ S_ssc_and(pTHX_ const RExC_state_t *pRExC_state, regnode_ssc *ssc,
      * */
 
     if ((ANYOF_FLAGS(and_with) & ANYOF_INVERT)
-        && OP(and_with) != ANYOF_SYNTHETIC)
+        && ! is_ANYOF_SYNTHETIC(and_with))
     {
         unsigned int i;
 
@@ -1230,13 +1230,13 @@ S_ssc_and(pTHX_ const RExC_state_t *pRExC_state, regnode_ssc *ssc,
         } /* else ssc already has no posixes */
     } /* else: Not inverted.  This routine is a no-op if 'and_with' is an SSC
          in its initial state */
-    else if (OP(and_with) != ANYOF_SYNTHETIC
+    else if (! is_ANYOF_SYNTHETIC(and_with)
              || ! ssc_is_cp_posixl_init(pRExC_state, and_with))
     {
         /* But if 'ssc' is in its initial state, the result is just 'and_with';
          * copy it over 'ssc' */
         if (ssc_is_cp_posixl_init(pRExC_state, ssc)) {
-            if (OP(and_with) == ANYOF_SYNTHETIC) {
+            if (is_ANYOF_SYNTHETIC(and_with)) {
                 StructCopy(and_with, ssc, regnode_ssc);
             }
             else {
@@ -1273,11 +1273,11 @@ S_ssc_or(pTHX_ const RExC_state_t *pRExC_state, regnode_ssc *ssc,
 
     PERL_ARGS_ASSERT_SSC_OR;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     /* 'or_with' is used as-is if it too is an SSC; otherwise have to extract
      * the code point inversion list and just the relevant flags */
-    if (OP(or_with) == ANYOF_SYNTHETIC) {
+    if (is_ANYOF_SYNTHETIC(or_with)) {
         ored_cp_list = or_with->invlist;
         ored_flags = ANYOF_FLAGS(or_with);
     }
@@ -1308,7 +1308,7 @@ S_ssc_or(pTHX_ const RExC_state_t *pRExC_state, regnode_ssc *ssc,
      * */
 
     if ((ANYOF_FLAGS(or_with) & ANYOF_INVERT)
-        && OP(or_with) != ANYOF_SYNTHETIC)
+        && ! is_ANYOF_SYNTHETIC(or_with))
     {
         /* We ignore P2, leaving P1 going forward */
     }
@@ -1341,7 +1341,7 @@ S_ssc_union(pTHX_ regnode_ssc *ssc, SV* const invlist, const bool invert2nd)
 {
     PERL_ARGS_ASSERT_SSC_UNION;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     _invlist_union_maybe_complement_2nd(ssc->invlist,
                                         invlist,
@@ -1356,7 +1356,7 @@ S_ssc_intersection(pTHX_ regnode_ssc *ssc,
 {
     PERL_ARGS_ASSERT_SSC_INTERSECTION;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     _invlist_intersection_maybe_complement_2nd(ssc->invlist,
                                                invlist,
@@ -1369,7 +1369,7 @@ S_ssc_add_range(pTHX_ regnode_ssc *ssc, const UV start, const UV end)
 {
     PERL_ARGS_ASSERT_SSC_ADD_RANGE;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     ssc->invlist = _add_range_to_invlist(ssc->invlist, start, end);
 }
@@ -1383,7 +1383,7 @@ S_ssc_cp_and(pTHX_ regnode_ssc *ssc, const UV cp)
 
     PERL_ARGS_ASSERT_SSC_CP_AND;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     cp_list = add_cp_to_invlist(cp_list, cp);
     ssc_intersection(ssc, cp_list,
@@ -1399,7 +1399,7 @@ S_ssc_clear_locale(pTHX_ regnode_ssc *ssc)
 
     PERL_ARGS_ASSERT_SSC_CLEAR_LOCALE;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     ANYOF_POSIXL_ZERO(ssc);
     ANYOF_FLAGS(ssc) &= ~ANYOF_LOCALE_FLAGS;
@@ -1416,7 +1416,7 @@ S_ssc_finalize(pTHX_ RExC_state_t *pRExC_state, regnode_ssc *ssc)
 
     PERL_ARGS_ASSERT_SSC_FINALIZE;
 
-    assert(OP(ssc) == ANYOF_SYNTHETIC);
+    assert(is_ANYOF_SYNTHETIC(ssc));
 
     /* The code in this file assumes that all but these flags aren't relevant
      * to the SSC, except ANYOF_EMPTY_STRING, which should be cleared by the
index 3db3c15..8bca5d2 100644 (file)
--- a/regcomp.h
+++ b/regcomp.h
@@ -204,6 +204,19 @@ struct regnode_ssc {
     SV* invlist;                        /* list of code points matched */
 };
 
+/*  We take advantage of 'next_off' not otherwise being used in the SSC by
+ *  actually using it: by setting it to 1.  This allows us to test and
+ *  distinguish between an SSC and other ANYOF node types, as 'next_off' cannot
+ *  otherwise be 1, because it is the offset to the next regnode expressed in
+ *  units of regnodes.  Since an ANYOF node contains extra fields, it adds up
+ *  to 12 regnode units on 32-bit systems, (hence the minimum this can be (if
+ *  not 0) is 11 there.  Even if things get tightly packed on a 64-bit system,
+ *  it still would be more than 1. */
+#define set_ANYOF_SYNTHETIC(n) STMT_START{ OP(n) = ANYOF;              \
+                                           NEXT_OFF(n) = 1;            \
+                               } STMT_END
+#define is_ANYOF_SYNTHETIC(n) (OP(n) == ANYOF && NEXT_OFF(n) == 1)
+
 /* XXX fix this description.
    Impose a limit of REG_INFTY on various pattern matching operations
    to limit stack growth and to avoid "infinite" recursions.
@@ -322,10 +335,9 @@ struct regnode_ssc {
  * performance penalty.  Better would be to split it off into a separate node,
  * which actually would improve performance a bit by allowing regexec.c to test
  * for a UTF-8 character being above 255 without having to call a function nor
- * calculate its code point value.  However, this solution might need to have a
- * second node type, ANYOF_SYNTHETIC_ABOVE_LATIN1_ALL.  Several flags are not
- * used in synthetic start class (SSC) nodes, so could be shared should new
- * flags be needed for SSCs. */
+ * calculate its code point value.  Several flags are not used in synthetic
+ * start class (SSC) nodes, so could be shared should new flags be needed for
+ * SSCs. */
 
 /* regexec.c is expecting this to be in the low bit */
 #define ANYOF_INVERT            0x01
index 09962dd..a198186 100644 (file)
@@ -55,7 +55,6 @@ REG_ANY     REG_ANY,    no 0 S    ; Match any one character (except newline).
 SANY        REG_ANY,    no 0 S    ; Match any one character.
 CANY        REG_ANY,    no 0 S    ; Match any one byte.
 ANYOF       ANYOF,      sv 0 S    ; Match character in (or not in) this class, single char match only
-ANYOF_SYNTHETIC ANYOF,  sv 0 S    ; Synthetic start class
 
 # Order of the below is important.  See ordering comment above.
 POSIXD      POSIXD,     none 0 S   ; Some [[:class:]] under /d; the FLAGS field gives which one
index 4a5771d..b8b5b99 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -1497,7 +1497,6 @@ S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
     /* We know what class it must start with. */
     switch (OP(c)) {
     case ANYOF:
-    case ANYOF_SYNTHETIC:
         if (utf8_target) {
             REXEC_FBC_UTF8_CLASS_SCAN(
                       reginclass(prog, c, (U8*)s, (U8*) strend, utf8_target));
@@ -7536,7 +7535,7 @@ S_reginclass(pTHX_ regexp * const prog, const regnode * const n, const U8* const
                     || (utf8_target
                         && (c >=256
                             || (! (flags & ANYOF_LOCALE))
-                            || OP(n) == ANYOF_SYNTHETIC))))
+                            || is_ANYOF_SYNTHETIC(n)))))
        {
            SV * const sw = core_regclass_swash(prog, n, TRUE, 0);
            if (sw) {
index f1a5fe2..0af89b9 100644 (file)
@@ -6,8 +6,8 @@
 
 /* Regops and State definitions */
 
-#define REGNODE_MAX            94
-#define REGMATCH_STATE_MAX     134
+#define REGNODE_MAX            93
+#define REGMATCH_STATE_MAX     133
 
 #define        END                     0       /* 0000 End of program. */
 #define        SUCCEED                 1       /* 0x01 Return from a subroutine, basically. */
 #define        SANY                    19      /* 0x13 Match any one character. */
 #define        CANY                    20      /* 0x14 Match any one byte. */
 #define        ANYOF                   21      /* 0x15 Match character in (or not in) this class, single char match only */
-#define        ANYOF_SYNTHETIC         22      /* 0x16 Synthetic start class */
-#define        POSIXD                  23      /* 0x17 Some [[:class:]] under /d; the FLAGS field gives which one */
-#define        POSIXL                  24      /* 0x18 Some [[:class:]] under /l; the FLAGS field gives which one */
-#define        POSIXU                  25      /* 0x19 Some [[:class:]] under /u; the FLAGS field gives which one */
-#define        POSIXA                  26      /* 0x1a Some [[:class:]] under /a; the FLAGS field gives which one */
-#define        NPOSIXD                 27      /* 0x1b complement of POSIXD, [[:^class:]] */
-#define        NPOSIXL                 28      /* 0x1c complement of POSIXL, [[:^class:]] */
-#define        NPOSIXU                 29      /* 0x1d complement of POSIXU, [[:^class:]] */
-#define        NPOSIXA                 30      /* 0x1e complement of POSIXA, [[:^class:]] */
-#define        CLUMP                   31      /* 0x1f Match any extended grapheme cluster sequence */
-#define        BRANCH                  32      /* 0x20 Match this alternative, or the next... */
-#define        BACK                    33      /* 0x21 Match "", "next" ptr points backward. */
-#define        EXACT                   34      /* 0x22 Match this string (preceded by length). */
-#define        EXACTF                  35      /* 0x23 Match this non-UTF-8 string (not guaranteed to be folded) using /id rules (w/len). */
-#define        EXACTFL                 36      /* 0x24 Match this string (not guaranteed to be folded) using /il rules (w/len). */
-#define        EXACTFU                 37      /* 0x25 Match this string (folded iff in UTF-8, length in folding doesn't change if not in UTF-8) using /iu rules (w/len). */
-#define        EXACTFA                 38      /* 0x26 Match this string (not guaranteed to be folded) using /iaa rules (w/len). */
-#define        EXACTFU_SS              39      /* 0x27 Match this string (folded iff in UTF-8, length in folding may change even if not in UTF-8) using /iu rules (w/len). */
-#define        EXACTFA_NO_TRIE         40      /* 0x28 Match this string (which is not trie-able; not guaranteed to be folded) using /iaa rules (w/len). */
-#define        NOTHING                 41      /* 0x29 Match empty string. */
-#define        TAIL                    42      /* 0x2a Match empty string. Can jump here from outside. */
-#define        STAR                    43      /* 0x2b Match this (simple) thing 0 or more times. */
-#define        PLUS                    44      /* 0x2c Match this (simple) thing 1 or more times. */
-#define        CURLY                   45      /* 0x2d Match this simple thing {n,m} times. */
-#define        CURLYN                  46      /* 0x2e Capture next-after-this simple thing */
-#define        CURLYM                  47      /* 0x2f Capture this medium-complex thing {n,m} times. */
-#define        CURLYX                  48      /* 0x30 Match this complex thing {n,m} times. */
-#define        WHILEM                  49      /* 0x31 Do curly processing and see if rest matches. */
-#define        OPEN                    50      /* 0x32 Mark this point in input as start of #n. */
-#define        CLOSE                   51      /* 0x33 Analogous to OPEN. */
-#define        REF                     52      /* 0x34 Match some already matched string */
-#define        REFF                    53      /* 0x35 Match already matched string, folded using native charset semantics for non-utf8 */
-#define        REFFL                   54      /* 0x36 Match already matched string, folded in loc. */
-#define        REFFU                   55      /* 0x37 Match already matched string, folded using unicode semantics for non-utf8 */
-#define        REFFA                   56      /* 0x38 Match already matched string, folded using unicode semantics for non-utf8, no mixing ASCII, non-ASCII */
-#define        NREF                    57      /* 0x39 Match some already matched string */
-#define        NREFF                   58      /* 0x3a Match already matched string, folded using native charset semantics for non-utf8 */
-#define        NREFFL                  59      /* 0x3b Match already matched string, folded in loc. */
-#define        NREFFU                  60      /* 0x3c Match already matched string, folded using unicode semantics for non-utf8 */
-#define        NREFFA                  61      /* 0x3d Match already matched string, folded using unicode semantics for non-utf8, no mixing ASCII, non-ASCII */
-#define        IFMATCH                 62      /* 0x3e Succeeds if the following matches. */
-#define        UNLESSM                 63      /* 0x3f Fails if the following matches. */
-#define        SUSPEND                 64      /* 0x40 "Independent" sub-RE. */
-#define        IFTHEN                  65      /* 0x41 Switch, should be preceded by switcher. */
-#define        GROUPP                  66      /* 0x42 Whether the group matched. */
-#define        LONGJMP                 67      /* 0x43 Jump far away. */
-#define        BRANCHJ                 68      /* 0x44 BRANCH with long offset. */
-#define        EVAL                    69      /* 0x45 Execute some Perl code. */
-#define        MINMOD                  70      /* 0x46 Next operator is not greedy. */
-#define        LOGICAL                 71      /* 0x47 Next opcode should set the flag only. */
-#define        RENUM                   72      /* 0x48 Group with independently numbered parens. */
-#define        TRIE                    73      /* 0x49 Match many EXACT(F[ALU]?)? at once. flags==type */
-#define        TRIEC                   74      /* 0x4a Same as TRIE, but with embedded charclass data */
-#define        AHOCORASICK             75      /* 0x4b Aho Corasick stclass. flags==type */
-#define        AHOCORASICKC            76      /* 0x4c Same as AHOCORASICK, but with embedded charclass data */
-#define        GOSUB                   77      /* 0x4d recurse to paren arg1 at (signed) ofs arg2 */
-#define        GOSTART                 78      /* 0x4e recurse to start of pattern */
-#define        NGROUPP                 79      /* 0x4f Whether the group matched. */
-#define        INSUBP                  80      /* 0x50 Whether we are in a specific recurse. */
-#define        DEFINEP                 81      /* 0x51 Never execute directly. */
-#define        ENDLIKE                 82      /* 0x52 Used only for the type field of verbs */
-#define        OPFAIL                  83      /* 0x53 Same as (?!) */
-#define        ACCEPT                  84      /* 0x54 Accepts the current matched string. */
-#define        VERB                    85      /* 0x55 Used only for the type field of verbs */
-#define        PRUNE                   86      /* 0x56 Pattern fails at this startpoint if no-backtracking through this */
-#define        MARKPOINT               87      /* 0x57 Push the current location for rollback by cut. */
-#define        SKIP                    88      /* 0x58 On failure skip forward (to the mark) before retrying */
-#define        COMMIT                  89      /* 0x59 Pattern fails outright if backtracking through this */
-#define        CUTGROUP                90      /* 0x5a On failure go to the next alternation in the group */
-#define        KEEPS                   91      /* 0x5b $& begins here. */
-#define        LNBREAK                 92      /* 0x5c generic newline pattern */
-#define        OPTIMIZED               93      /* 0x5d Placeholder for dump. */
-#define        PSEUDO                  94      /* 0x5e Pseudo opcode for internal use. */
+#define        POSIXD                  22      /* 0x16 Some [[:class:]] under /d; the FLAGS field gives which one */
+#define        POSIXL                  23      /* 0x17 Some [[:class:]] under /l; the FLAGS field gives which one */
+#define        POSIXU                  24      /* 0x18 Some [[:class:]] under /u; the FLAGS field gives which one */
+#define        POSIXA                  25      /* 0x19 Some [[:class:]] under /a; the FLAGS field gives which one */
+#define        NPOSIXD                 26      /* 0x1a complement of POSIXD, [[:^class:]] */
+#define        NPOSIXL                 27      /* 0x1b complement of POSIXL, [[:^class:]] */
+#define        NPOSIXU                 28      /* 0x1c complement of POSIXU, [[:^class:]] */
+#define        NPOSIXA                 29      /* 0x1d complement of POSIXA, [[:^class:]] */
+#define        CLUMP                   30      /* 0x1e Match any extended grapheme cluster sequence */
+#define        BRANCH                  31      /* 0x1f Match this alternative, or the next... */
+#define        BACK                    32      /* 0x20 Match "", "next" ptr points backward. */
+#define        EXACT                   33      /* 0x21 Match this string (preceded by length). */
+#define        EXACTF                  34      /* 0x22 Match this non-UTF-8 string (not guaranteed to be folded) using /id rules (w/len). */
+#define        EXACTFL                 35      /* 0x23 Match this string (not guaranteed to be folded) using /il rules (w/len). */
+#define        EXACTFU                 36      /* 0x24 Match this string (folded iff in UTF-8, length in folding doesn't change if not in UTF-8) using /iu rules (w/len). */
+#define        EXACTFA                 37      /* 0x25 Match this string (not guaranteed to be folded) using /iaa rules (w/len). */
+#define        EXACTFU_SS              38      /* 0x26 Match this string (folded iff in UTF-8, length in folding may change even if not in UTF-8) using /iu rules (w/len). */
+#define        EXACTFA_NO_TRIE         39      /* 0x27 Match this string (which is not trie-able; not guaranteed to be folded) using /iaa rules (w/len). */
+#define        NOTHING                 40      /* 0x28 Match empty string. */
+#define        TAIL                    41      /* 0x29 Match empty string. Can jump here from outside. */
+#define        STAR                    42      /* 0x2a Match this (simple) thing 0 or more times. */
+#define        PLUS                    43      /* 0x2b Match this (simple) thing 1 or more times. */
+#define        CURLY                   44      /* 0x2c Match this simple thing {n,m} times. */
+#define        CURLYN                  45      /* 0x2d Capture next-after-this simple thing */
+#define        CURLYM                  46      /* 0x2e Capture this medium-complex thing {n,m} times. */
+#define        CURLYX                  47      /* 0x2f Match this complex thing {n,m} times. */
+#define        WHILEM                  48      /* 0x30 Do curly processing and see if rest matches. */
+#define        OPEN                    49      /* 0x31 Mark this point in input as start of #n. */
+#define        CLOSE                   50      /* 0x32 Analogous to OPEN. */
+#define        REF                     51      /* 0x33 Match some already matched string */
+#define        REFF                    52      /* 0x34 Match already matched string, folded using native charset semantics for non-utf8 */
+#define        REFFL                   53      /* 0x35 Match already matched string, folded in loc. */
+#define        REFFU                   54      /* 0x36 Match already matched string, folded using unicode semantics for non-utf8 */
+#define        REFFA                   55      /* 0x37 Match already matched string, folded using unicode semantics for non-utf8, no mixing ASCII, non-ASCII */
+#define        NREF                    56      /* 0x38 Match some already matched string */
+#define        NREFF                   57      /* 0x39 Match already matched string, folded using native charset semantics for non-utf8 */
+#define        NREFFL                  58      /* 0x3a Match already matched string, folded in loc. */
+#define        NREFFU                  59      /* 0x3b Match already matched string, folded using unicode semantics for non-utf8 */
+#define        NREFFA                  60      /* 0x3c Match already matched string, folded using unicode semantics for non-utf8, no mixing ASCII, non-ASCII */
+#define        IFMATCH                 61      /* 0x3d Succeeds if the following matches. */
+#define        UNLESSM                 62      /* 0x3e Fails if the following matches. */
+#define        SUSPEND                 63      /* 0x3f "Independent" sub-RE. */
+#define        IFTHEN                  64      /* 0x40 Switch, should be preceded by switcher. */
+#define        GROUPP                  65      /* 0x41 Whether the group matched. */
+#define        LONGJMP                 66      /* 0x42 Jump far away. */
+#define        BRANCHJ                 67      /* 0x43 BRANCH with long offset. */
+#define        EVAL                    68      /* 0x44 Execute some Perl code. */
+#define        MINMOD                  69      /* 0x45 Next operator is not greedy. */
+#define        LOGICAL                 70      /* 0x46 Next opcode should set the flag only. */
+#define        RENUM                   71      /* 0x47 Group with independently numbered parens. */
+#define        TRIE                    72      /* 0x48 Match many EXACT(F[ALU]?)? at once. flags==type */
+#define        TRIEC                   73      /* 0x49 Same as TRIE, but with embedded charclass data */
+#define        AHOCORASICK             74      /* 0x4a Aho Corasick stclass. flags==type */
+#define        AHOCORASICKC            75      /* 0x4b Same as AHOCORASICK, but with embedded charclass data */
+#define        GOSUB                   76      /* 0x4c recurse to paren arg1 at (signed) ofs arg2 */
+#define        GOSTART                 77      /* 0x4d recurse to start of pattern */
+#define        NGROUPP                 78      /* 0x4e Whether the group matched. */
+#define        INSUBP                  79      /* 0x4f Whether we are in a specific recurse. */
+#define        DEFINEP                 80      /* 0x50 Never execute directly. */
+#define        ENDLIKE                 81      /* 0x51 Used only for the type field of verbs */
+#define        OPFAIL                  82      /* 0x52 Same as (?!) */
+#define        ACCEPT                  83      /* 0x53 Accepts the current matched string. */
+#define        VERB                    84      /* 0x54 Used only for the type field of verbs */
+#define        PRUNE                   85      /* 0x55 Pattern fails at this startpoint if no-backtracking through this */
+#define        MARKPOINT               86      /* 0x56 Push the current location for rollback by cut. */
+#define        SKIP                    87      /* 0x57 On failure skip forward (to the mark) before retrying */
+#define        COMMIT                  88      /* 0x58 Pattern fails outright if backtracking through this */
+#define        CUTGROUP                89      /* 0x59 On failure go to the next alternation in the group */
+#define        KEEPS                   90      /* 0x5a $& begins here. */
+#define        LNBREAK                 91      /* 0x5b generic newline pattern */
+#define        OPTIMIZED               92      /* 0x5c Placeholder for dump. */
+#define        PSEUDO                  93      /* 0x5d Pseudo opcode for internal use. */
        /* ------------ States ------------- */
 #define        TRIE_next               (REGNODE_MAX + 1)       /* state for TRIE */
 #define        TRIE_next_fail          (REGNODE_MAX + 2)       /* state for TRIE */
@@ -174,7 +173,6 @@ EXTCONST U8 PL_regkind[] = {
        REG_ANY,        /* SANY                   */
        REG_ANY,        /* CANY                   */
        ANYOF,          /* ANYOF                  */
-       ANYOF,          /* ANYOF_SYNTHETIC        */
        POSIXD,         /* POSIXD                 */
        POSIXD,         /* POSIXL                 */
        POSIXD,         /* POSIXU                 */
@@ -317,7 +315,6 @@ static const U8 regarglen[] = {
        0,                                      /* SANY         */
        0,                                      /* CANY         */
        0,                                      /* ANYOF        */
-       0,                                      /* ANYOF_SYNTHETIC */
        0,                                      /* POSIXD       */
        0,                                      /* POSIXL       */
        0,                                      /* POSIXU       */
@@ -417,7 +414,6 @@ static const char reg_off_by_arg[] = {
        0,      /* SANY         */
        0,      /* CANY         */
        0,      /* ANYOF        */
-       0,      /* ANYOF_SYNTHETIC */
        0,      /* POSIXD       */
        0,      /* POSIXL       */
        0,      /* POSIXU       */
@@ -522,79 +518,78 @@ EXTCONST char * const PL_reg_name[] = {
        "SANY",                         /* 0x13 */
        "CANY",                         /* 0x14 */
        "ANYOF",                        /* 0x15 */
-       "ANYOF_SYNTHETIC",              /* 0x16 */
-       "POSIXD",                       /* 0x17 */
-       "POSIXL",                       /* 0x18 */
-       "POSIXU",                       /* 0x19 */
-       "POSIXA",                       /* 0x1a */
-       "NPOSIXD",                      /* 0x1b */
-       "NPOSIXL",                      /* 0x1c */
-       "NPOSIXU",                      /* 0x1d */
-       "NPOSIXA",                      /* 0x1e */
-       "CLUMP",                        /* 0x1f */
-       "BRANCH",                       /* 0x20 */
-       "BACK",                         /* 0x21 */
-       "EXACT",                        /* 0x22 */
-       "EXACTF",                       /* 0x23 */
-       "EXACTFL",                      /* 0x24 */
-       "EXACTFU",                      /* 0x25 */
-       "EXACTFA",                      /* 0x26 */
-       "EXACTFU_SS",                   /* 0x27 */
-       "EXACTFA_NO_TRIE",              /* 0x28 */
-       "NOTHING",                      /* 0x29 */
-       "TAIL",                         /* 0x2a */
-       "STAR",                         /* 0x2b */
-       "PLUS",                         /* 0x2c */
-       "CURLY",                        /* 0x2d */
-       "CURLYN",                       /* 0x2e */
-       "CURLYM",                       /* 0x2f */
-       "CURLYX",                       /* 0x30 */
-       "WHILEM",                       /* 0x31 */
-       "OPEN",                         /* 0x32 */
-       "CLOSE",                        /* 0x33 */
-       "REF",                          /* 0x34 */
-       "REFF",                         /* 0x35 */
-       "REFFL",                        /* 0x36 */
-       "REFFU",                        /* 0x37 */
-       "REFFA",                        /* 0x38 */
-       "NREF",                         /* 0x39 */
-       "NREFF",                        /* 0x3a */
-       "NREFFL",                       /* 0x3b */
-       "NREFFU",                       /* 0x3c */
-       "NREFFA",                       /* 0x3d */
-       "IFMATCH",                      /* 0x3e */
-       "UNLESSM",                      /* 0x3f */
-       "SUSPEND",                      /* 0x40 */
-       "IFTHEN",                       /* 0x41 */
-       "GROUPP",                       /* 0x42 */
-       "LONGJMP",                      /* 0x43 */
-       "BRANCHJ",                      /* 0x44 */
-       "EVAL",                         /* 0x45 */
-       "MINMOD",                       /* 0x46 */
-       "LOGICAL",                      /* 0x47 */
-       "RENUM",                        /* 0x48 */
-       "TRIE",                         /* 0x49 */
-       "TRIEC",                        /* 0x4a */
-       "AHOCORASICK",                  /* 0x4b */
-       "AHOCORASICKC",                 /* 0x4c */
-       "GOSUB",                        /* 0x4d */
-       "GOSTART",                      /* 0x4e */
-       "NGROUPP",                      /* 0x4f */
-       "INSUBP",                       /* 0x50 */
-       "DEFINEP",                      /* 0x51 */
-       "ENDLIKE",                      /* 0x52 */
-       "OPFAIL",                       /* 0x53 */
-       "ACCEPT",                       /* 0x54 */
-       "VERB",                         /* 0x55 */
-       "PRUNE",                        /* 0x56 */
-       "MARKPOINT",                    /* 0x57 */
-       "SKIP",                         /* 0x58 */
-       "COMMIT",                       /* 0x59 */
-       "CUTGROUP",                     /* 0x5a */
-       "KEEPS",                        /* 0x5b */
-       "LNBREAK",                      /* 0x5c */
-       "OPTIMIZED",                    /* 0x5d */
-       "PSEUDO",                       /* 0x5e */
+       "POSIXD",                       /* 0x16 */
+       "POSIXL",                       /* 0x17 */
+       "POSIXU",                       /* 0x18 */
+       "POSIXA",                       /* 0x19 */
+       "NPOSIXD",                      /* 0x1a */
+       "NPOSIXL",                      /* 0x1b */
+       "NPOSIXU",                      /* 0x1c */
+       "NPOSIXA",                      /* 0x1d */
+       "CLUMP",                        /* 0x1e */
+       "BRANCH",                       /* 0x1f */
+       "BACK",                         /* 0x20 */
+       "EXACT",                        /* 0x21 */
+       "EXACTF",                       /* 0x22 */
+       "EXACTFL",                      /* 0x23 */
+       "EXACTFU",                      /* 0x24 */
+       "EXACTFA",                      /* 0x25 */
+       "EXACTFU_SS",                   /* 0x26 */
+       "EXACTFA_NO_TRIE",              /* 0x27 */
+       "NOTHING",                      /* 0x28 */
+       "TAIL",                         /* 0x29 */
+       "STAR",                         /* 0x2a */
+       "PLUS",                         /* 0x2b */
+       "CURLY",                        /* 0x2c */
+       "CURLYN",                       /* 0x2d */
+       "CURLYM",                       /* 0x2e */
+       "CURLYX",                       /* 0x2f */
+       "WHILEM",                       /* 0x30 */
+       "OPEN",                         /* 0x31 */
+       "CLOSE",                        /* 0x32 */
+       "REF",                          /* 0x33 */
+       "REFF",                         /* 0x34 */
+       "REFFL",                        /* 0x35 */
+       "REFFU",                        /* 0x36 */
+       "REFFA",                        /* 0x37 */
+       "NREF",                         /* 0x38 */
+       "NREFF",                        /* 0x39 */
+       "NREFFL",                       /* 0x3a */
+       "NREFFU",                       /* 0x3b */
+       "NREFFA",                       /* 0x3c */
+       "IFMATCH",                      /* 0x3d */
+       "UNLESSM",                      /* 0x3e */
+       "SUSPEND",                      /* 0x3f */
+       "IFTHEN",                       /* 0x40 */
+       "GROUPP",                       /* 0x41 */
+       "LONGJMP",                      /* 0x42 */
+       "BRANCHJ",                      /* 0x43 */
+       "EVAL",                         /* 0x44 */
+       "MINMOD",                       /* 0x45 */
+       "LOGICAL",                      /* 0x46 */
+       "RENUM",                        /* 0x47 */
+       "TRIE",                         /* 0x48 */
+       "TRIEC",                        /* 0x49 */
+       "AHOCORASICK",                  /* 0x4a */
+       "AHOCORASICKC",                 /* 0x4b */
+       "GOSUB",                        /* 0x4c */
+       "GOSTART",                      /* 0x4d */
+       "NGROUPP",                      /* 0x4e */
+       "INSUBP",                       /* 0x4f */
+       "DEFINEP",                      /* 0x50 */
+       "ENDLIKE",                      /* 0x51 */
+       "OPFAIL",                       /* 0x52 */
+       "ACCEPT",                       /* 0x53 */
+       "VERB",                         /* 0x54 */
+       "PRUNE",                        /* 0x55 */
+       "MARKPOINT",                    /* 0x56 */
+       "SKIP",                         /* 0x57 */
+       "COMMIT",                       /* 0x58 */
+       "CUTGROUP",                     /* 0x59 */
+       "KEEPS",                        /* 0x5a */
+       "LNBREAK",                      /* 0x5b */
+       "OPTIMIZED",                    /* 0x5c */
+       "PSEUDO",                       /* 0x5d */
        /* ------------ States ------------- */
        "TRIE_next",                    /* REGNODE_MAX +0x01 */
        "TRIE_next_fail",               /* REGNODE_MAX +0x02 */
@@ -714,7 +709,7 @@ EXTCONST U8 PL_varies[] __attribute__deprecated__ = {
 EXTCONST U8 PL_varies_bitmask[];
 #else
 EXTCONST U8 PL_varies_bitmask[] = {
-    0x00, 0x00, 0x00, 0x80, 0x03, 0xF8, 0xF3, 0x3F, 0x13, 0x00, 0x00, 0x00
+    0x00, 0x00, 0x00, 0xC0, 0x01, 0xFC, 0xF9, 0x9F, 0x09, 0x00, 0x00, 0x00
 };
 #endif /* DOINIT */
 
@@ -726,8 +721,8 @@ EXTCONST U8 PL_varies_bitmask[] = {
 EXTCONST U8 PL_simple[] __attribute__deprecated__;
 #else
 EXTCONST U8 PL_simple[] __attribute__deprecated__ = {
-    REG_ANY, SANY, CANY, ANYOF, ANYOF_SYNTHETIC, POSIXD, POSIXL, POSIXU,
-    POSIXA, NPOSIXD, NPOSIXL, NPOSIXU, NPOSIXA,
+    REG_ANY, SANY, CANY, ANYOF, POSIXD, POSIXL, POSIXU, POSIXA, NPOSIXD,
+    NPOSIXL, NPOSIXU, NPOSIXA,
     0
 };
 #endif /* DOINIT */
@@ -736,7 +731,7 @@ EXTCONST U8 PL_simple[] __attribute__deprecated__ = {
 EXTCONST U8 PL_simple_bitmask[];
 #else
 EXTCONST U8 PL_simple_bitmask[] = {
-    0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 #endif /* DOINIT */