This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[PATCH] function to parse Perl statement sequence
[perl5.git] / regexec.c
index 35ef8d4..e569a91 100644 (file)
--- a/regexec.c
+++ b/regexec.c
 /* TODO: Combine JUMPABLE and HAS_TEXT to cache OP(rn) */
 
 /* for use after a quantifier and before an EXACT-like node -- japhy */
-/* it would be nice to rework regcomp.sym to generate this stuff. sigh */
+/* it would be nice to rework regcomp.sym to generate this stuff. sigh
+ *
+ * NOTE that *nothing* that affects backtracking should be in here, specifically
+ * VERBS must NOT be included. JUMPABLE is used to determine  if we can ignore a
+ * node that is in between two EXACT like nodes when ascertaining what the required
+ * "follow" character is. This should probably be moved to regex compile time
+ * although it may be done at run time beause of the REF possibility - more
+ * investigation required. -- demerphq
+*/
 #define JUMPABLE(rn) (      \
     OP(rn) == OPEN ||       \
     (OP(rn) == CLOSE && (!cur_eval || cur_eval->u.eval.close_paren != ARG(rn))) || \
     OP(rn) == EVAL ||   \
     OP(rn) == SUSPEND || OP(rn) == IFMATCH || \
     OP(rn) == PLUS || OP(rn) == MINMOD || \
-    OP(rn) == KEEPS || (PL_regkind[OP(rn)] == VERB) || \
+    OP(rn) == KEEPS || \
     (PL_regkind[OP(rn)] == CURLY && ARG1(rn) > 0) \
 )
 #define IS_EXACT(rn) (PL_regkind[OP(rn)] == EXACT)
@@ -3967,7 +3975,24 @@ S_regmatch(pTHX_ regmatch_info *reginfo, regnode *prog)
                COP * const ocurcop = PL_curcop;
                PAD *old_comppad;
                char *saved_regeol = PL_regeol;
-           
+               struct re_save_state saved_state;
+
+               /* To not corrupt the existing regex state while executing the
+                * eval we would normally put it on the save stack, like with
+                * save_re_context. However, re-evals have a weird scoping so we
+                * can't just add ENTER/LEAVE here. With that, things like
+                *
+                *    (?{$a=2})(a(?{local$a=$a+1}))*aak*c(?{$b=$a})
+                *
+                * would break, as they expect the localisation to be unwound
+                * only when the re-engine backtracks through the bit that
+                * localised it.
+                *
+                * What we do instead is just saving the state in a local c
+                * variable.
+                */
+               Copy(&PL_reg_state, &saved_state, 1, struct re_save_state);
+
                n = ARG(scan);
                PL_op = (OP_4tree*)rexi->data->data[n];
                DEBUG_STATE_r( PerlIO_printf(Perl_debug_log, 
@@ -3989,6 +4014,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, regnode *prog)
                    PUTBACK;
                }
 
+               Copy(&saved_state, &PL_reg_state, 1, struct re_save_state);
+
                PL_op = oop;
                PAD_RESTORE_LOCAL(old_comppad);
                PL_curcop = ocurcop;