re_intuit_start(): simplify other=anchored block
authorDavid Mitchell <davem@iabyn.com>
Fri, 31 Jan 2014 23:58:14 +0000 (23:58 +0000)
committerDavid Mitchell <davem@iabyn.com>
Sat, 8 Feb 2014 12:59:51 +0000 (12:59 +0000)
This block of code calculates 2 limits: last, last2; plus a third,
last1 = min(last, last2)

It turns out that (as explained below), last is always <= last2, which
allows us to simplify the code. In particular, this means that last always
equals last1, so eliminate last1 and always use last instead.
At the same time, rename last2 to last1, so the vars have the same names /
meanings as in the other=float branch.

Here's the math (ignoring char/byte differences for simplicity's sake):

    last  = s (== start of just matched float substr)
                    - float_min_offset
                    +  anchored_offset
    last2 = strend - minlen + anchored_offset

Let

    delta = last2 - last

          =   (strend - minlen + anchored_offset)
            - (s - float_min_offset + anchored_offset)

          =  (strend  - s) - (minlen - float_min_offset) [1]

Now, we've just matched a floating substring at s. But this previous
match was constrained to *end* no later than end_shift chars before
strend,  so it was constrained to *start* no later than
end_shift + length(float) chars before strend; i.e.

    strend - s >= end_shift + length(float) [2].

Also, more or less by definition,

    minlen = float_min_offset + length(float) + end_shift
or
    end_shift = minlen - float_min_offset - length(float) [2]

So, combining [2] and [3] gives

    strend - s >= (minlen - float_min_offset - length(float)) + length(float)
    strend - s >= minlen - float_min_offset

Therefore, from [1],

    delta >= 0

regexec.c

index 14316fe..9ad2dca 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -917,8 +917,7 @@ Perl_re_intuit_start(pTHX_
        if (prog->substrs->check_ix) {
          do_other_anchored:
            {
-               char * last;
-               char *last1, *last2;
+               char *last, *last1;
                char * const saved_s = s;
                SV* must;
 
@@ -940,18 +939,15 @@ Perl_re_intuit_start(pTHX_
                    s = other_last;
 
                 assert(prog->minlen > prog->anchored_offset);
-               last2 = last1 = HOP3c(strend,
+               last1 = HOP3c(strend,
                                 prog->anchored_offset-prog->minlen, strbeg);
-               assert (last <= last2);
-               if (last < last1)
-                   last1 = last;
  
                /* On end-of-str: see comment below. */
                must = utf8_target ? prog->anchored_utf8 : prog->anchored_substr;
                 assert(SvPOK(must));
                 s = fbm_instr(
                     (unsigned char*)s,
-                    HOP3(last1 + SvCUR(must), -(SvTAIL(must)!=0), strbeg),
+                    HOP3(last + SvCUR(must), -(SvTAIL(must)!=0), strbeg),
                     must,
                     multiline ? FBMrf_MULTILINE : 0
                 );
@@ -965,7 +961,7 @@ Perl_re_intuit_start(pTHX_
                
                            
                if (!s) {
-                   if (last1 >= last2) {
+                   if (last >= last1) {
                        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                                                ", giving up...\n"));
                        goto fail_finish;
@@ -973,7 +969,7 @@ Perl_re_intuit_start(pTHX_
                    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                        ", trying floating at offset %ld...\n",
                        (long)(HOP3c(saved_s, 1, strend) - i_strpos)));
-                   other_last = HOP3c(last1, 1, strend);
+                   other_last = HOP3c(last, 1, strend);
                    rx_origin = HOP4c(last, 1 - prog->anchored_offset, strbeg, strend);
                    goto restart;
                }