add lex_re_reparsing boolean to yy_parser struct
authorDavid Mitchell <davem@iabyn.com>
Tue, 9 Apr 2013 16:17:16 +0000 (17:17 +0100)
committerDavid Mitchell <davem@iabyn.com>
Fri, 12 Apr 2013 10:29:55 +0000 (11:29 +0100)
When re-parsing a pattern for run-time (?{}) code blocks,
we end up with the EVAL_RE_REPARSING flag set in PL_in_eval.
Currently we clear this flag as soon as scan_str() returns, to ensure that
it's not set if we happen to parse further patterns (e.g. within the
(?{ ... }) code itself.

However, a soon-to-be-applied bugfix requires us to know the reparsing
state beyond this point. To solve this, we add a new boolean flag to the
parser struct, which is set from PL_in_eval in S_sublex_push() (with the
old value being saved). This allows us to have the flag around for the
entire pattern string parsing phase, without it affecting nested pattern
compilation.

parser.h
regcomp.c
regexec.c
toke.c

index 05735bf..e7b887e 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -71,7 +71,7 @@ typedef struct yy_parser {
     char       multi_open;     /* delimiter of said string */
     char       multi_close;    /* delimiter of said string */
     bool       preambled;
-    /*** 8-bit hole ***/
+    bool        lex_re_reparsing; /* we're doing G_RE_REPARSING */
     I32                lex_allbrackets;/* (), [], {}, ?: bracket count */
     SUBLEXINFO sublex_info;
     LEXSHARED  *lex_shared;
index 0849a97..0853815 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -5652,8 +5652,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
     else if ((pm_flags & PMf_USE_RE_EVAL)
                /* this second condition covers the non-regex literal case,
                 * i.e.  $foo =~ '(?{})'. */
-               || ( !(PL_in_eval & EVAL_RE_REPARSING) && IN_PERL_COMPILETIME
-                   && (PL_hints & HINT_RE_EVAL))
+               || (IN_PERL_COMPILETIME && (PL_hints & HINT_RE_EVAL))
     )
        runtime_code = S_has_runtime_code(aTHX_ pRExC_state, expr, pm_flags,
                            exp, plen);
index bb6c958..45bd09e 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -4878,8 +4878,6 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                 */
                Copy(&PL_reg_state, &saved_state, 1, struct re_save_state);
 
-                PL_in_eval &= ~EVAL_RE_REPARSING;
-
                if (!caller_cv)
                    caller_cv = find_runcv(NULL);
 
diff --git a/toke.c b/toke.c
index 4581bfd..e97f3fa 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -2525,6 +2525,7 @@ S_sublex_push(pTHX)
     SAVEGENERICPV(PL_lex_brackstack);
     SAVEGENERICPV(PL_lex_casestack);
     SAVEGENERICPV(PL_parser->lex_shared);
+    SAVEBOOL(PL_parser->lex_re_reparsing);
 
     /* The here-doc parser needs to be able to peek into outer lexing
        scopes to find the body of the here-doc.  So we put PL_linestr and
@@ -2568,6 +2569,9 @@ S_sublex_push(pTHX)
     else
        PL_lex_inpat = NULL;
 
+    PL_parser->lex_re_reparsing = cBOOL(PL_in_eval & EVAL_RE_REPARSING);
+    PL_in_eval &= ~EVAL_RE_REPARSING;
+
     return '(';
 }
 
@@ -9517,9 +9521,6 @@ S_scan_pat(pTHX_ char *start, I32 type)
     s = scan_str(start,!!PL_madskills,FALSE, (PL_in_eval & EVAL_RE_REPARSING),
                        TRUE /* look for escaped bracketed metas */ );
 
-    /* this was only needed for the initial scan_str; set it to false
-     * so that any (?{}) code blocks etc are parsed normally */
-    PL_in_eval &= ~EVAL_RE_REPARSING;
     if (!s) {
        const char * const delimiter = skipspace(start);
        Perl_croak(aTHX_