return TRUE;
}
+static void
+release_RExC_state(pTHX_ void *vstate) {
+ RExC_state_t *pRExC_state = (RExC_state_t *)vstate;
+
+ /* Any or all of these might be NULL.
+
+ There's no point in setting them to NULL after the free, since
+ pRExC_state is about to be released.
+ */
+ SvREFCNT_dec(RExC_rx_sv);
+ Safefree(RExC_open_parens);
+ Safefree(RExC_close_parens);
+ Safefree(RExC_logical_to_parno);
+ Safefree(RExC_parno_to_logical);
+
+ Safefree(pRExC_state);
+}
+
/*
* Perl_re_op_compile - the perl internal RE engine's function to compile a
* regular expression into internal code.
bool recompile = 0;
bool runtime_code = 0;
scan_data_t data;
- RExC_state_t RExC_state;
- RExC_state_t * const pRExC_state = &RExC_state;
#ifdef TRIE_STUDY_OPT
/* search for "restudy" in this file for a detailed explanation */
PERL_ARGS_ASSERT_RE_OP_COMPILE;
+ DEBUG_r(if (!PL_colorset) reginitcolors());
+
+ RExC_state_t *pRExC_state = NULL;
/* Ensure that all members of the pRExC_state is initialized to 0
* at the start of regex compilation. Historically we have had issues
* with people remembering to zero specific members or zeroing them
* too late, etc. Doing it in one place is saner and avoid oversight
* or error. */
- Zero(pRExC_state,1,RExC_state_t);
+ Newxz(pRExC_state, 1, RExC_state_t);
+
+ SAVEDESTRUCTOR_X(release_RExC_state, pRExC_state);
+
DEBUG_r({
/* and then initialize RExC_mysv1 and RExC_mysv2 early so if
* something calls regprop we don't have issues. These variables
- * not being set up properly motivated the use of Zero() to initalize
+ * not being set up properly motivated the use of Newxz() to initalize
* the pRExC_state structure, as there were codepaths under -Uusedl
* that left these unitialized, and non-null as well. */
RExC_mysv1 = sv_newmortal();
RExC_mysv2 = sv_newmortal();
});
- DEBUG_r(if (!PL_colorset) reginitcolors());
-
-
if (is_bare_re)
*is_bare_re = FALSE;
/* Clean up what we did in this parse */
SvREFCNT_dec_NN(RExC_rx_sv);
+ RExC_rx_sv = NULL;
goto redo_parse;
}
/* search for "restudy" in this file for a detailed explanation */
if (!restudied) {
StructCopy(&zero_scan_data, &data, scan_data_t);
- copyRExC_state = RExC_state;
+ copyRExC_state = *pRExC_state;
} else {
U32 seen=RExC_seen;
DEBUG_OPTIMISE_r(Perl_re_printf( aTHX_ "Restudying\n"));
- RExC_state = copyRExC_state;
+ *pRExC_state = copyRExC_state;
if (seen & REG_TOP_LEVEL_BRANCHES_SEEN)
RExC_seen |= REG_TOP_LEVEL_BRANCHES_SEEN;
else
regdump(RExC_rx);
});
- if (RExC_open_parens) {
- Safefree(RExC_open_parens);
- RExC_open_parens = NULL;
- }
- if (RExC_close_parens) {
- Safefree(RExC_close_parens);
- RExC_close_parens = NULL;
- }
- if (RExC_logical_to_parno) {
- Safefree(RExC_logical_to_parno);
- RExC_logical_to_parno = NULL;
- }
- if (RExC_parno_to_logical) {
- Safefree(RExC_parno_to_logical);
- RExC_parno_to_logical = NULL;
- }
+ /* we're returning ownership of the SV to the caller, ensure the cleanup
+ * doesn't release it
+ */
+ RExC_rx_sv = NULL;
#ifdef USE_ITHREADS
/* under ithreads the ?pat? PMf_USED flag on the pmop is simulated
array is mortal, but is a
fail-safe */
(void) sv_2mortal(msg);
- PREPARE_TO_DIE;
}
Perl_warner(aTHX_ packWARN(WARN_REGEXP), "%s", SvPVX(msg));
SvREFCNT_dec_NN(msg);
const char *ellipses = ""; \
IV len = RExC_precomp_end - RExC_precomp; \
\
- PREPARE_TO_DIE; \
if (len > RegexLengthToShowInErrorMessages) { \
/* chop 10 shorter than the max, to ensure meaning of "..." */ \
len = RegexLengthToShowInErrorMessages - 10; \
* Calls SAVEDESTRUCTOR_X if needed, then Simple_vFAIL()
*/
#define vFAIL(m) STMT_START { \
- PREPARE_TO_DIE; \
Simple_vFAIL(m); \
} STMT_END
* Calls SAVEDESTRUCTOR_X if needed, then Simple_vFAIL2().
*/
#define vFAIL2(m,a1) STMT_START { \
- PREPARE_TO_DIE; \
Simple_vFAIL2(m, a1); \
} STMT_END
* Calls SAVEDESTRUCTOR_X if needed, then Simple_vFAIL3().
*/
#define vFAIL3(m,a1,a2) STMT_START { \
- PREPARE_TO_DIE; \
Simple_vFAIL3(m, a1, a2); \
} STMT_END
} STMT_END
#define vFAIL4(m,a1,a2,a3) STMT_START { \
- PREPARE_TO_DIE; \
Simple_vFAIL4(m, a1, a2, a3); \
} STMT_END
/* A specialized version of vFAIL2 that works with UTF8f */
#define vFAIL2utf8f(m, a1) STMT_START { \
- PREPARE_TO_DIE; \
S_re_croak(aTHX_ UTF, m REPORT_LOCATION, a1, \
REPORT_LOCATION_ARGS(RExC_parse)); \
} STMT_END
#define vFAIL3utf8f(m, a1, a2) STMT_START { \
- PREPARE_TO_DIE; \
S_re_croak(aTHX_ UTF, m REPORT_LOCATION, a1, a2, \
REPORT_LOCATION_ARGS(RExC_parse)); \
} STMT_END
__FILE__, __LINE__, loc); \
} \
if (TO_OUTPUT_WARNINGS(loc)) { \
- if (ckDEAD(warns)) \
- PREPARE_TO_DIE; \
code; \
UPDATE_WARNINGS_LOC(loc); \
} \