Commit 5cb19bc2c4 for perl
commit 5cb19bc2c45525f6f9ade5145530486b30ed50e2
Author: Yves Orton <demerphq@gmail.com>
Date: Tue Oct 27 21:36:28 2026 +0100
regcomp: name EVAL and LOGICAL fields
Name the data slot, compile flags, node flags, optimistic-eval bit, and
logical mode stored in EVAL and LOGICAL nodes. This makes the packed
fields clear to the compiler, optimizer, debugger, and executor without
changing their representation.
diff --git a/regcomp.c b/regcomp.c
index 0041f2c15c..2a14d11017 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -4097,7 +4097,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
if (is_logical) {
regnode_offset eval;
ret = reg_node(pRExC_state, LOGICAL);
- FLAGS(REGNODE_p(ret)) = 2;
+ LOGICAL_MODE_SET(REGNODE_p(ret), 2);
eval = reg2node(pRExC_state, EVAL,
n,
@@ -4106,14 +4106,14 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
* return value */
RExC_flags & RXf_PMf_COMPILETIME
);
- FLAGS(REGNODE_p(eval)) = is_optimistic * EVAL_OPTIMISTIC_FLAG;
+ EVAL_IS_OPTIMISTIC_SET(REGNODE_p(eval), is_optimistic);
if (! REGTAIL(pRExC_state, ret, eval)) {
REQUIRE_BRANCHJ(flagp, 0);
}
return ret;
}
ret = reg2node(pRExC_state, EVAL, n, 0);
- FLAGS(REGNODE_p(ret)) = is_optimistic * EVAL_OPTIMISTIC_FLAG;
+ EVAL_IS_OPTIMISTIC_SET(REGNODE_p(ret), is_optimistic);
return ret;
}
@@ -4158,7 +4158,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
regnode_offset tail;
ret = reg_node(pRExC_state, LOGICAL);
- FLAGS(REGNODE_p(ret)) = 1;
+ LOGICAL_MODE_SET(REGNODE_p(ret), 1);
tail = reg(pRExC_state, 1, &flag, depth+1);
RETURN_FAIL_ON_RESTART(flag, flagp);
diff --git a/regcomp.h b/regcomp.h
index a9d88a00b8..2797e57a66 100644
--- a/regcomp.h
+++ b/regcomp.h
@@ -583,6 +583,27 @@ struct regnode_ssc {
ARG2i_SET((p), (val)); \
} STMT_END
+#define EVAL_CODE_DATA_SLOT(p) \
+ (assert(OP(p) == EVAL), PREVENT_LVALUE(ARG1u(p)))
+#define EVAL_CODE_DATA_SLOT_SET(p, val) STMT_START { \
+ assert(OP(p) == EVAL); \
+ ARG1u_SET((p), (val)); \
+} STMT_END
+
+#define EVAL_COMPILE_FLAGS(p) \
+ (assert(OP(p) == EVAL), PREVENT_LVALUE(ARG2i(p)))
+#define EVAL_COMPILE_FLAGS_SET(p, val) STMT_START { \
+ assert(OP(p) == EVAL); \
+ ARG2i_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 { \
+ assert(OP(p) == LOGICAL); \
+ FLAGS(p) = (val); \
+} STMT_END
+
#define REF_IS_VOLATILE(p) \
(assert(REGNODE_TYPE(OP(p)) == REF), PREVENT_LVALUE((FLAGS(p) & \
VOLATILE_REF) != 0))
@@ -591,6 +612,22 @@ struct regnode_ssc {
FLAGS(p) = (val) ? VOLATILE_REF : 0; \
} STMT_END
+#define EVAL_NODE_FLAGS(p) \
+ (assert(OP(p) == EVAL), PREVENT_LVALUE(FLAGS(p)))
+#define EVAL_NODE_FLAGS_SET(p, val) STMT_START { \
+ assert(OP(p) == EVAL); \
+ FLAGS(p) = (val); \
+} STMT_END
+
+#define EVAL_IS_OPTIMISTIC(p) \
+ (assert(OP(p) == EVAL), PREVENT_LVALUE((FLAGS(p) & EVAL_OPTIMISTIC_FLAG) \
+ != 0))
+#define EVAL_IS_OPTIMISTIC_SET(p, val) STMT_START { \
+ assert(OP(p) == EVAL); \
+ FLAGS(p) = (FLAGS(p) & ~EVAL_OPTIMISTIC_FLAG) | ((val) ? \
+ EVAL_OPTIMISTIC_FLAG : 0); \
+} STMT_END
+
/* the following define was set to 0xde in 075abff3
* as part of some linting logic. I have set it to 0
diff --git a/regcomp_debug.c b/regcomp_debug.c
index 094533a12f..a1a9cc6d65 100644
--- a/regcomp_debug.c
+++ b/regcomp_debug.c
@@ -753,7 +753,7 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o, const regmatch_
}
else if (k == LOGICAL)
/* 2: embedded, otherwise 1 */
- sv_catpvf(sv, "[%d]", FLAGS(o));
+ sv_catpvf(sv, "[%d]", LOGICAL_MODE(o));
else if (k == ANYOF || k == ANYOFH || k == ANYOFR) {
U8 flags;
U8 * bitmap;
@@ -1058,7 +1058,7 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o, const regmatch_
else if (op == SBOL)
sv_catpvf(sv, " /%s/", FLAGS(o) ? "\\A" : "^");
else if (op == EVAL) {
- if (FLAGS(o) & EVAL_OPTIMISTIC_FLAG)
+ if (EVAL_IS_OPTIMISTIC(o))
sv_catpvf(sv, " optimistic");
}
diff --git a/regcomp_study.c b/regcomp_study.c
index 8428881f4c..e5d605b224 100644
--- a/regcomp_study.c
+++ b/regcomp_study.c
@@ -3511,7 +3511,7 @@ Perl_study_chunk(pTHX_
}
}
else if (OP(scan) == EVAL) {
- if (data && !(FLAGS(scan) & EVAL_OPTIMISTIC_FLAG) )
+ if (data && !(EVAL_IS_OPTIMISTIC(scan)) )
data->flags |= SF_HAS_EVAL;
}
else if ( REGNODE_TYPE(OP(scan)) == ENDLIKE ) {
@@ -3538,7 +3538,7 @@ Perl_study_chunk(pTHX_
flags &= ~SCF_DO_SUBSTR;
}
}
- else if (OP(scan) == LOGICAL && FLAGS(scan) == 2) /* Embedded follows */
+ else if (OP(scan) == LOGICAL && LOGICAL_MODE(scan) == 2) /* Embedded follows */
{
if (flags & SCF_DO_SUBSTR) {
scan_commit(pRExC_state, data, minlenp, is_inf);
diff --git a/regexec.c b/regexec.c
index 99426c3e45..2259b6140f 100644
--- a/regexec.c
+++ b/regexec.c
@@ -9000,7 +9000,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
if (!caller_cv)
caller_cv = find_runcv(NULL);
- n = ARG1u(scan);
+ n = EVAL_CODE_DATA_SLOT(scan);
if (rexi->data->what[n] == 'r') { /* code from an external qr */
newcv = (ReANY(
@@ -9235,11 +9235,11 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
/* if we got here, it should be an engine which
* supports compiling code blocks and stuff */
assert(rex->engine && rex->engine->op_comp);
- assert(!(FLAGS(scan) & ~RXf_PMf_COMPILETIME));
+ assert(!(EVAL_NODE_FLAGS(scan) & ~RXf_PMf_COMPILETIME));
re_sv = rex->engine->op_comp(aTHX_ &ret, 1, NULL,
rex->engine, NULL, NULL,
/* copy /msixn etc to inner pattern */
- ARG2i(scan),
+ EVAL_COMPILE_FLAGS(scan),
pm_flags);
if (!(SvFLAGS(ret)
@@ -9494,7 +9494,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
break;
case LOGICAL: /* modifier for EVAL and IFMATCH */
- logical = FLAGS(scan) & EVAL_FLAGS_MASK; /* reserve a bit for optimistic eval */
+ logical = LOGICAL_MODE(scan) & EVAL_FLAGS_MASK; /* reserve a bit for optimistic eval */
break;
/*******************************************************************