This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Revert "Include time.h when testing for clock_xxx functions and syscalls"
[perl5.git] / regexec.c
index cae8a19..1d8e33a 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -272,7 +272,7 @@ static regmatch_state * S_push_slab(pTHX);
  * are needed for the regexp context stack bookkeeping. */
 
 STATIC CHECKPOINT
-S_regcppush(pTHX_ const regexp *rex, I32 parenfloor, U32 maxopenparen, int depth)
+S_regcppush(pTHX_ const regexp *rex, I32 parenfloor, U32 maxopenparen _pDEPTH)
 {
     const int retval = PL_savestack_ix;
     const int paren_elems_to_push =
@@ -358,7 +358,7 @@ S_regcppush(pTHX_ const regexp *rex, I32 parenfloor, U32 maxopenparen, int depth
 
 
 STATIC void
-S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p, int depth)
+S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p _pDEPTH)
 {
     UV i;
     U32 paren;
@@ -432,11 +432,13 @@ S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p, int depth)
  * but without popping the stack */
 
 STATIC void
-S_regcp_restore(pTHX_ regexp *rex, I32 ix, U32 *maxopenparen_p, int depth)
+S_regcp_restore(pTHX_ regexp *rex, I32 ix, U32 *maxopenparen_p _pDEPTH)
 {
     I32 tmpix = PL_savestack_ix;
+    PERL_ARGS_ASSERT_REGCP_RESTORE;
+
     PL_savestack_ix = ix;
-    S_regcppop(aTHX_ rex, maxopenparen_p, depth);
+    regcppop(rex, maxopenparen_p);
     PL_savestack_ix = tmpix;
 }
 
@@ -3615,6 +3617,14 @@ S_regtry(pTHX_ regmatch_info *reginfo, char **startposp)
      * above-mentioned test suite tests to succeed.  The common theme
      * on those tests seems to be returning null fields from matches.
      * --jhi updated by dapm */
+
+    /* After encountering a variant of the issue mentioned above I think
+     * the point Ilya was making is that if we properly unwind whenever
+     * we set lastparen to a smaller value then we should not need to do
+     * this every time, only when needed. So if we have tests that fail if
+     * we remove this, then it suggests somewhere else we are improperly
+     * unwinding the lastparen/paren buffers. See UNWIND_PARENS() and
+     * places it is called, and related regcp() routines. - Yves */
 #if 1
     if (prog->nparens) {
        regexp_paren_pair *pp = prog->offs;
@@ -5339,7 +5349,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
     I32 nextchr;   /* is always set to UCHARAT(locinput), or -1 at EOS */
 
     bool result = 0;       /* return value of S_regmatch */
-    int depth = 0;         /* depth of backtrack stack */
+    U32 depth = 0;            /* depth of backtrack stack */
     U32 nochange_depth = 0; /* depth of GOSUB recursion with nochange */
     const U32 max_nochange_depth =
         (3 * rex->nparens > MAX_RECURSE_EVAL_NOCHANGE_DEPTH) ?
@@ -5660,7 +5670,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                    DEBUG_TRIE_EXECUTE_r({
                                 DUMP_EXEC_POS( (char *)uc, scan, utf8_target, depth );
                                 /* HERE */
-                                PerlIO_printf( aTHX_ Perl_debug_log,
+                                PerlIO_printf( Perl_debug_log,
                                     "%*s%sState: %4"UVxf" Accepted: %c ",
                                     INDENT_CHARS(depth), "", PL_colors[4],
                                    (UV)state, (accepted ? 'Y' : 'N'));
@@ -6760,7 +6770,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
             }
 
             /* Save all the positions seen so far. */
-            ST.cp = S_regcppush(aTHX_ rex, 0, maxopenparen, depth);
+            ST.cp = regcppush(rex, 0, maxopenparen);
             REGCP_SET(ST.lastcp);
 
             /* and then jump to the code we share with EVAL */
@@ -6785,7 +6795,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                CV *newcv;
 
                /* save *all* paren positions */
-               S_regcppush(aTHX_ rex, 0, maxopenparen, depth);
+                regcppush(rex, 0, maxopenparen);
                REGCP_SET(runops_cp);
 
                if (!caller_cv)
@@ -6951,7 +6961,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                 * in the regexp code uses the pad ! */
                PL_op = oop;
                PL_curcop = ocurcop;
-               S_regcp_restore(aTHX_ rex, runops_cp, &maxopenparen, depth);
+                regcp_restore(rex, runops_cp, &maxopenparen);
                PL_curpm = PL_reg_curpm;
 
                if (logical != 2)
@@ -7019,7 +7029,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                                              * close_paren only for GOSUB */
                 ST.prev_recurse_locinput= NULL; /* only used for GOSUB */
                 /* Save all the seen positions so far. */
-                ST.cp = S_regcppush(aTHX_ rex, 0, maxopenparen, depth);
+                ST.cp = regcppush(rex, 0, maxopenparen);
                 REGCP_SET(ST.lastcp);
                 /* and set maxopenparen to 0, since we are starting a "fresh" match */
                 maxopenparen = 0;
@@ -7119,7 +7129,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
            rexi = RXi_GET(rex); 
 
            REGCP_UNWIND(ST.lastcp);
-           S_regcppop(aTHX_ rex, &maxopenparen, depth);
+            regcppop(rex, &maxopenparen);
            cur_eval = ST.prev_eval;
            cur_curlyx = ST.prev_curlyx;
 
@@ -7392,8 +7402,7 @@ NULL
            /* First just match a string of min A's. */
 
            if (n < min) {
-               ST.cp = S_regcppush(aTHX_ rex, cur_curlyx->u.curlyx.parenfloor,
-                                    maxopenparen, depth);
+                ST.cp = regcppush(rex, cur_curlyx->u.curlyx.parenfloor, maxopenparen);
                cur_curlyx->u.curlyx.lastloc = locinput;
                REGCP_SET(ST.lastcp);
 
@@ -7503,8 +7512,8 @@ NULL
            if (cur_curlyx->u.curlyx.minmod) {
                ST.save_curlyx = cur_curlyx;
                cur_curlyx = cur_curlyx->u.curlyx.prev_curlyx;
-               ST.cp = S_regcppush(aTHX_ rex, ST.save_curlyx->u.curlyx.parenfloor,
-                            maxopenparen, depth);
+                ST.cp = regcppush(rex, ST.save_curlyx->u.curlyx.parenfloor,
+                            maxopenparen);
                REGCP_SET(ST.lastcp);
                PUSH_YES_STATE_GOTO(WHILEM_B_min, ST.save_curlyx->u.curlyx.B,
                                     locinput);
@@ -7514,8 +7523,8 @@ NULL
            /* Prefer A over B for maximal matching. */
 
            if (n < max) { /* More greed allowed? */
-               ST.cp = S_regcppush(aTHX_ rex, cur_curlyx->u.curlyx.parenfloor,
-                            maxopenparen, depth);
+                ST.cp = regcppush(rex, cur_curlyx->u.curlyx.parenfloor,
+                            maxopenparen);
                cur_curlyx->u.curlyx.lastloc = locinput;
                REGCP_SET(ST.lastcp);
                PUSH_STATE_GOTO(WHILEM_A_max, A, locinput);
@@ -7542,7 +7551,7 @@ NULL
            /* FALLTHROUGH */
        case WHILEM_A_pre_fail: /* just failed to match even minimal A */
            REGCP_UNWIND(ST.lastcp);
-           S_regcppop(aTHX_ rex, &maxopenparen, depth);
+            regcppop(rex, &maxopenparen);
            cur_curlyx->u.curlyx.lastloc = ST.save_lastloc;
            cur_curlyx->u.curlyx.count--;
            CACHEsayNO;
@@ -7550,7 +7559,7 @@ NULL
 
        case WHILEM_A_max_fail: /* just failed to match A in a maximal match */
            REGCP_UNWIND(ST.lastcp);
-           S_regcppop(aTHX_ rex, &maxopenparen, depth); /* Restore some previous $<digit>s? */
+            regcppop(rex, &maxopenparen); /* Restore some previous $<digit>s? */
             DEBUG_EXECUTE_r(Perl_re_exec_indentf( aTHX_  "whilem: failed, trying continuation...\n",
                 depth)
            );
@@ -7576,7 +7585,7 @@ NULL
        case WHILEM_B_min_fail: /* just failed to match B in a minimal match */
            cur_curlyx = ST.save_curlyx;
            REGCP_UNWIND(ST.lastcp);
-           S_regcppop(aTHX_ rex, &maxopenparen, depth);
+            regcppop(rex, &maxopenparen);
 
            if (cur_curlyx->u.curlyx.count >= /*max*/ARG2(cur_curlyx->u.curlyx.me)) {
                /* Maximum greed exceeded */
@@ -7598,8 +7607,8 @@ NULL
            );
            /* Try grabbing another A and see if it helps. */
            cur_curlyx->u.curlyx.lastloc = locinput;
-           ST.cp = S_regcppush(aTHX_ rex, cur_curlyx->u.curlyx.parenfloor,
-                            maxopenparen, depth);
+            ST.cp = regcppush(rex, cur_curlyx->u.curlyx.parenfloor,
+                            maxopenparen);
            REGCP_SET(ST.lastcp);
            PUSH_STATE_GOTO(WHILEM_A_min,
                /*A*/ NEXTOPER(ST.save_curlyx->u.curlyx.me) + EXTRA_STEP_2ARGS,
@@ -7964,7 +7973,7 @@ NULL
                 char *li = locinput;
                minmod = 0;
                if (ST.min &&
-                        regrepeat(rex, &li, ST.A, reginfo, ST.min, depth)
+                        regrepeat(rex, &li, ST.A, reginfo, ST.min)
                             < ST.min)
                    sayNO;
                 SET_locinput(li);
@@ -8001,7 +8010,7 @@ NULL
                 /* avoid taking address of locinput, so it can remain
                  * a register var */
                 char *li = locinput;
-               ST.count = regrepeat(rex, &li, ST.A, reginfo, ST.max, depth);
+                ST.count = regrepeat(rex, &li, ST.A, reginfo, ST.max);
                if (ST.count < ST.min)
                    sayNO;
                 SET_locinput(li);
@@ -8084,7 +8093,7 @@ NULL
                      * locinput matches */
                     char *li = ST.oldloc;
                    ST.count += n;
-                   if (regrepeat(rex, &li, ST.A, reginfo, n, depth) < n)
+                    if (regrepeat(rex, &li, ST.A, reginfo, n) < n)
                        sayNO;
                     assert(n == REG_INFTY || locinput == li);
                }
@@ -8105,7 +8114,7 @@ NULL
            /* failed -- move forward one */
             {
                 char *li = locinput;
-                if (!regrepeat(rex, &li, ST.A, reginfo, 1, depth)) {
+                if (!regrepeat(rex, &li, ST.A, reginfo, 1)) {
                     sayNO;
                 }
                 locinput = li;
@@ -8179,7 +8188,7 @@ NULL
                st->u.eval.prev_rex = rex_sv;           /* inner */
 
                 /* Save *all* the positions. */
-               st->u.eval.cp = S_regcppush(aTHX_ rex, 0, maxopenparen, depth);
+                st->u.eval.cp = regcppush(rex, 0, maxopenparen);
                 rex_sv = CUR_EVAL.prev_rex;
                is_utf8_pat = reginfo->is_utf8_pat = cBOOL(RX_UTF8(rex_sv));
                SET_reg_curpm(rex_sv);
@@ -8193,8 +8202,7 @@ NULL
 
                /* Restore parens of the outer rex without popping the
                 * savestack */
-                S_regcp_restore(aTHX_ rex, CUR_EVAL.lastcp,
-                                        &maxopenparen, depth);
+                regcp_restore(rex, CUR_EVAL.lastcp, &maxopenparen);
 
                st->u.eval.prev_eval = cur_eval;
                 cur_eval = CUR_EVAL.prev_eval;
@@ -8647,7 +8655,7 @@ NULL
  */
 STATIC I32
 S_regrepeat(pTHX_ regexp *prog, char **startposp, const regnode *p,
-            regmatch_info *const reginfo, I32 max, int depth)
+            regmatch_info *const reginfo, I32 max _pDEPTH)
 {
     char *scan;     /* Pointer to current position in target string */
     I32 c;
@@ -8657,9 +8665,6 @@ S_regrepeat(pTHX_ regexp *prog, char **startposp, const regnode *p,
     unsigned int to_complement = 0;  /* Invert the result? */
     UV utf8_flags;
     _char_class_number classnum;
-#ifndef DEBUGGING
-    PERL_UNUSED_ARG(depth);
-#endif
 
     PERL_ARGS_ASSERT_REGREPEAT;