diff options
author | Yves Orton <demerphq@gmail.com> | 2023-01-14 14:38:38 +0100 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2023-03-13 21:26:08 +0800 |
commit | 59db194299c94c6707095797c3df0e2f67ff82b2 (patch) | |
tree | c016d5aabc09854ca74f22570efe64a72847018b /regexp.h | |
parent | 38508ce8fc3a1bd12a3bb65e9d4ceb9b396a18db (diff) | |
download | perl-59db194299c94c6707095797c3df0e2f67ff82b2.tar.gz |
regexec.c - make REF into a backtracking state
This way we can do the required paren restoration only when it is in use. When
we match a REF type node which is potentially a reference to an unclosed paren
we push the match context information, currently for "everything", but in a
future patch we can teach it to be more efficient by adding a new parameter to
the REF regop to track which parens it should save.
This converts the backtracking changes from the previous commit, so that it is
run only when specifically enabled via the define RE_PESSIMISTIC_PARENS which
is by default 0. We don't make the new fields in the struct conditional as the
stack frames are large and our changes don't make any real difference and it
keeps things simpler to not have conditional members, especially since some of
the structures have to line up with each other.
If enabling RE_PESSIMISTIC_PARENS fixes a backtracking bug then it means
something is sensitive to us not necessarily restoring the parens properly on
failure. We make some assumptions that the paren state after a failing state
will be corrected by a future successful state, or that the state of the
parens is irrelevant as we will fail anyway. This can be made not true by
EVAL, backrefs, and potentially some other scenarios. Thus I have left this
inefficient logic in place but guarded by the flag.
Diffstat (limited to 'regexp.h')
-rw-r--r-- | regexp.h | 6 |
1 files changed, 5 insertions, 1 deletions
@@ -958,7 +958,7 @@ typedef struct regmatch_state { struct { U32 paren; CHECKPOINT cp; - CHECKPOINT lastcp; /* remember current savestack index */ + CHECKPOINT lastcp; /* remember current savestack index */ U32 lastparen; U32 lastcloseparen; char *maxpos; /* highest possible point in string to match */ @@ -969,6 +969,10 @@ typedef struct regmatch_state { struct next_matchable_info Binfo; } curly; /* and CURLYN/PLUS/STAR */ + struct { + CHECKPOINT cp; + CHECKPOINT lastcp; + } backref; /* REF and friends */ } u; } regmatch_state; |