regexec(): simplify RXf_ANCH_GPOS pos calc
authorDavid Mitchell <davem@iabyn.com>
Fri, 19 Jul 2013 16:10:04 +0000 (17:10 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sun, 28 Jul 2013 09:33:39 +0000 (10:33 +0100)
There are two bits of code in regexec() that do special handling for
RXf_ANCH_GPOS:

First, after setting ganch from pos(), it does a couple of quick-fail
checks:
    fail if s > ganch
    fail if (ganch - gofs) < strbeg
at this point it also updates s to be ganch - gofs, although confusingly,
s in not subsequently used.

Second, when about to call regtry, it calculates a new  start value
(ignoring the old one, s):

    tmps_s = ganch - gofs;

then checks:
    fail if tmp_s < strbeg

As can be seen, these two sets of tests essentially partially duplicate
each other.

This commit moves all the work to the second block of code, which
simplifies things, and makes the first block of code purely about
calculating ganch.

Note that the new condition added by this commit in the second block,

    fail if s > tmp_s (i.e if s > (ganch - gofs))

subsumes both previous conditions, since
a) it is stronger than s > ganch
b) s will be >= strbeg, so tmp_s >= strbeg

regexec.c

index 00ec190..d95355c 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -2419,16 +2419,6 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
            reginfo->ganch = strbeg + mg->mg_len;       /* Defined pos() */
            DEBUG_GPOS_r(PerlIO_printf(Perl_debug_log,
                "GPOS MAGIC: reginfo->ganch = strbeg + %"IVdf"\n",(IV)mg->mg_len));
-
-           if (prog->extflags & RXf_ANCH_GPOS) {
-               if (s > reginfo->ganch)
-                   goto phooey;
-               s = reginfo->ganch - prog->gofs;
-               DEBUG_GPOS_r(PerlIO_printf(Perl_debug_log,
-                    "GPOS ANCH_GPOS: s = ganch - %"UVxf"\n",(UV)prog->gofs));
-               if (s < strbeg)
-                   goto phooey;
-           }
        }
        else {                          /* pos() not defined */
            reginfo->ganch = strbeg;
@@ -2542,7 +2532,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
            and we only enter this block when the same bit is set. */
         char *tmp_s = reginfo->ganch - prog->gofs;
 
-       if (tmp_s >= strbeg && regtry(reginfo, &tmp_s))
+       if (s <= tmp_s && regtry(reginfo, &tmp_s))
            goto got_it;
        goto phooey;
     }