Commit d9c46ed1b8 for perl
commit d9c46ed1b84e5a8351a038c6e1e6fbd79384e481
Author: Yves Orton <demerphq@gmail.com>
Date: Tue Oct 27 21:36:39 2026 +0100
regcomp: name regnode continuation offsets
Name the generic next offset and the IFTHEN and subpattern continuation
offsets. The accessors preserve the distinct storage layouts for
ordinary nodes and nodes with arguments while making each offset's
purpose clear.
diff --git a/regcomp.c b/regcomp.c
index 6f112a92fd..6a07c5b421 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -13483,7 +13483,7 @@ S_regtail(pTHX_ RExC_state_t * pRExC_state,
assert(val >= scan);
if (REGNODE_OFF_BY_ARG(OP(REGNODE_p(scan)))) {
assert((UV) (val - scan) <= U32_MAX);
- ARG1u_SET(REGNODE_p(scan), val - scan);
+ REGNODE_NEXT_OFFSET_SET(REGNODE_p(scan), val - scan);
}
else {
if (val - scan > U16_MAX) {
@@ -13583,7 +13583,7 @@ S_regtail_study(pTHX_ RExC_state_t *pRExC_state, regnode_offset p,
});
if (REGNODE_OFF_BY_ARG(OP(REGNODE_p(scan)))) {
assert((UV) (val - scan) <= U32_MAX);
- ARG1u_SET(REGNODE_p(scan), val - scan);
+ REGNODE_NEXT_OFFSET_SET(REGNODE_p(scan), val - scan);
}
else {
if (val - scan > U16_MAX) {
diff --git a/regcomp.h b/regcomp.h
index 1839d70910..ff4315c1c7 100644
--- a/regcomp.h
+++ b/regcomp.h
@@ -612,6 +612,28 @@ struct regnode_ssc {
ARG2u_SET((p), (val)); \
} STMT_END
+#define REGNODE_NEXT_OFFSET(p) \
+ (PREVENT_LVALUE((REGNODE_OFF_BY_ARG(OP(p)) ? ARG1u(p) : NEXT_OFF(p))))
+#define REGNODE_NEXT_OFFSET_SET(p, val) STMT_START { \
+ if (REGNODE_OFF_BY_ARG(OP(p))) ARG1u_SET((p), (val)); \
+ else NEXT_OFF_set((p), (val)); \
+} STMT_END
+
+#define IFTHEN_ELSE_OFFSET(p) \
+ (assert(OP(p) == IFTHEN), PREVENT_LVALUE(REGNODE_NEXT_OFFSET(p)))
+#define IFTHEN_ELSE_OFFSET_SET(p, val) STMT_START { \
+ assert(OP(p) == IFTHEN); \
+ REGNODE_NEXT_OFFSET_SET((p), (val)); \
+} STMT_END
+
+#define SUBPATTERN_CONTINUE_OFFSET(p) \
+ (assert(OP(p) == IFMATCH || OP(p) == UNLESSM || OP(p) == SUSPEND), \
+ PREVENT_LVALUE(REGNODE_NEXT_OFFSET(p)))
+#define SUBPATTERN_CONTINUE_OFFSET_SET(p, val) STMT_START { \
+ assert(OP(p) == IFMATCH || OP(p) == UNLESSM || OP(p) == SUSPEND); \
+ REGNODE_NEXT_OFFSET_SET((p), (val)); \
+} STMT_END
+
#define LOGICAL_MODE(p) \
(assert(OP(p) == LOGICAL), PREVENT_LVALUE(FLAGS(p) & EVAL_FLAGS_MASK))
#define LOGICAL_MODE_SET(p, val) STMT_START { \
diff --git a/regcomp_study.c b/regcomp_study.c
index e5d605b224..35e501c71b 100644
--- a/regcomp_study.c
+++ b/regcomp_study.c
@@ -60,7 +60,7 @@ S_rck_elide_nothing(pTHX_ regnode *node)
? I32_MAX
/* I32 may be smaller than U16 on CRAYs! */
: (I32_MAX < U16_MAX ? I32_MAX : U16_MAX));
- int off = (REGNODE_OFF_BY_ARG(OP(node)) ? ARG1u(node) : NEXT_OFF(node));
+ int off = REGNODE_NEXT_OFFSET(node);
int noff;
regnode *n = node;
@@ -69,14 +69,14 @@ S_rck_elide_nothing(pTHX_ regnode *node)
(n = regnext(n))
&& (
(REGNODE_TYPE(OP(n)) == NOTHING && (noff = NEXT_OFF(n)))
- || ((OP(n) == LONGJMP) && (noff = ARG1u(n)))
+ || ((OP(n) == LONGJMP) && (noff = REGNODE_NEXT_OFFSET(n)))
)
&& off + noff < max
) {
off += noff;
}
if (REGNODE_OFF_BY_ARG(OP(node)))
- ARG1u(node) = off;
+ REGNODE_NEXT_OFFSET_SET(node, off);
else
NEXT_OFF_set(node, off);
}
@@ -1285,7 +1285,7 @@ Perl_join_exact(pTHX_ RExC_state_t *pRExC_state, regnode *scan,
if (flags && !NEXT_OFF(n)) {
DEBUG_PEEP("atch", val, depth, 0);
if (REGNODE_OFF_BY_ARG(OP(n))) {
- ARG1u_SET(n, val - n);
+ REGNODE_NEXT_OFFSET_SET(n, val - n);
}
else {
NEXT_OFF_set(n, val - n);
@@ -2806,7 +2806,7 @@ Perl_study_chunk(pTHX_
regnode *nnxt = regnext(nxt1);
if (nnxt == nxt) {
if (REGNODE_OFF_BY_ARG(OP(nxt1)))
- ARG1u_SET(nxt1, nxt2 - nxt1);
+ REGNODE_NEXT_OFFSET_SET(nxt1, nxt2 - nxt1);
else if (nxt2 - nxt1 < U16_MAX)
NEXT_OFF_set(nxt1, nxt2 - nxt1);
else
@@ -2842,7 +2842,7 @@ Perl_study_chunk(pTHX_
regnode *nxt = oscan + NEXT_OFF(oscan);
if (OP(REGNODE_BEFORE(nxt)) == NOTHING) /* LONGJMP */
- nxt += ARG1u(nxt);
+ nxt += REGNODE_NEXT_OFFSET(nxt);
nxt = REGNODE_BEFORE(nxt);
if (
/* we've not already set WHILEM count on this node */
diff --git a/regexec.c b/regexec.c
index ab7f1484ee..cd352ba52e 100644
--- a/regexec.c
+++ b/regexec.c
@@ -9487,7 +9487,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
if (sw)
next = REGNODE_AFTER_type(scan,tregnode_IFTHEN);
else {
- next = scan + ARG1u(scan);
+ next = scan + IFTHEN_ELSE_OFFSET(scan);
if (OP(next) == IFTHEN) /* Fake one. */
next = REGNODE_AFTER_type(next,tregnode_IFTHEN);
}
@@ -9589,7 +9589,7 @@ NULL
assert(next); /* keep Coverity happy */
if (OP(REGNODE_BEFORE(next)) == NOTHING) /* LONGJMP */
- next += ARG1u(next);
+ next += REGNODE_NEXT_OFFSET(next);
/* XXXX Probably it is better to teach regpush to support
parenfloor > maxopenparen ... */
@@ -9914,7 +9914,7 @@ NULL
#define ST st->u.branch
case BRANCHJ: /* /(...|A|...)/ with long next pointer */
- next = scan + ARG1u(scan);
+ next = scan + REGNODE_NEXT_OFFSET(scan);
if (next == scan)
next = NULL;
ST.before_paren = BRANCH_CAPTURE_FLOOR(scan);
@@ -10642,7 +10642,7 @@ NULL
sayNO;
/* Here, we didn't want it to match, so is actually success */
- next = scan + ARG1u(scan);
+ next = scan + SUBPATTERN_CONTINUE_OFFSET(scan);
if (next == scan)
next = NULL;
break;
@@ -10704,7 +10704,7 @@ NULL
loceol = st->loceol;
script_run_begin = st->sr0;
}
- scan = ST.me + ARG1u(ST.me);
+ scan = ST.me + SUBPATTERN_CONTINUE_OFFSET(ST.me);
if (scan == ST.me)
scan = NULL;
continue; /* execute B */
@@ -10714,7 +10714,7 @@ NULL
case LONGJMP: /* alternative with many branches compiles to
* (BRANCHJ; EXACT ...; LONGJMP ) x N */
- next = scan + ARG1u(scan);
+ next = scan + REGNODE_NEXT_OFFSET(scan);
if (next == scan)
next = NULL;
break;