#if defined(USE_ITHREADS)
Ap |void* |regdupe_internal|NN REGEXP * const r|NN CLONE_PARAMS* param
#endif
-p |regexp_engine*|current_re_engine
+EXp |regexp_engine const *|current_re_engine
Ap |REGEXP*|pregcomp |NN SV * const pattern|const U32 flags
p |REGEXP*|re_op_compile |NULLOK SV ** const patternp \
|int pat_count|NULLOK OP *expr \
- |NULLOK const regexp_engine* eng \
+ |NN const regexp_engine* eng \
|NULLOK REGEXP *VOL old_re \
|NULLOK int *is_bare_re \
|U32 rx_flags|U32 pm_flags
#if defined(PERL_CORE) || defined(PERL_EXT)
#define _is_utf8__perl_idstart(a) Perl__is_utf8__perl_idstart(aTHX_ a)
#define av_reify(a) Perl_av_reify(aTHX_ a)
+#define current_re_engine() Perl_current_re_engine(aTHX)
#define is_utf8_X_L(a) Perl_is_utf8_X_L(aTHX_ a)
#define is_utf8_X_LV(a) Perl_is_utf8_X_LV(aTHX_ a)
#define is_utf8_X_LVT(a) Perl_is_utf8_X_LVT(aTHX_ a)
#define core_prototype(a,b,c,d) Perl_core_prototype(aTHX_ a,b,c,d)
#define coresub_op(a,b,c) Perl_coresub_op(aTHX_ a,b,c)
#define create_eval_scope(a) Perl_create_eval_scope(aTHX_ a)
-#define current_re_engine() Perl_current_re_engine(aTHX)
#define cv_ckproto_len_flags(a,b,c,d,e) Perl_cv_ckproto_len_flags(aTHX_ a,b,c,d,e)
#define cvgv_set(a,b) Perl_cvgv_set(aTHX_ a,b)
#define cvstash_set(a,b) Perl_cvstash_set(aTHX_ a,b)
START_EXTERN_C
extern REGEXP* my_re_compile (pTHX_ SV * const pattern, const U32 pm_flags);
-extern REGEXP* my_re_op_compile (pTHX_ SV * const pattern, OP *expr, const U32 pm_flags);
+extern REGEXP* my_re_op_compile (pTHX_ SV ** const patternp, int pat_count,
+ OP *expr, const regexp_engine* eng, REGEXP *VOL old_re,
+ int *is_bare_re, U32 orig_rx_flags, U32 pm_flags);
+
extern I32 my_regexec (pTHX_ REGEXP * const prog, char* stringarg, char* strend,
char* strbeg, I32 minend, SV* screamer,
void* data, U32 flags);
my_reg_named_buff_iter,
my_reg_qr_package,
#if defined(USE_ITHREADS)
- my_regdupe
+ my_regdupe,
#endif
+ my_re_op_compile,
};
MODULE = re PACKAGE = re
if (is_compiletime) {
U32 rx_flags = pm->op_pmflags & RXf_PMf_COMPILETIME;
- regexp_engine *eng = current_re_engine();
+ regexp_engine const *eng = current_re_engine();
if (o->op_flags & OPf_SPECIAL)
rx_flags |= RXf_SPLIT;
- if (!has_code || (eng && eng != &PL_core_reg_engine)) {
+ if (!has_code || !eng->op_comp) {
/* compile-time simple constant pattern */
SV *pat;
pat = newSVpvn_flags(p, len, SVs_TEMP);
}
- PM_SETRE(pm, CALLREGCOMP(pat, rx_flags));
+ PM_SETRE(pm, CALLREGCOMP_ENG(eng, pat, rx_flags));
#ifdef PERL_MAD
op_getmad(expr,(OP*)pm,'e');
#else
}
else {
/* compile-time pattern that includes literal code blocks */
- REGEXP* re = re_op_compile(NULL, 0, expr, NULL, NULL, NULL,
+ REGEXP* re = eng->op_comp(aTHX_ NULL, 0, expr, eng, NULL, NULL,
rx_flags, pm->op_pmflags);
PM_SETRE(pm, re);
if (pm->op_pmflags & PMf_HAS_CV) {
#ifdef USE_ITHREADS
void* (*dupe) (pTHX_ REGEXP * const rx, CLONE_PARAMS *param);
#endif
+ REGEXP* (*op_comp) (...);
+
When a regexp is compiled, its C<engine> field is then set to point at
the appropriate structure, so that when it needs to be used Perl can find
On unthreaded builds this field doesn't exist.
+=head2 op_comp
+
+This is private to the perl core and subject to change. Should be left
+null.
+
=head1 The REGEXP structure
The REGEXP struct is defined in F<regexp.h>. All regex engines must be able to
if (PL_op->op_flags & OPf_SPECIAL)
PL_reginterp_cnt = (I32_MAX>>1); /* Mark as safe. */
- new_re = re_op_compile(args, nargs, pm->op_code_list, eng, re,
+ new_re = (eng->op_comp
+ ? eng->op_comp
+ : &Perl_re_op_compile
+ )(aTHX_ args, nargs, pm->op_code_list, eng, re,
&is_bare_re,
(pm->op_pmflags & RXf_PMf_COMPILETIME),
pm->op_pmflags);
#define PERL_ARGS_ASSERT_CROAK_XS_USAGE \
assert(cv); assert(params)
-PERL_CALLCONV regexp_engine* Perl_current_re_engine(pTHX);
+PERL_CALLCONV regexp_engine const * Perl_current_re_engine(pTHX);
PERL_CALLCONV const char * Perl_custom_op_desc(pTHX_ const OP *o)
__attribute__warn_unused_result__
__attribute__nonnull__(pTHX_1);
#define PERL_ARGS_ASSERT_RE_INTUIT_STRING \
assert(r)
-PERL_CALLCONV REGEXP* Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count, OP *expr, const regexp_engine* eng, REGEXP *VOL old_re, int *is_bare_re, U32 rx_flags, U32 pm_flags);
+PERL_CALLCONV REGEXP* Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count, OP *expr, const regexp_engine* eng, REGEXP *VOL old_re, int *is_bare_re, U32 rx_flags, U32 pm_flags)
+ __attribute__nonnull__(pTHX_4);
+#define PERL_ARGS_ASSERT_RE_OP_COMPILE \
+ assert(eng)
+
PERL_CALLCONV Malloc_t Perl_realloc(Malloc_t where, MEM_SIZE nbytes)
__attribute__malloc__
__attribute__warn_unused_result__;
* scope
*/
-#ifndef PERL_IN_XSUB_RE
-#define RE_ENGINE_PTR &PL_core_reg_engine
-#else
-extern const struct regexp_engine my_reg_engine;
-#define RE_ENGINE_PTR &my_reg_engine
-#endif
-
#ifndef PERL_IN_XSUB_RE
-/* return the currently in-scope regex engine (or NULL if none) */
+/* return the currently in-scope regex engine (or the default if none) */
-regexp_engine *
+regexp_engine const *
Perl_current_re_engine(pTHX)
{
dVAR;
SV **ptr;
if (!table)
- return NULL;
+ return &PL_core_reg_engine;
ptr = hv_fetchs(table, "regcomp", FALSE);
if ( !(ptr && SvIOK(*ptr) && SvIV(*ptr)))
- return NULL;
+ return &PL_core_reg_engine;
return INT2PTR(regexp_engine*,SvIV(*ptr));
}
else {
SV *ptr;
if (!PL_curcop->cop_hints_hash)
- return NULL;
+ return &PL_core_reg_engine;
ptr = cop_hints_fetch_pvs(PL_curcop, "regcomp", 0);
if ( !(ptr && SvIOK(ptr) && SvIV(ptr)))
- return NULL;
+ return &PL_core_reg_engine;
return INT2PTR(regexp_engine*,SvIV(ptr));
}
}
Perl_pregcomp(pTHX_ SV * const pattern, const U32 flags)
{
dVAR;
- regexp_engine *eng = current_re_engine();
+ regexp_engine const *eng = current_re_engine();
+ GET_RE_DEBUG_FLAGS_DECL;
PERL_ARGS_ASSERT_PREGCOMP;
/* Dispatch a request to compile a regexp to correct regexp engine. */
- if (eng) {
- GET_RE_DEBUG_FLAGS_DECL;
- DEBUG_COMPILE_r({
- PerlIO_printf(Perl_debug_log, "Using engine %"UVxf"\n",
- PTR2UV(eng));
- });
- return CALLREGCOMP_ENG(eng, pattern, flags);
- }
- return Perl_re_compile(aTHX_ pattern, flags);
+ DEBUG_COMPILE_r({
+ PerlIO_printf(Perl_debug_log, "Using engine %"UVxf"\n",
+ PTR2UV(eng));
+ });
+ return CALLREGCOMP_ENG(eng, pattern, flags);
}
#endif
{
SV *pat = pattern; /* defeat constness! */
PERL_ARGS_ASSERT_RE_COMPILE;
- return Perl_re_op_compile(aTHX_ &pat, 1, NULL,
- NULL, NULL, NULL, rx_flags, 0);
+ return Perl_re_op_compile(aTHX_ &pat, 1, NULL, current_re_engine(),
+ NULL, NULL, rx_flags, 0);
}
* If the pattern hasn't changed from old_re, then old_re will be
* returned.
*
- * If eng is set (and not equal to PL_core_reg_engine), then just do the
- * initial concatenation of arguments, then pass on to the external
+ * eng is the current engine. If that engine has an op_comp method, then
+ * handle directly (i.e. we assume that op_comp was us); otherwise, just
+ * do the initial concatenation of arguments and pass on to the external
* engine.
*
* If is_bare_re is not null, set it to a boolean indicating whether the
#endif
GET_RE_DEBUG_FLAGS_DECL;
+ PERL_ARGS_ASSERT_RE_OP_COMPILE;
+
DEBUG_r(if (!PL_colorset) reginitcolors());
#ifndef PERL_IN_XSUB_RE
if (SvROK(rx))
rx = SvRV(rx);
if (SvTYPE(rx) == SVt_REGEXP
- && RX_ENGINE((REGEXP*)rx) == RE_ENGINE_PTR)
+ && RX_ENGINE((REGEXP*)rx)->op_comp)
{
RXi_GET_DECL(((struct regexp*)SvANY(rx)), ri);
exp = SvPV_nomg(pat, plen);
- if (eng && eng != RE_ENGINE_PTR) {
+ if (!eng->op_comp) {
if ((SvUTF8(pat) && IN_BYTES)
|| SvGMAGICAL(pat) || SvAMAGIC(pat))
{
/* non-zero initialization begins here */
RXi_SET( r, ri );
- r->engine= RE_ENGINE_PTR;
+ r->engine= eng;
r->extflags = rx_flags;
if (pm_flags & PMf_IS_QR) {
ri->code_blocks = pRExC_state->code_blocks;
return rx;
}
-#undef RE_ENGINE_PTR
-
SV*
Perl_reg_named_buff(pTHX_ REGEXP * const rx, SV * const key, SV * const value,
Perl_reg_named_buff_iter,
Perl_reg_qr_package,
#if defined(USE_ITHREADS)
- Perl_regdupe_internal
+ Perl_regdupe_internal,
#endif
+ Perl_re_op_compile
};
#endif /* DOINIT */
#endif /* PLUGGABLE_RE_EXTENSION */
#ifdef USE_ITHREADS
void* (*dupe) (pTHX_ REGEXP * const rx, CLONE_PARAMS *param);
#endif
+ REGEXP* (*op_comp) (pTHX_ SV ** const patternp, int pat_count,
+ OP *expr, const struct regexp_engine* eng,
+ REGEXP *VOL old_re,
+ int *is_bare_re, U32 orig_rx_flags, U32 pm_flags);
} regexp_engine;
/*