pp_match(): combine intuit and regexec branches
authorDavid Mitchell <davem@iabyn.com>
Sun, 16 Jun 2013 15:01:22 +0000 (16:01 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sun, 28 Jul 2013 09:33:35 +0000 (10:33 +0100)
There was some code that looked roughly like:

    if (can_match_on_intuit_only) {
        ....
        goto yup;
    }
    if (!regexec())
        goto ret_no;

  gotcha:
    A; B;
    if (simple)
        RETURNYES;
    X; Y;
    RETURN;

  yup:
    A;
    if (!simple)
        goto gotcha;
    B;
    RETURNYES

Refactor it to look like

    if (can_match_on_intuit_only) {
        ....
        goto gotcha;
    }
    if (!regexec())
        goto ret_no;

  gotcha:
    A; B;
    if (simple)
        RETURNYES;
    X; Y;
    RETURN;

As well as simplifying the code, it also avoids duplicating some work
(the 'A' above was done twice sometimes) - harmless but less efficient.

pp_hot.c

index f6965da..ceb934d 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1442,6 +1442,9 @@ PP(pp_match)
        if ( (RX_EXTFLAGS(rx) & RXf_CHECK_ALL)
             && !SvROK(TARG))   /* Cannot trust since INTUIT cannot guess ^ */
         {
+            /* we can match based purely on the result of INTUIT.
+             * Fix up all the things that won't get set because we skip
+             * calling regexec() */
             assert(!RX_NPARENS(rx));
             /* match via INTUIT shouldn't have any captures.
              * Let @-, @+, $^N know */
@@ -1458,13 +1461,14 @@ PP(pp_match)
                 RX_MATCH_UTF8(rx)
                     ? (char*)utf8_hop((U8*)s, RX_MINLENRET(rx)) - truebase
                     : s - truebase + RX_MINLENRET(rx);
-           goto yup;
+           goto gotcha;
         }
     }
     if (!CALLREGEXEC(rx, (char*)s, (char *)strend, (char*)truebase,
                     minmatch, TARG, NUM2PTR(void*, gpos), r_flags))
        goto ret_no;
 
+  gotcha:
     PL_curpm = pm;
     if (dynpm->op_pmflags & PMf_ONCE) {
 #ifdef USE_ITHREADS
@@ -1474,7 +1478,6 @@ PP(pp_match)
 #endif
     }
 
-  gotcha:
     if (rxtainted)
        RX_MATCH_TAINTED_on(rx);
     TAINT_IF(RX_MATCH_TAINTED(rx));
@@ -1500,6 +1503,8 @@ PP(pp_match)
        RETPUSHYES;
     }
 
+    /* push captures on stack */
+
     {
        const I32 nparens = RX_NPARENS(rx);
        I32 i = (global && !nparens) ? 1 : 0;
@@ -1534,27 +1539,7 @@ PP(pp_match)
        LEAVE_SCOPE(oldsave);
        RETURN;
     }
-
-yup:                                   /* Confirmed by INTUIT */
-    if (rxtainted)
-       RX_MATCH_TAINTED_on(rx);
-    TAINT_IF(RX_MATCH_TAINTED(rx));
-    PL_curpm = pm;
-    if (dynpm->op_pmflags & PMf_ONCE) {
-#ifdef USE_ITHREADS
-        SvREADONLY_on(PL_regex_pad[dynpm->op_pmoffset]);
-#else
-        dynpm->op_pmflags |= PMf_USED;
-#endif
-    }
-
-
-    if (global) {
-       goto gotcha;
-    }
-
-    LEAVE_SCOPE(oldsave);
-    RETPUSHYES;
+    /* NOTREACHED */
 
 nope:
 ret_no: