From: Nicholas Clark Date: Wed, 5 Apr 2006 21:40:11 +0000 (+0000) Subject: Save the regexp engine state as 1 block on the save stack. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=1ade1aa1ca2b2fe7e0085ec2cd022693e0d7a0d6;p=p5sagit%2Fp5-mst-13.2.git Save the regexp engine state as 1 block on the save stack. p4raw-id: //depot/perl@27728 --- diff --git a/regcomp.c b/regcomp.c index 3e939df..982fc7d 100644 --- 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) { diff --git a/regexp.h b/regexp.h index a9c2130..178feca 100644 --- 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 --- 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 --- 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