(sv = names[PL_padix]) && sv != &PL_sv_undef)
continue;
sv = *av_fetch(PL_comppad, PL_padix, TRUE);
- if (!(SvFLAGS(sv) & (SVs_PADTMP|SVs_PADMY)))
+ if (!(SvFLAGS(sv) & (SVs_PADTMP|SVs_PADMY)) && !IS_PADGV(sv))
break;
}
retval = PL_padix;
case OP_AELEMFAST:
#ifdef USE_ITHREADS
if (PL_curpad) {
- SvREFCNT_dec(cGVOPo);
- PL_curpad[cPADOPo->op_padix] = Nullsv;
+ 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);
}
- pad_free(cPADOPo->op_padix);
cPADOPo->op_padix = 0;
#else
SvREFCNT_dec(cGVOPo);
break;
}
- if (o->op_targ > 0)
+ if (o->op_targ > 0) {
pad_free(o->op_targ);
+ o->op_targ = 0;
+ }
}
STATIC void
{
dTHR;
#ifdef USE_ITHREADS
+ GvIN_PAD_on(gv);
return newPADOP(type, flags, SvREFCNT_inc(gv));
#else
return newSVOP(type, flags, SvREFCNT_inc(gv));
{
tmpop = ((UNOP*)left)->op_first;
if (tmpop->op_type == OP_GV && !pm->op_pmreplroot) {
- pm->op_pmreplroot = (OP*)((SVOP*)tmpop)->op_sv; /* XXXXXX */
+ pm->op_pmreplroot = (OP*)cGVOPx(tmpop);
pm->op_pmflags |= PMf_ONCE;
tmpop = cUNOPo->op_first; /* to list (nulled) */
tmpop = ((UNOP*)tmpop)->op_first; /* to pushmark */
}
else if (sv->op_type == OP_PADSV) { /* private variable */
padoff = sv->op_targ;
+ sv->op_targ = 0;
op_free(sv);
sv = Nullop;
}
else if (sv->op_type == OP_THREADSV) { /* per-thread variable */
padoff = sv->op_targ;
+ sv->op_targ = 0;
iterflags |= OPf_SPECIAL;
op_free(sv);
sv = Nullop;
}
}
-#ifdef DEBUG_CLOSURES
+#ifdef DEBUGGING
STATIC void
-cv_dump(CV *cv)
+S_cv_dump(pTHX_ CV *cv)
{
CV *outside = CvOUTSIDE(cv);
AV* padlist = CvPADLIST(cv);
SvIVX(pname[ix]));
}
}
-#endif /* DEBUG_CLOSURES */
+#endif /* DEBUGGING */
STATIC CV *
S_cv_clone2(pTHX_ CV *proto, CV *outside)
PL_curpad[ix] = sv;
}
}
+ else if (IS_PADGV(ppad[ix])) {
+ PL_curpad[ix] = SvREFCNT_inc(ppad[ix]);
+ }
else {
SV* sv = NEWSV(0,0);
SvPADTMP_on(sv);
for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
SV *namesv;
- if (SvIMMORTAL(PL_curpad[ix]))
+ if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]))
continue;
/*
* The only things that a clonable function needs in its
AvFLAGS(av) = AVf_REIFY;
for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
- if (SvIMMORTAL(PL_curpad[ix]))
+ if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]))
continue;
if (!SvPADMY(PL_curpad[ix]))
SvPADTMP_on(PL_curpad[ix]);
#ifdef USE_ITHREADS
/* XXXXXX hack: dependence on sizeof(PADOP) <= sizeof(SVOP) */
kPADOP->op_padix = pad_alloc(OP_GV, SVs_PADTMP);
+ GvIN_PAD_on(gv);
PL_curpad[kPADOP->op_padix] = SvREFCNT_inc(gv);
#else
kid->op_sv = SvREFCNT_inc(gv);
return o;
}
kid->op_targ = kkid->op_targ;
+ kkid->op_targ = 0;
/* Now we do not need PADSV and SASSIGN. */
kid->op_sibling = o->op_sibling; /* NULL */
cLISTOPo->op_first = NULL;
&& (((LISTOP*)o)->op_first->op_sibling->op_type
== OP_PADSV)
&& (((LISTOP*)o)->op_first->op_sibling->op_targ
- == o->op_next->op_targ))) {
+ == o->op_next->op_targ)))
+ {
goto ignore_optimization;
}
else {
o->op_targ = o->op_next->op_targ;
+ o->op_next->op_targ = 0;
o->op_private |= OPpTARGET_MY;
}
}
# define cGVOP_set(v) (PL_curpad[cPADOP->op_padix] = (SV*)(v))
# define cGVOPo_set(v) (PL_curpad[cPADOPo->op_padix] = (SV*)(v))
# define kGVOP_set(v) (PL_curpad[kPADOP->op_padix] = (SV*)(v))
+# define IS_PADGV(v) (v && SvTYPE(v) == SVt_PVGV && GvIN_PAD(v))
#else
# define cGVOPx(o) ((GV*)cSVOPx(o)->op_sv)
# define cGVOP ((GV*)cSVOP->op_sv)
# define cGVOP_set(v) (cPADOP->op_sv = (SV*)(v))
# define cGVOPo_set(v) (cPADOPo->op_sv = (SV*)(v))
# define kGVOP_set(v) (kPADOP->op_sv = (SV*)(v))
+# define IS_PADGV(v) FALSE
#endif
#define Nullop Null(OP*)