summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Williamson <public@khwilliamson.com>2010-12-07 17:04:02 -0700
committerKarl Williamson <public@khwilliamson.com>2010-12-11 15:58:01 -0700
commit3a15e693385b1ab6186ad77f2fc208db1d0e05ea (patch)
treeb474df6fa1a82f6ee0117e92818bbcd8c97253a8
parent40c7855679f2fac8010393d53040d01a1eecb050 (diff)
downloadperl-3a15e693385b1ab6186ad77f2fc208db1d0e05ea.tar.gz
regcomp: Allow freeing up bit in ANYOF flags
The flags field is fully used, and until the ANYOF node is split later in development, the CLASS bit will need to be freed up to give the space for other uses. This patch allows for this to easily be toggled.
-rw-r--r--regcomp.c22
-rw-r--r--regcomp.h30
-rw-r--r--regexec.c4
3 files changed, 42 insertions, 14 deletions
diff --git a/regcomp.c b/regcomp.c
index 50634d22e5..1303ef41df 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -3609,8 +3609,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
goto do_default;
if (flags & SCF_DO_STCLASS_OR) { /* Everything but \n */
value = (ANYOF_BITMAP_TEST(data->start_class,'\n')
- || ((data->start_class->flags & ANYOF_CLASS)
- && ANYOF_CLASS_TEST_ANY_SET(data->start_class)));
+ || ANYOF_CLASS_TEST_ANY_SET(data->start_class));
cl_anything(pRExC_state, data->start_class);
}
if (flags & SCF_DO_STCLASS_AND || !value)
@@ -8377,12 +8376,21 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, U32 depth)
if (SIZE_ONLY) {
RExC_size += ANYOF_SKIP;
+#ifdef ANYOF_ADD_LOC_SKIP
+ if (LOC) {
+ RExC_size += ANYOF_ADD_LOC_SKIP;
+ }
+#endif
listsv = &PL_sv_undef; /* For code scanners: listsv always non-NULL. */
}
else {
RExC_emit += ANYOF_SKIP;
- if (LOC)
+ if (LOC) {
ANYOF_FLAGS(ret) |= ANYOF_LOCALE;
+#ifdef ANYOF_ADD_LOC_SKIP
+ RExC_emit += ANYOF_ADD_LOC_SKIP;
+#endif
+ }
ANYOF_BITMAP_ZERO(ret);
listsv = newSVpvs("# comment\n");
}
@@ -8596,10 +8604,14 @@ parseit:
if (LOC && namedclass < ANYOF_MAX && ! need_class) {
need_class = 1;
if (SIZE_ONLY) {
+#ifdef ANYOF_CLASS_ADD_SKIP
RExC_size += ANYOF_CLASS_ADD_SKIP;
+#endif
}
else {
+#ifdef ANYOF_CLASS_ADD_SKIP
RExC_emit += ANYOF_CLASS_ADD_SKIP;
+#endif
ANYOF_CLASS_ZERO(ret);
}
ANYOF_FLAGS(ret) |= ANYOF_CLASS;
@@ -9700,8 +9712,8 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o)
}
EMIT_ANYOF_TEST_SEPARATOR(do_sep,sv,flags);
- /* output any special charclass tests (used mostly under use locale) */
- if (o->flags & ANYOF_CLASS && ANYOF_CLASS_TEST_ANY_SET(o))
+ /* output any special charclass tests (used entirely under use locale) */
+ if (ANYOF_CLASS_TEST_ANY_SET(o))
for (i = 0; i < (int)(sizeof(anyofs)/sizeof(char*)); i++)
if (ANYOF_CLASS_TEST(o,i)) {
sv_catpv(sv, anyofs[i]);
diff --git a/regcomp.h b/regcomp.h
index 6dc05f5d7c..c140089093 100644
--- a/regcomp.h
+++ b/regcomp.h
@@ -406,12 +406,6 @@ struct regnode_charclass_class {
#define ANYOF_CLASS_CLEAR(p, c) (ANYOF_CLASS_BYTE(p, c) &= ~ANYOF_BIT(c))
#define ANYOF_CLASS_TEST(p, c) (ANYOF_CLASS_BYTE(p, c) & ANYOF_BIT(c))
-/* Quicker way to see if there are actually any tests. This is because
- * currently the set of tests can be empty even when the class bitmap is
- * allocated */
-#define ANYOF_CLASS_TEST_ANY_SET(p) /* assumes sizeof(p) = 4 */ \
- memNE (((struct regnode_charclass_class*)(p))->classflags, "0000", ANYOF_CLASS_SIZE)
-
#define ANYOF_CLASS_ZERO(ret) Zero(((struct regnode_charclass_class*)(ret))->classflags, ANYOF_CLASSBITMAP_SIZE, char)
#define ANYOF_BITMAP_ZERO(ret) Zero(((struct regnode_charclass*)(ret))->bitmap, ANYOF_BITMAP_SIZE, char)
@@ -431,7 +425,29 @@ struct regnode_charclass_class {
#define ANYOF_SKIP ((ANYOF_SIZE - 1)/sizeof(regnode))
#define ANYOF_CLASS_SKIP ((ANYOF_CLASS_SIZE - 1)/sizeof(regnode))
-#define ANYOF_CLASS_ADD_SKIP (ANYOF_CLASS_SKIP - ANYOF_SKIP)
+
+/* The class bit can be set to the locale one if necessary to save bits at the
+ * expense of having locale ANYOF nodes always have a class bit map, and hence
+ * take up extra space. This allows convenient changing it as development
+ * proceeds on this */
+#if ANYOF_CLASS == ANYOF_LOCALE
+# undef ANYOF_CLASS_ADD_SKIP
+# define ANYOF_ADD_LOC_SKIP (ANYOF_CLASS_SKIP - ANYOF_SKIP)
+
+ /* Quicker way to see if there are actually any tests. This is because
+ * currently the set of tests can be empty even when the class bitmap is
+ * allocated */
+# if ANYOF_CLASSBITMAP_SIZE != 4
+# error ANYOF_CLASSBITMAP_SIZE is expected to be 4
+# endif
+# define ANYOF_CLASS_TEST_ANY_SET(p) /* assumes sizeof(p) = 4 */ \
+ memNE (((struct regnode_charclass_class*)(p))->classflags, \
+ "\0\0\0\0", ANYOF_CLASSBITMAP_SIZE)
+#else
+# define ANYOF_CLASS_ADD_SKIP (ANYOF_CLASS_SKIP - ANYOF_SKIP)
+# undef ANYOF_ADD_LOC_SKIP
+# define ANYOF_CLASS_TEST_ANY_SET(p) (ANYOF_FLAGS(p) & ANYOF_CLASS)
+#endif
/*
diff --git a/regexec.c b/regexec.c
index c1f1ae26ea..f2723e4cc6 100644
--- a/regexec.c
+++ b/regexec.c
@@ -6356,8 +6356,8 @@ S_reginclass(pTHX_ const regexp * const prog, register const regnode * const n,
match = TRUE;
}
- if (!match && (flags & ANYOF_CLASS) && ANYOF_CLASS_TEST_ANY_SET(n)) {
- PL_reg_flags |= RF_tainted;
+ if (!match && ANYOF_CLASS_TEST_ANY_SET(n)) {
+ PL_reg_flags |= RF_tainted; /* CLASS implies LOCALE */
if (
(ANYOF_CLASS_TEST(n, ANYOF_ALNUM) && isALNUM_LC(c)) ||
(ANYOF_CLASS_TEST(n, ANYOF_NALNUM) && !isALNUM_LC(c)) ||