Save the regexp engine state as 1 block on the save stack.
Nicholas Clark [Wed, 5 Apr 2006 21:40:11 +0000 (21:40 +0000)]
p4raw-id: //depot/perl@27728

regcomp.c
regexp.h
scope.c
scope.h

index 3e939df..982fc7d 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -6167,50 +6167,65 @@ void
 Perl_save_re_context(pTHX)
 {
     dVAR;
-    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 */
+
+    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);
+
+    state->re_state_reg_flags = PL_reg_flags;
+    state->re_state_bostr = PL_bostr;
+    state->re_state_reginput = PL_reginput;
+    state->re_state_regbol = PL_regbol;
+    state->re_state_regeol = PL_regeol;
+    state->re_state_regstartp = PL_regstartp;
+    state->re_state_regendp = PL_regendp;
+    state->re_state_reglastparen = PL_reglastparen;
+    state->re_state_reglastcloseparen = PL_reglastcloseparen;
+    state->re_state_regtill = PL_regtill;
+    state->re_state_reg_start_tmp = PL_reg_start_tmp;
+    state->re_state_reg_start_tmpl = PL_reg_start_tmpl;
+    state->re_state_reg_eval_set = PL_reg_eval_set;
+    state->re_state_regnarrate = PL_regnarrate;
+    state->re_state_regindent = PL_regindent;
+    state->re_state_reg_call_cc = PL_reg_call_cc;
+    state->re_state_reg_re = PL_reg_re;
+    state->re_state_reg_ganch = PL_reg_ganch;
+    state->re_state_reg_sv = PL_reg_sv;
+    state->re_state_reg_match_utf8 = PL_reg_match_utf8;
+    state->re_state_reg_magic = PL_reg_magic;
+    state->re_state_reg_oldpos = PL_reg_oldpos;
+    state->re_state_reg_oldcurpm = PL_reg_oldcurpm;
+    state->re_state_reg_curpm = PL_reg_curpm;
+    state->re_state_reg_oldsaved = PL_reg_oldsaved;
+    state->re_state_reg_oldsavedlen = PL_reg_oldsavedlen;
+    state->re_state_reg_maxiter = PL_reg_maxiter;
+    state->re_state_reg_leftiter = PL_reg_leftiter;
+    state->re_state_reg_poscache = PL_reg_poscache;
+    state->re_state_reg_poscache_size = PL_reg_poscache_size;
+    state->re_state_regsize = PL_regsize;
+#ifdef DEBUGGING
+    state->re_state_reg_starttry = PL_reg_starttry;
+#endif
+#ifdef PERL_OLD_COPY_ON_WRITE
+    state->re_state_nrs = PL_nrs;
+#endif
+
     PL_reg_start_tmp = 0;
-    SAVEI32(PL_reg_start_tmpl);                /* from regexec.c */
     PL_reg_start_tmpl = 0;
-    SAVEI32(PL_reg_eval_set);          /* from regexec.c */
-    SAVEI32(PL_regnarrate);            /* from regexec.c */
-    SAVEINT(PL_regindent);             /* 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 = NULL;
-    SAVEI32(PL_reg_oldsavedlen);       /* old length of saved substr during match */
     PL_reg_oldsavedlen = 0;
-#ifdef PERL_OLD_COPY_ON_WRITE
-    SAVESPTR(PL_nrs);
-    PL_nrs = NULL;
-#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 = NULL;
-    SAVEI32(PL_reg_poscache_size);     /* size of pos cache of WHILEM */
     PL_reg_poscache_size = 0;
-    SAVEI32(PL_regsize);               /* from regexec.c */
+#ifdef PERL_OLD_COPY_ON_WRITE
+    PL_nrs = NULL;
+#endif
 
     /* Save $1..$n (#18107: UTF-8 s/(\w+)/uc($1)/e); AMS 20021106. */
     if (PL_curpm) {
index a9c2130..178feca 100644 (file)
--- a/regexp.h
+++ b/regexp.h
@@ -287,3 +287,53 @@ typedef struct regmatch_slab {
     regmatch_state states[PERL_REGMATCH_SLAB_SLOTS];
     struct regmatch_slab *prev, *next;
 } regmatch_slab;
+
+struct re_save_state {
+    U32 re_state_reg_flags;            /* from regexec.c */
+    char *re_state_bostr;
+    char *re_state_reginput;           /* String-input pointer. */
+    char *re_state_regbol;             /* Beginning of input, for ^ check. */
+    char *re_state_regeol;             /* End of input, for $ check. */
+    I32 *re_state_regstartp;           /* Pointer to startp array. */
+    I32 *re_state_regendp;             /* Ditto for endp. */
+    U32 *re_state_reglastparen;                /* Similarly for lastparen. */
+    U32 *re_state_reglastcloseparen;   /* Similarly for lastcloseparen. */
+    char *re_state_regtill;            /* How far we are required to go. */
+    char **re_state_reg_start_tmp;     /* from regexec.c */
+    U32 re_state_reg_start_tmpl;       /* from regexec.c */
+    I32 re_state_reg_eval_set;         /* from regexec.c */
+    I32 re_state_regnarrate;           /* from regexec.c */
+    int re_state_regindent;            /* from regexec.c */
+    struct re_cc_state *re_state_reg_call_cc;          /* from regexec.c */
+    regexp *re_state_reg_re;           /* from regexec.c */
+    char *re_state_reg_ganch;          /* from regexec.c */
+    SV *re_state_reg_sv;               /* from regexec.c */
+    bool re_state_reg_match_utf8;      /* from regexec.c */
+    MAGIC *re_state_reg_magic;         /* from regexec.c */
+    I32 re_state_reg_oldpos;           /* from regexec.c */
+    PMOP *re_state_reg_oldcurpm;       /* from regexec.c */
+    PMOP *re_state_reg_curpm;          /* from regexec.c */
+    char *re_state_reg_oldsaved;       /* old saved substr during match */
+    STRLEN re_state_reg_oldsavedlen;   /* old length of saved substr during match */
+    I32 re_state_reg_maxiter;          /* max wait until caching pos */
+    I32 re_state_reg_leftiter;         /* wait until caching pos */
+    char *re_state_reg_poscache;       /* cache of pos of WHILEM */
+    STRLEN re_state_reg_poscache_size; /* size of pos cache of WHILEM */
+    I32 re_state_regsize;              /* from regexec.c */
+    char *re_state_reg_starttry;       /* from regexec.c */
+#ifdef PERL_OLD_COPY_ON_WRITE
+    SV *re_state_nrs;
+#endif
+};
+
+#define SAVESTACK_ALLOC_FOR_RE_SAVE_STATE \
+       (1 + ((sizeof(struct re_save_state) - 1) / sizeof(*PL_savestack)))
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ *
+ * ex: set ts=8 sts=4 sw=4 noet:
+ */
diff --git a/scope.c b/scope.c
index fcdf86f..d7e4d5e 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -984,6 +984,59 @@ Perl_leave_scope(pTHX_ I32 base)
            i = SSPOPINT;
            CopARYBASE_set((COP *)ptr, i);
            break;
+       case SAVEt_RE_STATE:
+           {
+               const struct re_save_state *const state
+                   = (struct re_save_state *)
+                   (PL_savestack + PL_savestack_ix
+                    - SAVESTACK_ALLOC_FOR_RE_SAVE_STATE);
+               PL_savestack_ix -= SAVESTACK_ALLOC_FOR_RE_SAVE_STATE;
+
+               PL_reg_flags = state->re_state_reg_flags;
+               PL_bostr = state->re_state_bostr;
+               PL_reginput = state->re_state_reginput;
+               PL_regbol = state->re_state_regbol;
+               PL_regeol = state->re_state_regeol;
+               PL_regstartp = state->re_state_regstartp;
+               PL_regendp = state->re_state_regendp;
+               PL_reglastparen = state->re_state_reglastparen;
+               PL_reglastcloseparen = state->re_state_reglastcloseparen;
+               PL_regtill = state->re_state_regtill;
+               if (PL_reg_start_tmp != state->re_state_reg_start_tmp) {
+                   Safefree(PL_reg_start_tmp);
+                   PL_reg_start_tmp = state->re_state_reg_start_tmp;
+               }
+               PL_reg_start_tmpl = state->re_state_reg_start_tmpl;
+               PL_reg_eval_set = state->re_state_reg_eval_set;
+               PL_regnarrate = state->re_state_regnarrate;
+               PL_regindent = state->re_state_regindent;
+               PL_reg_call_cc = state->re_state_reg_call_cc;
+               PL_reg_re = state->re_state_reg_re;
+               PL_reg_ganch = state->re_state_reg_ganch;
+               PL_reg_sv = state->re_state_reg_sv;
+               PL_reg_match_utf8 = state->re_state_reg_match_utf8;
+               PL_reg_magic = state->re_state_reg_magic;
+               PL_reg_oldpos = state->re_state_reg_oldpos;
+               PL_reg_oldcurpm = state->re_state_reg_oldcurpm;
+               PL_reg_curpm = state->re_state_reg_curpm;
+               PL_reg_oldsaved = state->re_state_reg_oldsaved;
+               PL_reg_oldsavedlen = state->re_state_reg_oldsavedlen;
+               PL_reg_maxiter = state->re_state_reg_maxiter;
+               PL_reg_leftiter = state->re_state_reg_leftiter;
+               if (PL_reg_poscache != state->re_state_reg_poscache) {
+                   Safefree(PL_reg_poscache);
+                   PL_reg_poscache = state->re_state_reg_poscache;
+               }
+               PL_reg_poscache_size = state->re_state_reg_poscache_size;
+               PL_regsize = state->re_state_regsize;
+#ifdef DEBUGGING
+               PL_reg_starttry = state->re_state_reg_starttry;
+#endif
+#ifdef PERL_OLD_COPY_ON_WRITE
+               PL_nrs = state->re_state_nrs;
+#endif
+           }
+           break;
        default:
            Perl_croak(aTHX_ "panic: leave_scope inconsistency");
        }
diff --git a/scope.h b/scope.h
index 50fd752..772eb41 100644 (file)
--- a/scope.h
+++ b/scope.h
@@ -50,6 +50,7 @@
 #define SAVEt_SET_SVFLAGS      39
 #define SAVEt_SAVESWITCHSTACK  40
 #define SAVEt_COP_ARYBASE      41
+#define SAVEt_RE_STATE         42
 
 #ifndef SCOPE_SAVES_SIGNAL_MASK
 #define SCOPE_SAVES_SIGNAL_MASK 0