diff options
author | Karl Williamson <public@khwilliamson.com> | 2013-07-06 12:26:43 -0600 |
---|---|---|
committer | Karl Williamson <public@khwilliamson.com> | 2013-07-16 13:58:06 -0600 |
commit | a0316a6cd4a14261beb22d95530d5763e8b6756b (patch) | |
tree | 26f2d40eaca022f4185e709ea341944aa3d9fef5 /embed.fnc | |
parent | d212d2222867b5b63a5f6d8c3243d0d45a26988c (diff) | |
download | perl-a0316a6cd4a14261beb22d95530d5763e8b6756b.tar.gz |
Reinstate + fix "Revert "regcomp.c: Add a constant 0 element before inversion lists" "
This reverts commit de353015643cf10b437d714d3483c1209e079916 which
reverted 533c4e2f08b42d977e5004e823d4849f7473d2d0, thus reinstating it,
plus this commit adds a fix to get it to pass under Address Sanitizer.
The root cause of the problem is that there are two measures of the
length of an inversion list. One is SvCUR(), and the other is
invlist_len(). The original commit caused these to get off-by-one in
some cases. The ultimate solution is to only store one value, and
return the other one based off that. Rather than redo the whole branch,
I've taken an easier way out, which is to add a dummy element at the end
of some inversion lists, so that they aren't off-by-one. Then the other
patches from the original branch will be applied. Each will be
tested with Address Sanitizer. Then the work to fix the underlying
problem will be done.
The original commit's message was:
This commit is the first step to separating the header from the body of
inversion lists. Doing so will allow the compiled-in inversion lists to
be fully read-only.
To invert an inversion list, one simply unshifts a 0 to the front of it
if one is not there, and shifts off the 0 if it does have one.
The current data structure reserves an element at the beginning of each
inversion list that is either 0 or 1. If 0, it means the inversion list
begins there; if 1, it means the inversion list starts at the next
element. Inverting involves flipping this bit.
This commit changes the structure so that there is an additional element
just after the element that flips. This new element is always 0, and
the flipping element now says whether the inversion list begins at the
constant 0 element, or the one after that.
Doing this allows the flipping element to be separated in later commits
from the body of the inversion list, which will always begin with the
constant 0 element. That means that the body of the inversion list can
be const.
Diffstat (limited to 'embed.fnc')
-rw-r--r-- | embed.fnc | 10 |
1 files changed, 7 insertions, 3 deletions
@@ -1089,7 +1089,7 @@ Ap |SV* |regclass_swash |NULLOK const regexp *prog \ |NULLOK SV **listsvp|NULLOK SV **altsvp #ifdef PERL_IN_REGCOMP_C EMsR |SV* |_new_invlist_C_array|NN UV* list -: Not used currently: EXMs |bool |_invlistEQ |NN SV* const a|NN SV* const b|bool complement_b +: Not used currently: EXMs |bool |_invlistEQ |NN SV* const a|NN SV* const b|const bool complement_b #endif Ap |I32 |pregexec |NN REGEXP * const prog|NN char* stringarg \ |NN char* strend|NN char* strbeg|I32 minend \ @@ -1452,9 +1452,13 @@ EiMR |UV |invlist_highest|NN SV* const invlist #endif #if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_UTF8_C) EXmM |void |_invlist_intersection |NN SV* const a|NN SV* const b|NN SV** i -EXpM |void |_invlist_intersection_maybe_complement_2nd|NULLOK SV* const a|NN SV* const b|bool complement_b|NN SV** i +EXpM |void |_invlist_intersection_maybe_complement_2nd \ + |NULLOK SV* const a|NN SV* const b \ + |const bool complement_b|NN SV** i EXmM |void |_invlist_union |NULLOK SV* const a|NN SV* const b|NN SV** output -EXpM |void |_invlist_union_maybe_complement_2nd|NULLOK SV* const a|NN SV* const b|bool complement_b|NN SV** output +EXpM |void |_invlist_union_maybe_complement_2nd \ + |NULLOK SV* const a|NN SV* const b \ + |const bool complement_b|NN SV** output EXmM |void |_invlist_subtract|NN SV* const a|NN SV* const b|NN SV** result EXpM |void |_invlist_invert|NN SV* const invlist EXpM |void |_invlist_invert_prop|NN SV* const invlist |