#define OP_REFCNT_LOCK NOOP
#define OP_REFCNT_UNLOCK NOOP
#define OpREFCNT_set(o,n) NOOP
-#define OpREFCNT_dec(o) 0
+#define OpREFCNT_dec(o) ((o)->op_targ--)
#ifdef PL_OP_SLAB_ALLOC
#define SLAB_SIZE 8192
OP_REFCNT_UNLOCK;
return;
}
+ o->op_targ = 0; /* XXXXXX */
OP_REFCNT_UNLOCK;
break;
default:
case OP_GV:
case OP_AELEMFAST:
#ifdef USE_ITHREADS
- if (PL_curpad) {
- GV *gv = cGVOPo;
- pad_swipe(cPADOPo->op_padix);
- /* No GvIN_PAD_off(gv) here, because other references may still
- * exist on the pad */
- SvREFCNT_dec(gv);
- }
- cPADOPo->op_padix = 0;
+ if (cPADOPo->op_padix > 0) {
+ if (PL_curpad) {
+ GV *gv = cGVOPo;
+ pad_swipe(cPADOPo->op_padix);
+ /* No GvIN_PAD_off(gv) here, because other references may still
+ * exist on the pad */
+ SvREFCNT_dec(gv);
+ }
+ cPADOPo->op_padix = 0;
+ }
#else
- SvREFCNT_dec(cGVOPo);
+ SvREFCNT_dec(cSVOPo->op_sv);
cSVOPo->op_sv = Nullsv;
#endif
break;
break;
case OP_SUBST:
op_free(cPMOPo->op_pmreplroot);
- cPMOPo->op_pmreplroot = Nullop;
- /* FALL THROUGH */
+ goto clear_pmop;
case OP_PUSHRE:
+#ifdef USE_ITHREADS
+ if ((PADOFFSET)cPMOPo->op_pmreplroot) {
+ if (PL_curpad) {
+ GV *gv = (GV*)PL_curpad[(PADOFFSET)cPMOPo->op_pmreplroot];
+ pad_swipe((PADOFFSET)cPMOPo->op_pmreplroot);
+ /* No GvIN_PAD_off(gv) here, because other references may still
+ * exist on the pad */
+ SvREFCNT_dec(gv);
+ }
+ }
+#else
+ SvREFCNT_dec((SV*)cPMOPo->op_pmreplroot);
+#endif
+ /* FALL THROUGH */
case OP_MATCH:
case OP_QR:
+clear_pmop:
+ cPMOPo->op_pmreplroot = Nullop;
ReREFCNT_dec(cPMOPo->op_pmregexp);
cPMOPo->op_pmregexp = (REGEXP*)NULL;
break;
{
tmpop = ((UNOP*)left)->op_first;
if (tmpop->op_type == OP_GV && !pm->op_pmreplroot) {
- pm->op_pmreplroot = (OP*)cGVOPx(tmpop);
+#ifdef USE_ITHREADS
+ pm->op_pmreplroot = (OP*)cPADOPx(tmpop)->op_padix;
+ cPADOPx(tmpop)->op_padix = 0; /* steal it */
+#else
+ pm->op_pmreplroot = (OP*)cSVOPx(tmpop)->op_sv;
+ cSVOPx(tmpop)->op_sv = Nullsv; /* steal it */
+#endif
pm->op_pmflags |= PMf_ONCE;
tmpop = cUNOPo->op_first; /* to list (nulled) */
tmpop = ((UNOP*)tmpop)->op_first; /* to pushmark */
if (svp && *svp != &PL_sv_undef && !SvIOK(*svp)) {
(void)SvIOK_on(*svp);
SvIVX(*svp) = 1;
+#ifndef USE_ITHREADS
+ /* XXX This nameless kludge interferes with cloning SVs. :-(
+ * What's more, it seems entirely redundant when considering
+ * PL_DBsingle exists to do the same thing */
SvSTASH(*svp) = (HV*)cop;
+#endif
}
}
}
}
-#ifdef DEBUGGING
STATIC void
S_cv_dump(pTHX_ CV *cv)
{
+#ifdef DEBUGGING
CV *outside = CvOUTSIDE(cv);
AV* padlist = CvPADLIST(cv);
AV* pad_name;
(IV)I_32(SvNVX(pname[ix])),
SvIVX(pname[ix]));
}
-}
#endif /* DEBUGGING */
+}
STATIC CV *
S_cv_clone2(pTHX_ CV *proto, CV *outside)
CV *cv;
HV *hv;
- Perl_sv_setpvf(aTHX_ sv, "%_:%ld-%ld",
- CopFILESV(PL_curcop),
+ Perl_sv_setpvf(aTHX_ sv, "%s:%ld-%ld",
+ CopFILE(PL_curcop),
(long)PL_subline, (long)CopLINE(PL_curcop));
gv_efullname3(tmpstr, gv, Nullch);
hv_store(GvHV(PL_DBsub), SvPVX(tmpstr), SvCUR(tmpstr), sv, 0);
s++;
else
s = name;
+
+ if (*s != 'B' && *s != 'E' && *s != 'S' && *s != 'I')
+ goto done;
+
if (strEQ(s, "BEGIN")) {
I32 oldscope = PL_scopestack_ix;
ENTER;
if (!PL_beginav)
PL_beginav = newAV();
DEBUG_x( dump_sub(gv) );
- av_push(PL_beginav, (SV *)cv);
+ av_push(PL_beginav, SvREFCNT_inc(cv));
GvCV(gv) = 0;
call_list(oldscope, PL_beginav);
else if (strEQ(s, "END") && !PL_error_count) {
if (!PL_endav)
PL_endav = newAV();
+ DEBUG_x( dump_sub(gv) );
av_unshift(PL_endav, 1);
- av_store(PL_endav, 0, (SV *)cv);
+ av_store(PL_endav, 0, SvREFCNT_inc(cv));
GvCV(gv) = 0;
}
else if (strEQ(s, "STOP") && !PL_error_count) {
if (!PL_stopav)
PL_stopav = newAV();
+ DEBUG_x( dump_sub(gv) );
av_unshift(PL_stopav, 1);
- av_store(PL_stopav, 0, (SV *)cv);
+ av_store(PL_stopav, 0, SvREFCNT_inc(cv));
GvCV(gv) = 0;
}
else if (strEQ(s, "INIT") && !PL_error_count) {
if (!PL_initav)
PL_initav = newAV();
+ DEBUG_x( dump_sub(gv) );
av_push(PL_initav, SvREFCNT_inc(cv));
GvCV(gv) = 0;
}
s++;
else
s = name;
+
+ if (*s != 'B' && *s != 'E' && *s != 'S' && *s != 'I')
+ goto done;
+
if (strEQ(s, "BEGIN")) {
if (!PL_beginav)
PL_beginav = newAV();
- av_push(PL_beginav, (SV *)cv);
+ av_push(PL_beginav, SvREFCNT_inc(cv));
GvCV(gv) = 0;
}
else if (strEQ(s, "END")) {
if (!PL_endav)
PL_endav = newAV();
av_unshift(PL_endav, 1);
- av_store(PL_endav, 0, (SV *)cv);
+ av_store(PL_endav, 0, SvREFCNT_inc(cv));
GvCV(gv) = 0;
}
else if (strEQ(s, "STOP")) {
if (!PL_stopav)
PL_stopav = newAV();
av_unshift(PL_stopav, 1);
- av_store(PL_stopav, 0, (SV *)cv);
+ av_store(PL_stopav, 0, SvREFCNT_inc(cv));
GvCV(gv) = 0;
}
else if (strEQ(s, "INIT")) {
if (!PL_initav)
PL_initav = newAV();
- av_push(PL_initav, (SV *)cv);
+ av_push(PL_initav, SvREFCNT_inc(cv));
GvCV(gv) = 0;
}
}
else
CvANON_on(cv);
+done:
return cv;
}