#define RF_warned 2 /* warned about big count? */
#define RF_evaled 4 /* Did an EVAL with setting? */
#define RF_utf8 8 /* String contains multibyte chars? */
-#define RF_false 16 /* odd number of nested negatives */
#define UTF ((PL_reg_flags & RF_utf8) != 0)
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(). */
- U8* str = (U8*)STRING(prog->regstclass);
- int cl_l = (PL_regkind[(U8)OP(prog->regstclass)] == EXACT
+ const U8* str = (U8*)STRING(prog->regstclass);
+ const int cl_l = (PL_regkind[(U8)OP(prog->regstclass)] == EXACT
? CHR_DIST(str+STR_LEN(prog->regstclass), str)
: 1);
char *endpos = (prog->anchored_substr || prog->anchored_utf8 || ml_anch)
? HOP3c(HOP3c(check_at, -start_shift, strbeg),
cl_l, strend)
: strend);
- char *startpos = strbeg;
t = s;
cache_re(prog);
- s = find_byclass(prog, prog->regstclass, s, endpos, startpos, 1);
+ s = find_byclass(prog, prog->regstclass, s, endpos, 1);
if (!s) {
#ifdef DEBUGGING
- char *what = 0;
+ const char *what = 0;
#endif
if (endpos == strend) {
DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
/* We know what class REx starts with. Try to find this position... */
STATIC char *
-S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *startpos, I32 norun)
+S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, I32 norun)
{
I32 doevery = (prog->reganch & ROPT_SKIP) == 0;
char *m;
len0, len0, s0,
len1, len1, s1);
});
- if (find_byclass(prog, c, s, strend, startpos, 0))
+ if (find_byclass(prog, c, s, strend, 0))
goto got_it;
DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Contradicts stclass...\n"));
}
}
else {
STRLEN len;
- char *little = SvPV(float_real, len);
+ const char * const little = SvPV(float_real, len);
if (SvTAIL(float_real)) {
if (memEQ(strend - len + 1, little, len - 1))
#define sayNO_SILENT goto do_no
#define saySAME(x) if (x) goto yes; else goto no
+#define POSCACHE_SUCCESS 0 /* caching success rather than failure */
+#define POSCACHE_SEEN 1 /* we know what we're caching */
+#define POSCACHE_START 2 /* the real cache: this bit maps to pos 0 */
+#define CACHEsayYES STMT_START { \
+ if (cache_offset | cache_bit) { \
+ if (!(PL_reg_poscache[0] & (1<<POSCACHE_SEEN))) \
+ PL_reg_poscache[0] |= (1<<POSCACHE_SUCCESS) || (1<<POSCACHE_SEEN); \
+ else if (!(PL_reg_poscache[0] & (1<<POSCACHE_SUCCESS))) { \
+ /* cache records failure, but this is success */ \
+ DEBUG_r( \
+ PerlIO_printf(Perl_debug_log, \
+ "%*s (remove success from failure cache)\n", \
+ REPORT_CODE_OFF+PL_regindent*2, "") \
+ ); \
+ PL_reg_poscache[cache_offset] &= ~(1<<cache_bit); \
+ } \
+ } \
+ sayYES; \
+} STMT_END
+#define CACHEsayNO STMT_START { \
+ if (cache_offset | cache_bit) { \
+ if (!(PL_reg_poscache[0] & (1<<POSCACHE_SEEN))) \
+ PL_reg_poscache[0] |= (1<<POSCACHE_SEEN); \
+ else if ((PL_reg_poscache[0] & (1<<POSCACHE_SUCCESS))) { \
+ /* cache records success, but this is failure */ \
+ DEBUG_r( \
+ PerlIO_printf(Perl_debug_log, \
+ "%*s (remove failure from success cache)\n", \
+ REPORT_CODE_OFF+PL_regindent*2, "") \
+ ); \
+ PL_reg_poscache[cache_offset] &= ~(1<<cache_bit); \
+ } \
+ } \
+ sayNO; \
+} STMT_END
+
/* this is used to determine how far from the left messages like
'failed...' are printed. Currently 29 makes these messages line
up with the opcode they refer to. Earlier perls used 25 which
I32 unwind = 0;
/* used by the trie code */
- SV *sv_accept_buff; /* accepting states we have traversed */
- reg_trie_accepted *accept_buff; /* "" */
- reg_trie_data *trie; /* what trie are we using right now */
- U32 accepted = 0; /* how many accepting states we have seen*/
+ SV *sv_accept_buff = 0; /* accepting states we have traversed */
+ reg_trie_accepted *accept_buff = 0; /* "" */
+ reg_trie_data *trie; /* what trie are we using right now */
+ U32 accepted = 0; /* how many accepting states we have seen*/
#if 0
I32 firstcp = PL_savestack_ix;
SV *dsv1 = PERL_DEBUG_PAD_ZERO(1);
SV *dsv2 = PERL_DEBUG_PAD_ZERO(2);
- SV *re_debug_flags;
+ SV *re_debug_flags = NULL;
#endif
GET_RE_DEBUG_FLAGS;
CHECKPOINT cp, lastcp;
CURCUR* cc = PL_regcc;
char *lastloc = cc->lastloc; /* Detection of 0-len. */
+ I32 cache_offset = 0, cache_bit = 0;
n = cc->cur + 1; /* how many we know we matched */
PL_reginput = locinput;
PL_reg_leftiter = PL_reg_maxiter;
}
if (PL_reg_leftiter-- == 0) {
- I32 size = (PL_reg_maxiter + 7)/8;
+ I32 size = (PL_reg_maxiter + 7 + POSCACHE_START)/8;
if (PL_reg_poscache) {
if ((I32)PL_reg_poscache_size < size) {
Renew(PL_reg_poscache, size, char);
);
}
if (PL_reg_leftiter < 0) {
- I32 o = locinput - PL_bostr, b;
+ cache_offset = locinput - PL_bostr;
- o = (scan->flags & 0xf) - 1 + o * (scan->flags>>4);
- b = o % 8;
- o /= 8;
- if (PL_reg_poscache[o] & (1<<b)) {
+ cache_offset = (scan->flags & 0xf) - 1 + POSCACHE_START
+ + cache_offset * (scan->flags>>4);
+ cache_bit = cache_offset % 8;
+ cache_offset /= 8;
+ if (PL_reg_poscache[cache_offset] & (1<<cache_bit)) {
DEBUG_EXECUTE_r(
PerlIO_printf(Perl_debug_log,
"%*s already tried at this position...\n",
REPORT_CODE_OFF+PL_regindent*2, "")
);
- if (PL_reg_flags & RF_false)
+ if (PL_reg_poscache[0] & (1<<POSCACHE_SUCCESS))
+ /* cache records success */
sayYES;
else
+ /* cache records failure */
sayNO_SILENT;
}
- PL_reg_poscache[o] |= (1<<b);
+ PL_reg_poscache[cache_offset] |= (1<<cache_bit);
}
}
REGCP_SET(lastcp);
if (regmatch(cc->next)) {
regcpblow(cp);
- sayYES; /* All done. */
+ CACHEsayYES; /* All done. */
}
REGCP_UNWIND(lastcp);
regcppop();
"Complex regular subexpression recursion",
REG_INFTY - 1);
}
- sayNO;
+ CACHEsayNO;
}
DEBUG_EXECUTE_r(
REGCP_SET(lastcp);
if (regmatch(cc->scan)) {
regcpblow(cp);
- sayYES;
+ CACHEsayYES;
}
REGCP_UNWIND(lastcp);
regcppop();
cc->cur = n - 1;
cc->lastloc = lastloc;
- sayNO;
+ CACHEsayNO;
}
/* Prefer scan over next for maximal matching. */
REGCP_SET(lastcp);
if (regmatch(cc->scan)) {
regcpblow(cp);
- sayYES;
+ CACHEsayYES;
}
REGCP_UNWIND(lastcp);
regcppop(); /* Restore some previous $<digit>s? */
if (PL_regcc)
ln = PL_regcc->cur;
if (regmatch(cc->next))
- sayYES;
+ CACHEsayYES;
if (PL_regcc)
PL_regcc->cur = ln;
PL_regcc = cc;
cc->cur = n - 1;
cc->lastloc = lastloc;
- sayNO;
+ CACHEsayNO;
}
/* NOT REACHED */
case BRANCHJ:
}
else
PL_reginput = locinput;
- PL_reg_flags ^= RF_false;
goto do_ifmatch;
case IFMATCH:
n = 1;
do_ifmatch:
inner = NEXTOPER(NEXTOPER(scan));
if (regmatch(inner) != n) {
- if (n == 0)
- PL_reg_flags ^= RF_false;
say_no:
if (logical) {
logical = 0;
else
sayNO;
}
- if (n == 0)
- PL_reg_flags ^= RF_false;
say_yes:
if (logical) {
logical = 0;
PL_reginput = scan;
DEBUG_r({
- SV *re_debug_flags;
+ SV *re_debug_flags = NULL;
SV *prop = sv_newmortal();
GET_RE_DEBUG_FLAGS;
DEBUG_EXECUTE_r({
static void
restore_pos(pTHX_ void *arg)
{
+ (void)arg; /* unused */
if (PL_reg_eval_set) {
if (PL_reg_oldsaved) {
PL_reg_re->subbeg = PL_reg_oldsaved;