typedef struct RExC_state_t {
U32 flags; /* are we folding, multilining? */
char *precomp; /* uncompiled string. */
- regexp *rx;
+ regexp *rx; /* perl core regexp structure */
+ regexp_internal *rxi; /* internal data for regexp object pprivate field */
char *start; /* Start of input for compile */
char *end; /* End of input for compile */
char *parse; /* Input-scan pointer. */
#define RExC_flags (pRExC_state->flags)
#define RExC_precomp (pRExC_state->precomp)
#define RExC_rx (pRExC_state->rx)
+#define RExC_rxi (pRExC_state->rxi)
#define RExC_start (pRExC_state->start)
#define RExC_end (pRExC_state->end)
#define RExC_parse (pRExC_state->parse)
#define RExC_whilem_seen (pRExC_state->whilem_seen)
-#define RExC_offsets (pRExC_state->rx->offsets) /* I am not like the others */
+#define RExC_offsets (pRExC_state->rxi->offsets) /* I am not like the others */
#define RExC_emit (pRExC_state->emit)
#define RExC_emit_start (pRExC_state->emit_start)
#define RExC_naughty (pRExC_state->naughty)
trie->refcount = 1;
trie->startstate = 1;
trie->wordcount = word_count;
- RExC_rx->data->data[ data_slot ] = (void*)trie;
+ RExC_rxi->data->data[ data_slot ] = (void*)trie;
Newxz( trie->charmap, 256, U16 );
if (!(UTF && folder))
Newxz( trie->bitmap, ANYOF_BITMAP_SIZE, char );
try 'g' and succeed, prodceding to match 'cdgu'.
*/
/* add a fail transition */
- reg_trie_data *trie=(reg_trie_data *)RExC_rx->data->data[ARG(source)];
+ reg_trie_data *trie=(reg_trie_data *)RExC_rxi->data->data[ARG(source)];
U32 *q;
const U32 ucharcount = trie->uniquecharcount;
const U32 numstates = trie->statecount;
ARG_SET( stclass, data_slot );
Newxz( aho, 1, reg_ac_data );
- RExC_rx->data->data[ data_slot ] = (void*)aho;
+ RExC_rxi->data->data[ data_slot ] = (void*)aho;
aho->trie=trie;
aho->states=(reg_trie_state *)savepvn((const char*)trie->states,
numstates * sizeof(reg_trie_state));
end = RExC_close_parens[paren-1];
} else {
paren = 0;
- start = RExC_rx->program + 1;
+ start = RExC_rxi->program + 1;
end = RExC_opend;
}
if (!recursed) {
check there too. */
regnode *trie_node= scan;
regnode *tail= regnext(scan);
- reg_trie_data *trie = (reg_trie_data*)RExC_rx->data->data[ ARG(scan) ];
+ reg_trie_data *trie = (reg_trie_data*)RExC_rxi->data->data[ ARG(scan) ];
I32 max1 = 0, min1 = I32_MAX;
struct regnode_charclass_class accum;
}
#else
else if (PL_regkind[OP(scan)] == TRIE) {
- reg_trie_data *trie = (reg_trie_data*)RExC_rx->data->data[ ARG(scan) ];
+ reg_trie_data *trie = (reg_trie_data*)RExC_rxi->data->data[ ARG(scan) ];
U8*bang=NULL;
min += trie->minlen;
STATIC I32
S_add_data(RExC_state_t *pRExC_state, I32 n, const char *s)
{
- if (RExC_rx->data) {
- const U32 count = RExC_rx->data->count;
- Renewc(RExC_rx->data,
- sizeof(*RExC_rx->data) + sizeof(void*) * (count + n - 1),
+ if (RExC_rxi->data) {
+ const U32 count = RExC_rxi->data->count;
+ Renewc(RExC_rxi->data,
+ sizeof(*RExC_rxi->data) + sizeof(void*) * (count + n - 1),
char, struct reg_data);
- Renew(RExC_rx->data->what, count + n, U8);
- RExC_rx->data->count += n;
+ Renew(RExC_rxi->data->what, count + n, U8);
+ RExC_rxi->data->count += n;
}
else {
- Newxc(RExC_rx->data, sizeof(*RExC_rx->data) + sizeof(void*) * (n - 1),
+ Newxc(RExC_rxi->data, sizeof(*RExC_rxi->data) + sizeof(void*) * (n - 1),
char, struct reg_data);
- Newx(RExC_rx->data->what, n, U8);
- RExC_rx->data->count = n;
+ Newx(RExC_rxi->data->what, n, U8);
+ RExC_rxi->data->count = n;
}
- Copy(s, RExC_rx->data->what + RExC_rx->data->count - n, n, U8);
- return RExC_rx->data->count - n;
+ Copy(s, RExC_rxi->data->what + RExC_rxi->data->count - n, n, U8);
+ return RExC_rxi->data->count - n;
}
#ifndef PERL_IN_XSUB_RE
#endif
BEGIN_BLOCK
register regexp *r;
+ register regexp_internal *ri;
regnode *scan;
regnode *first;
I32 flags;
/* Allocate space and zero-initialize. Note, the two step process
of zeroing when in debug mode, thus anything assigned has to
happen after that */
- Newxc(r, sizeof(regexp) + (unsigned)RExC_size * sizeof(regnode),
- char, regexp);
- if (r == NULL)
+ Newxz(r, 1, regexp);
+ Newxc(ri, sizeof(regexp_internal) + (unsigned)RExC_size * sizeof(regnode),
+ char, regexp_internal);
+ if ( r == NULL || ri == NULL )
FAIL("Regexp out of space");
#ifdef DEBUGGING
/* avoid reading uninitialized memory in DEBUGGING code in study_chunk() */
- Zero(r, sizeof(regexp) + (unsigned)RExC_size * sizeof(regnode), char);
+ Zero(ri, sizeof(regexp_internal) + (unsigned)RExC_size * sizeof(regnode), char);
#else
- /* bulk initialize fields with 0. */
- Zero(r, sizeof(regexp), char);
+ /* bulk initialize base fields with 0. */
+ Zero(ri, sizeof(regexp_internal), char);
#endif
/* non-zero initialization begins here */
+ RXi_SET( r, ri );
r->engine= RE_ENGINE_PTR;
r->refcnt = 1;
r->prelen = xend - exp;
}
/* Useful during FAIL. */
- Newxz(r->offsets, 2*RExC_size+1, U32); /* MJD 20001228 */
- if (r->offsets) {
- r->offsets[0] = RExC_size;
+ Newxz(ri->offsets, 2*RExC_size+1, U32); /* MJD 20001228 */
+ if (ri->offsets) {
+ ri->offsets[0] = RExC_size;
}
DEBUG_OFFSETS_r(PerlIO_printf(Perl_debug_log,
"%s %"UVuf" bytes for offset annotations.\n",
- r->offsets ? "Got" : "Couldn't get",
+ ri->offsets ? "Got" : "Couldn't get",
(UV)((2*RExC_size+1) * sizeof(U32))));
RExC_rx = r;
+ RExC_rxi = ri;
/* Second pass: emit code. */
RExC_flags = pm->op_pmflags; /* don't let top level (?i) bleed */
RExC_naughty = 0;
RExC_npar = 1;
RExC_cpar = 1;
- RExC_emit_start = r->program;
- RExC_emit = r->program;
+ RExC_emit_start = ri->program;
+ RExC_emit = ri->program;
#ifdef DEBUGGING
/* put a sentinal on the end of the program so we can check for
overwrites */
- r->program[RExC_size].type = 255;
+ ri->program[RExC_size].type = 255;
#endif
/* Store the count of eval-groups for security checks: */
RExC_emit->next_off = (RExC_seen_evals > (I32)U16_MAX) ? U16_MAX : (U16)RExC_seen_evals;
REGC((U8)REG_MAGIC, (char*) RExC_emit++);
- r->data = 0;
if (reg(pRExC_state, 0, &flags,1) == NULL)
return(NULL);
pm->op_pmflags = RExC_flags;
if (UTF)
r->extflags |= RXf_UTF8; /* Unicode in it? */
- r->regstclass = NULL;
+ ri->regstclass = NULL;
if (RExC_naughty >= 10) /* Probably an expensive pattern. */
r->intflags |= PREGf_NAUGHTY;
- scan = r->program + 1; /* First BRANCH. */
+ scan = ri->program + 1; /* First BRANCH. */
/* testing for BRANCH here tells us whether there is "must appear"
data in the pattern. If there is then we can use it for optimisations */
if (OP(first) == EXACT)
NOOP; /* Empty, get anchored substr later. */
else if ((OP(first) == EXACTF || OP(first) == EXACTFL))
- r->regstclass = first;
+ ri->regstclass = first;
}
#ifdef TRIE_STCLASS
else if (PL_regkind[OP(first)] == TRIE &&
- ((reg_trie_data *)r->data->data[ ARG(first) ])->minlen>0)
+ ((reg_trie_data *)ri->data->data[ ARG(first) ])->minlen>0)
{
regnode *trie_op;
/* this can happen only on restudy */
}
OP(trie_op)+=2;
make_trie_failtable(pRExC_state, (regnode *)first, trie_op, 0);
- r->regstclass = trie_op;
+ ri->regstclass = trie_op;
}
#endif
else if (strchr((const char*)PL_simple,OP(first)))
- r->regstclass = first;
+ ri->regstclass = first;
else if (PL_regkind[OP(first)] == BOUND ||
PL_regkind[OP(first)] == NBOUND)
- r->regstclass = first;
+ ri->regstclass = first;
else if (PL_regkind[OP(first)] == BOL) {
r->extflags |= (OP(first) == MBOL
? RXf_ANCH_MBOL
data.last_found = newSVpvs("");
data.longest = &(data.longest_fixed);
first = scan;
- if (!r->regstclass) {
+ if (!ri->regstclass) {
cl_init(pRExC_state, &ch_class);
data.start_class = &ch_class;
stclass_flag = SCF_DO_STCLASS_AND;
SvREFCNT_dec(data.longest_fixed);
longest_fixed_length = 0;
}
- if (r->regstclass
- && (OP(r->regstclass) == REG_ANY || OP(r->regstclass) == SANY))
- r->regstclass = NULL;
+ if (ri->regstclass
+ && (OP(ri->regstclass) == REG_ANY || OP(ri->regstclass) == SANY))
+ ri->regstclass = NULL;
if ((!(r->anchored_substr || r->anchored_utf8) || r->anchored_offset)
&& stclass_flag
&& !(data.start_class->flags & ANYOF_EOS)
{
const I32 n = add_data(pRExC_state, 1, "f");
- Newx(RExC_rx->data->data[n], 1,
+ Newx(RExC_rxi->data->data[n], 1,
struct regnode_charclass_class);
StructCopy(data.start_class,
- (struct regnode_charclass_class*)RExC_rx->data->data[n],
+ (struct regnode_charclass_class*)RExC_rxi->data->data[n],
struct regnode_charclass_class);
- r->regstclass = (regnode*)RExC_rx->data->data[n];
+ ri->regstclass = (regnode*)RExC_rxi->data->data[n];
r->intflags &= ~PREGf_SKIP; /* Used in find_byclass(). */
DEBUG_COMPILE_r({ SV *sv = sv_newmortal();
regprop(r, sv, (regnode*)data.start_class);
DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log, "\nMulti Top Level\n"));
- scan = r->program + 1;
+ scan = ri->program + 1;
cl_init(pRExC_state, &ch_class);
data.start_class = &ch_class;
data.last_closep = &last_close;
{
const I32 n = add_data(pRExC_state, 1, "f");
- Newx(RExC_rx->data->data[n], 1,
+ Newx(RExC_rxi->data->data[n], 1,
struct regnode_charclass_class);
StructCopy(data.start_class,
- (struct regnode_charclass_class*)RExC_rx->data->data[n],
+ (struct regnode_charclass_class*)RExC_rxi->data->data[n],
struct regnode_charclass_class);
- r->regstclass = (regnode*)RExC_rx->data->data[n];
+ ri->regstclass = (regnode*)RExC_rxi->data->data[n];
r->intflags &= ~PREGf_SKIP; /* Used in find_byclass(). */
DEBUG_COMPILE_r({ SV* sv = sv_newmortal();
regprop(r, sv, (regnode*)data.start_class);
PerlIO_printf(Perl_debug_log,"Final program:\n");
regdump(r);
});
- DEBUG_OFFSETS_r(if (r->offsets) {
- const U32 len = r->offsets[0];
+ DEBUG_OFFSETS_r(if (ri->offsets) {
+ const U32 len = ri->offsets[0];
U32 i;
GET_RE_DEBUG_FLAGS_DECL;
- PerlIO_printf(Perl_debug_log, "Offsets: [%"UVuf"]\n\t", (UV)r->offsets[0]);
+ PerlIO_printf(Perl_debug_log, "Offsets: [%"UVuf"]\n\t", (UV)ri->offsets[0]);
for (i = 1; i <= len; i++) {
- if (r->offsets[i*2-1] || r->offsets[i*2])
+ if (ri->offsets[i*2-1] || ri->offsets[i*2])
PerlIO_printf(Perl_debug_log, "%"UVuf":%"UVuf"[%"UVuf"] ",
- (UV)i, (UV)r->offsets[i*2-1], (UV)r->offsets[i*2]);
+ (UV)i, (UV)ri->offsets[i*2-1], (UV)ri->offsets[i*2]);
}
PerlIO_printf(Perl_debug_log, "\n");
});
if (start_arg) {
SV *sv = newSVpvn( start_arg, RExC_parse - start_arg);
ARG(ret) = add_data( pRExC_state, 1, "S" );
- RExC_rx->data->data[ARG(ret)]=(void*)sv;
+ RExC_rxi->data->data[ARG(ret)]=(void*)sv;
ret->flags = 0;
} else {
ret->flags = 1;
LEAVE;
n = add_data(pRExC_state, 3, "nop");
- RExC_rx->data->data[n] = (void*)rop;
- RExC_rx->data->data[n+1] = (void*)sop;
- RExC_rx->data->data[n+2] = (void*)pad;
+ RExC_rxi->data->data[n] = (void*)rop;
+ RExC_rxi->data->data[n+1] = (void*)sop;
+ RExC_rxi->data->data[n+2] = (void*)pad;
SvREFCNT_dec(sv);
}
else { /* First pass */
RExC_parse++;
if (!SIZE_ONLY) {
num = add_data( pRExC_state, 1, "S" );
- RExC_rx->data->data[num]=(void*)sv_dat;
+ RExC_rxi->data->data[num]=(void*)sv_dat;
SvREFCNT_inc(sv_dat);
}
ret = reganode(pRExC_state,NGROUPP,num);
if (!SIZE_ONLY) {
num = add_data( pRExC_state, 1, "S" );
ARG_SET(ret,num);
- RExC_rx->data->data[num]=(void*)sv_dat;
+ RExC_rxi->data->data[num]=(void*)sv_dat;
SvREFCNT_inc(sv_dat);
}
/* override incorrect value set in reganode MJD */
av_store(av, 2, (SV*)unicode_alternate);
rv = newRV_noinc((SV*)av);
n = add_data(pRExC_state, 1, "s");
- RExC_rx->data->data[n] = (void*)rv;
+ RExC_rxi->data->data[n] = (void*)rv;
ARG_SET(ret, n);
}
return ret;
dVAR;
SV * const sv = sv_newmortal();
SV *dsv= sv_newmortal();
+ RXi_GET_DECL(r,ri);
- (void)dumpuntil(r, r->program, r->program + 1, NULL, NULL, sv, 0, 0);
+ (void)dumpuntil(r, ri->program, ri->program + 1, NULL, NULL, sv, 0, 0);
/* Header fields of interest. */
if (r->anchored_substr) {
if (r->check_substr || r->check_utf8)
PerlIO_printf(Perl_debug_log, ") ");
- if (r->regstclass) {
- regprop(r, sv, r->regstclass);
+ if (ri->regstclass) {
+ regprop(r, sv, ri->regstclass);
PerlIO_printf(Perl_debug_log, "stclass %s ", SvPVX_const(sv));
}
if (r->extflags & RXf_ANCH) {
#ifdef DEBUGGING
dVAR;
register int k;
+ RXi_GET_DECL(prog,progi);
GET_RE_DEBUG_FLAGS_DECL;
+
sv_setpvn(sv, "", 0);
Perl_sv_catpvf(aTHX_ sv, " %s", s );
} else if (k == TRIE) {
/* print the details of the trie in dumpuntil instead, as
- * prog->data isn't available here */
+ * progi->data isn't available here */
const char op = OP(o);
const I32 n = ARG(o);
const reg_ac_data * const ac = IS_TRIE_AC(op) ?
- (reg_ac_data *)prog->data->data[n] :
+ (reg_ac_data *)progi->data->data[n] :
NULL;
const reg_trie_data * const trie = !IS_TRIE_AC(op) ?
- (reg_trie_data*)prog->data->data[n] :
+ (reg_trie_data*)progi->data->data[n] :
ac->trie;
Perl_sv_catpvf(aTHX_ sv, "-%s",reg_name[o->flags]);
else if (k == VERB) {
if (!o->flags)
Perl_sv_catpvf(aTHX_ sv, ":%"SVf,
- (SV*)prog->data->data[ ARG( o ) ]);
+ (SV*)progi->data->data[ ARG( o ) ]);
} else if (k == LOGICAL)
Perl_sv_catpvf(aTHX_ sv, "[%d]", o->flags); /* 2: embedded, otherwise 1 */
else if (k == ANYOF) {
Perl_pregfree(pTHX_ struct regexp *r)
{
dVAR;
-
+ RXi_GET_DECL(r,ri);
GET_RE_DEBUG_FLAGS_DECL;
if (!r || (--r->refcnt > 0))
/* gcov results gave these as non-null 100% of the time, so there's no
optimisation in checking them before calling Safefree */
Safefree(r->precomp);
- Safefree(r->offsets); /* 20010421 MJD */
+ Safefree(ri->offsets); /* 20010421 MJD */
RX_MATCH_COPY_FREE(r);
#ifdef PERL_OLD_COPY_ON_WRITE
if (r->saved_copy)
}
if (r->paren_names)
SvREFCNT_dec(r->paren_names);
- if (r->data) {
- int n = r->data->count;
+ if (ri->data) {
+ int n = ri->data->count;
PAD* new_comppad = NULL;
PAD* old_comppad;
PADOFFSET refcnt;
while (--n >= 0) {
/* If you add a ->what type here, update the comment in regcomp.h */
- switch (r->data->what[n]) {
+ switch (ri->data->what[n]) {
case 's':
case 'S':
- SvREFCNT_dec((SV*)r->data->data[n]);
+ SvREFCNT_dec((SV*)ri->data->data[n]);
break;
case 'f':
- Safefree(r->data->data[n]);
+ Safefree(ri->data->data[n]);
break;
case 'p':
- new_comppad = (AV*)r->data->data[n];
+ new_comppad = (AV*)ri->data->data[n];
break;
case 'o':
if (new_comppad == NULL)
(SvTYPE(new_comppad) == SVt_PVAV) ? new_comppad : NULL
);
OP_REFCNT_LOCK;
- refcnt = OpREFCNT_dec((OP_4tree*)r->data->data[n]);
+ refcnt = OpREFCNT_dec((OP_4tree*)ri->data->data[n]);
OP_REFCNT_UNLOCK;
if (!refcnt)
- op_free((OP_4tree*)r->data->data[n]);
+ op_free((OP_4tree*)ri->data->data[n]);
PAD_RESTORE_LOCAL(old_comppad);
SvREFCNT_dec((SV*)new_comppad);
{ /* Aho Corasick add-on structure for a trie node.
Used in stclass optimization only */
U32 refcount;
- reg_ac_data *aho=(reg_ac_data*)r->data->data[n];
+ reg_ac_data *aho=(reg_ac_data*)ri->data->data[n];
OP_REFCNT_LOCK;
refcount = --aho->refcount;
OP_REFCNT_UNLOCK;
Safefree(aho->fail);
aho->trie=NULL; /* not necessary to free this as it is
handled by the 't' case */
- Safefree(r->data->data[n]); /* do this last!!!! */
- Safefree(r->regstclass);
+ Safefree(ri->data->data[n]); /* do this last!!!! */
+ Safefree(ri->regstclass);
}
}
break;
{
/* trie structure. */
U32 refcount;
- reg_trie_data *trie=(reg_trie_data*)r->data->data[n];
+ reg_trie_data *trie=(reg_trie_data*)ri->data->data[n];
OP_REFCNT_LOCK;
refcount = --trie->refcount;
OP_REFCNT_UNLOCK;
if (trie->revcharmap)
SvREFCNT_dec((SV*)trie->revcharmap);
#endif
- Safefree(r->data->data[n]); /* do this last!!!! */
+ Safefree(ri->data->data[n]); /* do this last!!!! */
}
}
break;
default:
- Perl_croak(aTHX_ "panic: regfree data code '%c'", r->data->what[n]);
+ Perl_croak(aTHX_ "panic: regfree data code '%c'", ri->data->what[n]);
}
}
- Safefree(r->data->what);
- Safefree(r->data);
+ Safefree(ri->data->what);
+ Safefree(ri->data);
}
Safefree(r->startp);
Safefree(r->endp);
- if (r->swap) {
- Safefree(r->swap->startp);
- Safefree(r->swap->endp);
- Safefree(r->swap);
+ if (ri->swap) {
+ Safefree(ri->swap->startp);
+ Safefree(ri->swap->endp);
+ Safefree(ri->swap);
}
+ Safefree(ri);
Safefree(r);
}
Perl_regdupe(pTHX_ const regexp *r, CLONE_PARAMS *param)
{
dVAR;
- REGEXP *ret;
+ regexp *ret;
+ regexp_internal *reti;
int i, len, npar;
struct reg_substr_datum *s;
-
+ RXi_GET_DECL(r,ri);
+
if (!r)
return (REGEXP *)NULL;
if ((ret = (REGEXP *)ptr_table_fetch(PL_ptr_table, r)))
return ret;
- len = r->offsets[0];
+ len = ri->offsets[0];
npar = r->nparens+1;
- Newxc(ret, sizeof(regexp) + (len+1)*sizeof(regnode), char, regexp);
- Copy(r->program, ret->program, len+1, regnode);
+ Newxz(ret, 1, regexp);
+ Newxc(reti, sizeof(regexp_internal) + (len+1)*sizeof(regnode), char, regexp_internal);
+ RXi_SET(ret,reti);
+ Copy(ri->program, reti->program, len+1, regnode);
Newx(ret->startp, npar, I32);
Copy(r->startp, ret->startp, npar, I32);
Newx(ret->endp, npar, I32);
Copy(r->startp, ret->startp, npar, I32);
- if(r->swap) {
- Newx(ret->swap, 1, regexp_paren_ofs);
+ if(ri->swap) {
+ Newx(reti->swap, 1, regexp_paren_ofs);
/* no need to copy these */
- Newx(ret->swap->startp, npar, I32);
- Newx(ret->swap->endp, npar, I32);
+ Newx(reti->swap->startp, npar, I32);
+ Newx(reti->swap->endp, npar, I32);
} else {
- ret->swap = NULL;
+ reti->swap = NULL;
}
Newx(ret->substrs, 1, struct reg_substr_data);
s->utf8_substr = sv_dup_inc(r->substrs->data[i].utf8_substr, param);
}
- ret->regstclass = NULL;
- if (r->data) {
+ reti->regstclass = NULL;
+ if (ri->data) {
struct reg_data *d;
- const int count = r->data->count;
+ const int count = ri->data->count;
int i;
Newxc(d, sizeof(struct reg_data) + count*sizeof(void *),
d->count = count;
for (i = 0; i < count; i++) {
- d->what[i] = r->data->what[i];
+ d->what[i] = ri->data->what[i];
switch (d->what[i]) {
/* legal options are one of: sSfpontT
see also regcomp.h and pregfree() */
case 's':
case 'S':
- d->data[i] = sv_dup_inc((SV *)r->data->data[i], param);
+ d->data[i] = sv_dup_inc((SV *)ri->data->data[i], param);
break;
case 'p':
- d->data[i] = av_dup_inc((AV *)r->data->data[i], param);
+ d->data[i] = av_dup_inc((AV *)ri->data->data[i], param);
break;
case 'f':
/* This is cheating. */
Newx(d->data[i], 1, struct regnode_charclass_class);
- StructCopy(r->data->data[i], d->data[i],
+ StructCopy(ri->data->data[i], d->data[i],
struct regnode_charclass_class);
- ret->regstclass = (regnode*)d->data[i];
+ reti->regstclass = (regnode*)d->data[i];
break;
case 'o':
/* Compiled op trees are readonly and in shared memory,
and can thus be shared without duplication. */
OP_REFCNT_LOCK;
- d->data[i] = (void*)OpREFCNT_inc((OP*)r->data->data[i]);
+ d->data[i] = (void*)OpREFCNT_inc((OP*)ri->data->data[i]);
OP_REFCNT_UNLOCK;
break;
case 'n':
- d->data[i] = r->data->data[i];
+ d->data[i] = ri->data->data[i];
break;
case 't':
- d->data[i] = r->data->data[i];
+ d->data[i] = ri->data->data[i];
OP_REFCNT_LOCK;
((reg_trie_data*)d->data[i])->refcount++;
OP_REFCNT_UNLOCK;
break;
case 'T':
- d->data[i] = r->data->data[i];
+ d->data[i] = ri->data->data[i];
OP_REFCNT_LOCK;
((reg_ac_data*)d->data[i])->refcount++;
OP_REFCNT_UNLOCK;
* without duplication. We free the stclass in pregfree
* when the corresponding reg_ac_data struct is freed.
*/
- ret->regstclass= r->regstclass;
+ reti->regstclass= ri->regstclass;
break;
default:
- Perl_croak(aTHX_ "panic: re_dup unknown data code '%c'", r->data->what[i]);
+ Perl_croak(aTHX_ "panic: re_dup unknown data code '%c'", ri->data->what[i]);
}
}
- ret->data = d;
+ reti->data = d;
}
else
- ret->data = NULL;
+ reti->data = NULL;
- Newx(ret->offsets, 2*len+1, U32);
- Copy(r->offsets, ret->offsets, 2*len+1, U32);
+ Newx(reti->offsets, 2*len+1, U32);
+ Copy(ri->offsets, reti->offsets, 2*len+1, U32);
ret->precomp = SAVEPVN(r->precomp, r->prelen);
ret->refcnt = r->refcnt;
Perl_reg_stringify(pTHX_ MAGIC *mg, STRLEN *lp, U32 *flags, I32 *haseval ) {
dVAR;
const regexp * const re = (regexp *)mg->mg_obj;
-
+ RXi_GET_DECL(re,ri);
+
if (!mg->mg_ptr) {
const char *fptr = "msix";
char reflags[6];
mg->mg_ptr[mg->mg_len] = 0;
}
if (haseval)
- *haseval = re->program[0].next_off;
+ *haseval = ri->program[0].next_off;
if (flags)
*flags = ((re->extflags & RXf_UTF8) ? 1 : 0);
dVAR;
register I32 offset;
- if (p == &PL_regdummy)
+ if (!p)
return(NULL);
offset = (reg_off_by_arg[OP(p)] ? ARG(p) : NEXT_OFF(p));
register U8 op = PSEUDO; /* Arbitrary non-END op. */
register const regnode *next;
const regnode *optstart= NULL;
+ RXi_GET_DECL(r,ri);
GET_RE_DEBUG_FLAGS_DECL;
#ifdef DEBUG_DUMPUNTIL
const char op = OP(node);
const I32 n = ARG(node);
const reg_ac_data * const ac = op>=AHOCORASICK ?
- (reg_ac_data *)r->data->data[n] :
+ (reg_ac_data *)ri->data->data[n] :
NULL;
const reg_trie_data * const trie = op<AHOCORASICK ?
- (reg_trie_data*)r->data->data[n] :
+ (reg_trie_data*)ri->data->data[n] :
ac->trie;
const regnode *nextbranch= NULL;
I32 word_idx;
register char *other_last = NULL; /* other substr checked before this */
char *check_at = NULL; /* check substr found at this pos */
const I32 multiline = prog->extflags & RXf_PMf_MULTILINE;
+ RXi_GET_DECL(prog,progi);
#ifdef DEBUGGING
const char * const i_strpos = strpos;
#endif
/* XXXX BmUSEFUL already changed, maybe multiple change is meaningful... */
/* trie stclasses are too expensive to use here, we are better off to
leave it to regmatch itself */
- if (prog->regstclass && PL_regkind[OP(prog->regstclass)]!=TRIE) {
+ if (progi->regstclass && PL_regkind[OP(progi->regstclass)]!=TRIE) {
/* minlen == 0 is possible if regstclass is \b or \B,
and the fixed substr is ''$.
Since minlen is already taken into account, s+1 is before strend;
regstclass does not come from lookahead... */
/* If regstclass takes bytelength more than 1: If charlength==1, OK.
This leaves EXACTF only, which is dealt with in find_byclass(). */
- const U8* const str = (U8*)STRING(prog->regstclass);
- const int cl_l = (PL_regkind[OP(prog->regstclass)] == EXACT
- ? CHR_DIST(str+STR_LEN(prog->regstclass), str)
+ const U8* const str = (U8*)STRING(progi->regstclass);
+ const int cl_l = (PL_regkind[OP(progi->regstclass)] == EXACT
+ ? CHR_DIST(str+STR_LEN(progi->regstclass), str)
: 1);
char * endpos;
if (prog->anchored_substr || prog->anchored_utf8 || ml_anch)
(IV)start_shift, check_at - strbeg, s - strbeg, endpos - strbeg));
t = s;
- s = find_byclass(prog, prog->regstclass, s, endpos, NULL);
+ s = find_byclass(prog, progi->regstclass, s, endpos, NULL);
if (!s) {
#ifdef DEBUGGING
const char *what = NULL;
char *e;
register I32 tmp = 1; /* Scratch variable? */
register const bool do_utf8 = PL_reg_match_utf8;
-
+ RXi_GET_DECL(prog,progi);
+
/* We know what class it must start with. */
switch (OP(c)) {
case ANYOF:
: trie_plain;
/* what trie are we using right now */
reg_ac_data *aho
- = (reg_ac_data*)prog->data->data[ ARG( c ) ];
+ = (reg_ac_data*)progi->data->data[ ARG( c ) ];
reg_trie_data *trie=aho->trie;
const char *last_start = strend - trie->minlen;
SV* const oreplsv = GvSV(PL_replgv);
const bool do_utf8 = (bool)DO_UTF8(sv);
I32 multiline;
-
+ RXi_GET_DECL(prog,progi);
regmatch_info reginfo; /* create some info to pass to regtry etc */
GET_RE_DEBUG_FLAGS_DECL;
/* Check validity of program. */
- if (UCHARAT(prog->program) != REG_MAGIC) {
+ if (UCHARAT(progi->program) != REG_MAGIC) {
Perl_croak(aTHX_ "corrupted regexp program");
}
}
if (PL_curpm && (PM_GETRE(PL_curpm) == prog)) {
I32 *t;
- if (!prog->swap) {
+ if (!progi->swap) {
/* We have to be careful. If the previous successful match
was from this regex we don't want a subsequent paritally
successful match to clobber the old results.
to the re, and switch the buffer each match. If we fail
we switch it back, otherwise we leave it swapped.
*/
- Newxz(prog->swap, 1, regexp_paren_ofs);
+ Newxz(progi->swap, 1, regexp_paren_ofs);
/* no need to copy these */
- Newxz(prog->swap->startp, prog->nparens + 1, I32);
- Newxz(prog->swap->endp, prog->nparens + 1, I32);
+ Newxz(progi->swap->startp, prog->nparens + 1, I32);
+ Newxz(progi->swap->endp, prog->nparens + 1, I32);
}
- t = prog->swap->startp;
- prog->swap->startp = prog->startp;
+ t = progi->swap->startp;
+ progi->swap->startp = prog->startp;
prog->startp = t;
- t = prog->swap->endp;
- prog->swap->endp = prog->endp;
+ t = progi->swap->endp;
+ progi->swap->endp = prog->endp;
prog->endp = t;
}
if (!(flags & REXEC_CHECKED) && (prog->check_substr != NULL || prog->check_utf8 != NULL)) {
});
goto phooey;
}
- else if ( (c = prog->regstclass) ) {
+ else if ( (c = progi->regstclass) ) {
if (minlen) {
- const OPCODE op = OP(prog->regstclass);
+ const OPCODE op = OP(progi->regstclass);
/* don't bother with what can't match */
if (PL_regkind[op] != EXACT && op != CANY && PL_regkind[op] != TRIE)
strend = HOPc(strend, -(minlen - 1));
PL_colors[4], PL_colors[5]));
if (PL_reg_eval_set)
restore_pos(aTHX_ prog);
- if (prog->swap) {
+ if (progi->swap) {
/* we failed :-( roll it back */
I32 *t;
- t = prog->swap->startp;
- prog->swap->startp = prog->startp;
+ t = progi->swap->startp;
+ progi->swap->startp = prog->startp;
prog->startp = t;
- t = prog->swap->endp;
- prog->swap->endp = prog->endp;
+ t = progi->swap->endp;
+ progi->swap->endp = prog->endp;
prog->endp = t;
}
return 0;
register I32 *ep;
CHECKPOINT lastcp;
regexp *prog = reginfo->prog;
+ RXi_GET_DECL(prog,progi);
GET_RE_DEBUG_FLAGS_DECL;
reginfo->cutpoint=NULL;
}
#endif
REGCP_SET(lastcp);
- if (regmatch(reginfo, prog->program + 1)) {
+ if (regmatch(reginfo, progi->program + 1)) {
PL_regendp[0] = PL_reginput - PL_bostr;
return 1;
}
STATIC I32
S_reg_check_named_buff_matched(pTHX_ const regexp *rex, const regnode *scan) {
I32 n;
- SV *sv_dat=(SV*)rex->data->data[ ARG( scan ) ];
+ RXi_GET_DECL(rex,rexi);
+ SV *sv_dat=(SV*)rexi->data->data[ ARG( scan ) ];
I32 *nums=(I32*)SvPVX(sv_dat);
for ( n=0; n<SvIVX(sv_dat); n++ ) {
if ((I32)*PL_reglastparen >= nums[n] &&
const U32 uniflags = UTF8_ALLOW_DEFAULT;
regexp *rex = reginfo->prog;
-
+ RXi_GET_DECL(rex,rexi);
+
regmatch_slab *orig_slab;
regmatch_state *orig_state;
PerlIO_printf(Perl_debug_log,
"%3"IVdf":%*s%s(%"IVdf")\n",
- (IV)(scan - rex->program), depth*2, "",
+ (IV)(scan - rexi->program), depth*2, "",
SvPVX_const(prop),
(PL_regkind[OP(scan)] == END || !rnext) ?
- 0 : (IV)(rnext - rex->program));
+ 0 : (IV)(rnext - rexi->program));
});
next = scan + NEXT_OFF(scan);
/* what trie are we using right now */
reg_trie_data * const trie
- = (reg_trie_data*)rex->data->data[ ARG( scan ) ];
+ = (reg_trie_data*)rexi->data->data[ ARG( scan ) ];
U32 state = trie->startstate;
if (trie->bitmap && trie_type != trie_utf8_fold &&
/* only one choice left - just continue */
DEBUG_EXECUTE_r({
reg_trie_data * const trie
- = (reg_trie_data*)rex->data->data[ ARG(ST.me) ];
+ = (reg_trie_data*)rexi->data->data[ ARG(ST.me) ];
SV ** const tmp = av_fetch( trie->words,
ST.accept_buff[ 0 ].wordnum-1, 0 );
SV *sv= tmp ? sv_newmortal() : NULL;
DEBUG_EXECUTE_r({
reg_trie_data * const trie
- = (reg_trie_data*)rex->data->data[ ARG(ST.me) ];
+ = (reg_trie_data*)rexi->data->data[ ARG(ST.me) ];
SV ** const tmp = av_fetch( trie->words,
ST.accept_buff[ best ].wordnum - 1, 0 );
regnode *nextop=(!ST.jump || !ST.jump[ST.accept_buff[best].wordnum]) ?
{
SV *ret;
regexp *re;
+ regexp_internal *rei;
regnode *startpoint;
case GOSTART:
nochange_depth = 0;
}
re = rex;
+ rei = rexi;
(void)ReREFCNT_inc(rex);
if (OP(scan)==GOSUB) {
startpoint = scan + ARG2L(scan);
ST.close_paren = ARG(scan);
} else {
- startpoint = re->program+1;
+ startpoint = rei->program+1;
ST.close_paren = 0;
}
goto eval_recurse_doit;
PAD *old_comppad;
n = ARG(scan);
- PL_op = (OP_4tree*)rex->data->data[n];
+ PL_op = (OP_4tree*)rexi->data->data[n];
DEBUG_STATE_r( PerlIO_printf(Perl_debug_log,
" re_eval 0x%"UVxf"\n", PTR2UV(PL_op)) );
- PAD_SAVE_LOCAL(old_comppad, (PAD*)rex->data->data[n + 2]);
+ PAD_SAVE_LOCAL(old_comppad, (PAD*)rexi->data->data[n + 2]);
PL_regendp[0] = PL_reg_magic->mg_len = locinput - PL_bostr;
CALLRUNOPS(aTHX); /* Scalar context. */
PL_regsize = osize;
}
}
+ rei = RXi_GET(re);
DEBUG_EXECUTE_r(
debug_start_match(re, do_utf8, locinput, PL_regeol,
"Matching embedded");
);
- startpoint = re->program + 1;
+ startpoint = rei->program + 1;
ST.close_paren = 0; /* only used for GOSUB */
/* borrowed from regtry */
if (PL_reg_start_tmpl <= re->nparens) {
ST.prev_rex = rex;
ST.prev_curlyx = cur_curlyx;
rex = re;
+ rexi = rei;
cur_curlyx = NULL;
ST.B = next;
ST.prev_eval = cur_eval;
PL_reg_flags ^= ST.toggle_reg_flags;
ReREFCNT_dec(rex);
rex = ST.prev_rex;
+ rexi = RXi_GET(rex);
regcpblow(ST.cp);
cur_eval = ST.prev_eval;
cur_curlyx = ST.prev_curlyx;
PL_reg_flags ^= ST.toggle_reg_flags;
ReREFCNT_dec(rex);
rex = ST.prev_rex;
+ rexi = RXi_GET(rex);
PL_reginput = locinput;
REGCP_UNWIND(ST.lastcp);
regcppop(rex);
case CUTGROUP:
PL_reginput = locinput;
sv_yes_mark = st->u.mark.mark_name = scan->flags ? NULL :
- (SV*)rex->data->data[ ARG( scan ) ];
+ (SV*)rexi->data->data[ ARG( scan ) ];
PUSH_STATE_GOTO(CUTGROUP_next,next);
/* NOTREACHED */
case CUTGROUP_next_fail:
PL_reg_flags ^= st->u.eval.toggle_reg_flags;
st->u.eval.prev_rex = rex; /* inner */
- rex = cur_eval->u.eval.prev_rex; /* outer */
+ rex = cur_eval->u.eval.prev_rex; /* outer */
+ rexi = RXi_GET(rex);
cur_curlyx = cur_eval->u.eval.prev_curlyx;
ReREFCNT_inc(rex);
st->u.eval.cp = regcppush(0); /* Save *all* the positions. */
case PRUNE:
PL_reginput = locinput;
if (!scan->flags)
- sv_yes_mark = sv_commit = (SV*)rex->data->data[ ARG( scan ) ];
+ sv_yes_mark = sv_commit = (SV*)rexi->data->data[ ARG( scan ) ];
PUSH_STATE_GOTO(COMMIT_next,next);
/* NOTREACHED */
case COMMIT_next_fail:
case MARKPOINT:
ST.prev_mark = mark_state;
ST.mark_name = sv_commit = sv_yes_mark
- = (SV*)rex->data->data[ ARG( scan ) ];
+ = (SV*)rexi->data->data[ ARG( scan ) ];
mark_state = st;
ST.mark_loc = PL_reginput = locinput;
PUSH_YES_STATE_GOTO(MARKPOINT_next,next);
otherwise do nothing. Meaning we need to scan
*/
regmatch_state *cur = mark_state;
- SV *find = (SV*)rex->data->data[ ARG( scan ) ];
+ SV *find = (SV*)rexi->data->data[ ARG( scan ) ];
while (cur) {
if ( sv_eq( cur->u.mark.mark_name,
SV *sw = NULL;
SV *si = NULL;
SV *alt = NULL;
- const struct reg_data * const data = prog ? prog->data : NULL;
+ RXi_GET_DECL(prog,progi);
+ const struct reg_data * const data = prog ? progi->data : NULL;
if (data && data->count) {
const U32 n = ARG(node);