summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--op.h12
-rw-r--r--perl.c6
-rw-r--r--pp_hot.c11
-rw-r--r--sv.c10
4 files changed, 24 insertions, 15 deletions
diff --git a/op.h b/op.h
index adf5d1f223..2bb042bfa0 100644
--- a/op.h
+++ b/op.h
@@ -329,18 +329,26 @@ struct pmop {
};
#ifdef USE_ITHREADS
-#define PM_GETRE(o) (INT2PTR(REGEXP*,SvIVX(PL_regex_pad[(o)->op_pmoffset])))
+#define PM_GETRE(o) (SvROK(PL_regex_pad[(o)->op_pmoffset]) ? \
+ (REGEXP*)SvRV(PL_regex_pad[(o)->op_pmoffset]) : NULL)
/* The assignment is just to enforce type safety (or at least get a warning).
*/
#define PM_SETRE(o,r) STMT_START { \
const REGEXP *const slosh = (r); \
- PM_SETRE_OFFSET((o), PTR2IV(slosh)); \
+ SV *const whap = PL_regex_pad[(o)->op_pmoffset]; \
+ SvIOK_off(whap); \
+ SvROK_on(whap); \
+ SvRV_set(whap, (SV*)slosh); \
} STMT_END
/* Actually you can assign any IV, not just an offset. And really should it be
UV? */
+/* Need to turn the SvOK off as the regexp code is quite carefully manually
+ reference counting the thing pointed to, so don't want sv_setiv also
+ deciding to clear a reference count because it sees an SV. */
#define PM_SETRE_OFFSET(o,iv) \
STMT_START { \
SV* const sv = PL_regex_pad[(o)->op_pmoffset]; \
+ SvROK_off(sv); \
sv_setiv(sv, (iv)); \
} STMT_END
diff --git a/perl.c b/perl.c
index 72735c274d..e57356bcd1 100644
--- a/perl.c
+++ b/perl.c
@@ -884,13 +884,11 @@ perl_destruct(pTHXx)
* flag is set in regexec.c:S_regtry
*/
SvFLAGS(resv) &= ~SVf_BREAK;
+ /* So stop it pointing to what is now a dead reference. */
+ SvROK_off(resv);
}
else if(SvREPADTMP(resv)) {
SvREPADTMP_off(resv);
- }
- else if(SvIOKp(resv)) {
- REGEXP *re = INT2PTR(REGEXP *,SvIVX(resv));
- ReREFCNT_dec(re);
}
}
}
diff --git a/pp_hot.c b/pp_hot.c
index 7a71b6f79e..d391272f64 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1197,9 +1197,18 @@ PP(pp_qr)
dVAR; dSP;
register PMOP * const pm = cPMOP;
REGEXP * rx = PM_GETRE(pm);
- SV * const pkg = CALLREG_PACKAGE(rx);
+ SV * const pkg = rx ? CALLREG_PACKAGE(rx) : NULL;
SV * const rv = sv_newmortal();
+ if (!rx) {
+ /* FIXME ORANGE.
+ This can go if/when regexps are stored directly in PL_regex_pad
+ rather than via references. do_clean_objs finds and frees them
+ when they are stored as references. */
+ XPUSHs(rv);
+ RETURN;
+ }
+
SvUPGRADE(rv, SVt_IV);
/* This RV is about to own a reference to the regexp. (In addition to the
reference already owned by the PMOP. */
diff --git a/sv.c b/sv.c
index f8e18a9e05..c2b1e1eb35 100644
--- a/sv.c
+++ b/sv.c
@@ -11268,15 +11268,9 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
newSViv(PTR2IV(CALLREGDUPE(
INT2PTR(REGEXP *, SvIVX(regex)), param))))
*/
- /* And while we're at it, can we FIXME on the whole hiding
- pointer inside an IV hack? */
- SV * const sv =
- SvREPADTMP(regex)
- ? sv_dup_inc((SV*) regex, param)
- : newSViv(PTR2IV(sv_dup_inc(INT2PTR(SV *, SvIVX(regex)), param)))
- ;
+ SV * const sv = sv_dup_inc((SV*) regex, param);
if (SvFLAGS(regex) & SVf_BREAK)
- SvFLAGS(sv) |= SVf_BREAK; /* unrefcnted PL_curpm */
+ assert(SvFLAGS(sv) & SVf_BREAK); /* unrefcnted PL_curpm */
av_push(PL_regex_padav, sv);
}
}