Skip to content

Commit 676faf6

Browse files
committed
regmatch(): improve savestack ix debugging output
Under use re Debug => 'STATE'; S_regmatch() produces various bits of debugging output regarding savestack manipulation; e.g. when the current index is saved; or when the savestack is popped back to that index on success or failure etc. Unfortunately that output is patchy and inconsistent. For example it often talks confusingly about "Setting an EVAL scope" even when an EVAL hasn't been executed. And it doesn't log all savestack manipulation. After this commit there is a standard set of debugging messages, such as: savestack: snapping ix=14 savestack: regcppush filled in range [14..18) savestack: regcppop freed in range [14..18) savestack: freeing in range [10..14) which are consistently applied. There should be no change in functionality unless that specific debugging is enabled.
1 parent 0e943ce commit 676faf6

File tree

1 file changed

+45
-12
lines changed

1 file changed

+45
-12
lines changed

regexec.c

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -298,29 +298,40 @@ S_regcppush(pTHX_ const regexp *rex, I32 parenfloor, U32 maxopenparen comma_pDEP
298298
depth, retval, PL_savestack_ix);
299299
});
300300

301+
DEBUG_STATE_r(
302+
Perl_re_exec_indentf(aTHX_
303+
"savestack: regcppush filled in range [%" IVdf "..%" IVdf ")\n",
304+
depth, (IV)retval, (IV)PL_savestack_ix
305+
)
306+
);
307+
301308
return retval;
302309
}
303310

304311
/* These are needed since we do not localize EVAL nodes: */
305312
#define REGCP_SET(cp) \
306313
DEBUG_STATE_r( \
307314
Perl_re_exec_indentf( aTHX_ \
308-
"Setting an EVAL scope, savestack = %" IVdf ",\n", \
315+
"savestack: snapping ix=%" IVdf "\n", \
309316
depth, (IV)PL_savestack_ix \
310317
) \
311318
); \
312319
cp = PL_savestack_ix
313320

321+
/* REGCP_UNWIND(cp): unwind savestack back to marked index,
322+
* but without restoring regcppush()ed data (leave_scope() treats
323+
* SAVEt_REGCONTEXT as a NOOP)
324+
*/
325+
314326
#define REGCP_UNWIND(cp) \
315327
DEBUG_STATE_r( \
316-
if (cp != PL_savestack_ix) \
317-
Perl_re_exec_indentf( aTHX_ \
318-
"Clearing an EVAL scope, savestack = %" \
319-
IVdf "..%" IVdf "\n", \
320-
depth, (IV)(cp), (IV)PL_savestack_ix \
321-
) \
328+
Perl_re_exec_indentf( aTHX_ \
329+
"savestack: freeing in range [%" \
330+
IVdf "..%" IVdf ")\n", \
331+
depth, (IV)(cp), (IV)PL_savestack_ix \
332+
) \
322333
); \
323-
regcpblow(cp)
334+
LEAVE_SCOPE(cp)
324335

325336
/* set the start and end positions of capture ix */
326337
#define CLOSE_ANY_CAPTURE(rex, ix, s, e) \
@@ -403,6 +414,10 @@ S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p comma_pDEPTH)
403414
{
404415
UV i;
405416
U32 paren;
417+
#ifdef DEBUGGING
418+
I32 orig_ix = PL_savestack_ix;
419+
#endif
420+
406421
DECLARE_AND_GET_RE_DEBUG_FLAGS;
407422

408423
PERL_ARGS_ASSERT_REGCPPOP;
@@ -491,6 +506,14 @@ S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p comma_pDEPTH)
491506
"finished regcppop at %" IVdf "\n",
492507
depth, PL_savestack_ix);
493508
});
509+
510+
DEBUG_STATE_r(
511+
Perl_re_exec_indentf(aTHX_
512+
"savestack: regcppop freed in range [%" IVdf "..%" IVdf ")\n",
513+
depth, (IV)(PL_savestack_ix), (IV)orig_ix
514+
)
515+
);
516+
494517
}
495518

496519
/* restore the parens and associated vars at savestack position ix,
@@ -499,15 +522,25 @@ S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p comma_pDEPTH)
499522
STATIC void
500523
S_regcp_restore(pTHX_ regexp *rex, I32 ix, U32 *maxopenparen_p comma_pDEPTH)
501524
{
525+
DECLARE_AND_GET_RE_DEBUG_FLAGS;
502526
I32 tmpix = PL_savestack_ix;
503527
PERL_ARGS_ASSERT_REGCP_RESTORE;
504528

529+
DEBUG_STATE_r(
530+
Perl_re_exec_indentf( aTHX_
531+
"savestack: regcp_restore: ix was %" IVdf "\n",
532+
depth, (IV)PL_savestack_ix);
533+
);
505534
PL_savestack_ix = ix;
506535
regcppop(rex, maxopenparen_p);
507536
PL_savestack_ix = tmpix;
537+
DEBUG_STATE_r(
538+
Perl_re_exec_indentf( aTHX_
539+
"savestack: regcp_restore: reset ix=%" IVdf "\n",
540+
depth, (IV)PL_savestack_ix);
541+
);
508542
}
509543

510-
#define regcpblow(cp) LEAVE_SCOPE(cp) /* Ignores regcppush()ed data. */
511544

512545
STATIC bool
513546
S_isFOO_lc(pTHX_ const U8 classnum, const U8 character)
@@ -8723,7 +8756,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
87238756
SV *save_sv= GvSV(PL_replgv);
87248757
SV *replsv;
87258758
SvREFCNT_inc(save_sv);
8726-
regcpblow(ST.cp); /* LEAVE in disguise */
8759+
REGCP_UNWIND(ST.cp); /* LEAVE in disguise */
87278760
/* don't move this initialization up */
87288761
replsv = GvSV(PL_replgv);
87298762
sv_setsv(replsv, save_sv);
@@ -8990,7 +9023,7 @@ NULL
89909023

89919024
ST.prev_curlyx= cur_curlyx;
89929025
cur_curlyx = st;
8993-
ST.cp = PL_savestack_ix;
9026+
REGCP_SET(ST.cp);
89949027

89959028
/* these fields contain the state of the current curly.
89969029
* they are accessed by subsequent WHILEMs */
@@ -9013,7 +9046,7 @@ NULL
90139046
NOT_REACHED; /* NOTREACHED */
90149047

90159048
case CURLYX_end_fail: /* just failed to match all of A*B */
9016-
regcpblow(ST.cp);
9049+
REGCP_UNWIND(ST.cp); /* LEAVE in disguise */
90179050
cur_curlyx = ST.prev_curlyx;
90189051
sayNO;
90199052
NOT_REACHED; /* NOTREACHED */

0 commit comments

Comments
 (0)