{
stack_sp = sp;
av_extend(stack, (p - stack_base) + (n) + 128);
-#ifdef NOTDEF
- stack_sp = AvARRAY(stack) + (sp - stack_base);
- stack_base = AvARRAY(stack);
- stack_max = stack_base + AvMAX(stack) - 1;
-#endif
return stack_sp;
}
if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) {
sv_upgrade(sv, SvTYPE(osv));
if (SvGMAGICAL(osv)) {
+ MAGIC* mg;
+ bool oldtainted = tainted;
mg_get(osv);
+ if (tainting && tainted && (mg = mg_find(osv, 't'))) {
+ SAVESPTR(mg->mg_obj);
+ mg->mg_obj = osv;
+ }
SvFLAGS(osv) |= (SvFLAGS(osv) &
(SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
+ tainted = oldtainted;
}
SvMAGIC(sv) = SvMAGIC(osv);
SvFLAGS(sv) |= SvMAGICAL(osv);
- localizing = TRUE;
+ localizing = 1;
SvSETMAGIC(sv);
- localizing = FALSE;
+ localizing = 0;
}
return sv;
}
GP *ogp = GvGP(gv);
SSCHECK(3);
- SSPUSHPTR(gv);
+ SSPUSHPTR(SvREFCNT_inc(gv));
SSPUSHPTR(ogp);
SSPUSHINT(SAVEt_GP);
if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) {
sv_upgrade(sv, SvTYPE(osv));
if (SvGMAGICAL(osv)) {
+ MAGIC* mg;
+ bool oldtainted = tainted;
mg_get(osv);
+ if (tainting && tainted && (mg = mg_find(osv, 't'))) {
+ SAVESPTR(mg->mg_obj);
+ mg->mg_obj = osv;
+ }
SvFLAGS(osv) |= (SvFLAGS(osv) &
(SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
+ tainted = oldtainted;
}
SvMAGIC(sv) = SvMAGIC(osv);
SvFLAGS(sv) |= SvMAGICAL(osv);
- localizing = TRUE;
+ localizing = 1;
SvSETMAGIC(sv);
- localizing = FALSE;
+ localizing = 0;
}
return sv;
}
IV *ivp;
{
SSCHECK(3);
- SSPUSHINT(*ivp);
+ SSPUSHIV(*ivp);
SSPUSHPTR(ivp);
SSPUSHINT(SAVEt_IV);
}
SV** svp;
{
SSCHECK(2);
- SSPUSHPTR(svp);
+ SSPUSHLONG((long)(svp-curpad));
SSPUSHINT(SAVEt_CLEARSV);
}
value = (SV*)SSPOPPTR;
sv = (SV*)SSPOPPTR;
sv_replace(sv,value);
- localizing = TRUE;
+ localizing = 2;
SvSETMAGIC(sv);
- localizing = FALSE;
+ localizing = 0;
break;
case SAVEt_SV: /* scalar reference */
value = (SV*)SSPOPPTR;
gv = (GV*)SSPOPPTR;
sv = GvSV(gv);
- if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv) && SvTYPE(sv) != SVt_PVGV){
+ if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv) &&
+ SvTYPE(sv) != SVt_PVGV)
+ {
(void)SvUPGRADE(value, SvTYPE(sv));
SvMAGIC(value) = SvMAGIC(sv);
SvFLAGS(value) |= SvMAGICAL(sv);
}
SvREFCNT_dec(sv);
GvSV(gv) = value;
- localizing = TRUE;
+ localizing = 2;
SvSETMAGIC(value);
- localizing = FALSE;
+ localizing = 0;
break;
case SAVEt_SVREF: /* scalar reference */
ptr = SSPOPPTR;
sv = *(SV**)ptr;
value = (SV*)SSPOPPTR;
- if (SvTYPE(sv) >= SVt_PVMG && SvTYPE(sv) != SVt_PVGV) {
+ if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv) &&
+ SvTYPE(sv) != SVt_PVGV)
+ {
(void)SvUPGRADE(value, SvTYPE(sv));
SvMAGIC(value) = SvMAGIC(sv);
SvFLAGS(value) |= SvMAGICAL(sv);
}
SvREFCNT_dec(sv);
*(SV**)ptr = value;
- localizing = TRUE;
+ localizing = 2;
SvSETMAGIC(value);
- localizing = FALSE;
+ localizing = 0;
break;
case SAVEt_AV: /* array reference */
av = (AV*)SSPOPPTR;
gv = (GV*)SSPOPPTR;
gp_free(gv);
GvGP(gv) = (GP*)ptr;
+ SvREFCNT_dec(gv);
break;
case SAVEt_FREESV:
ptr = SSPOPPTR;
Safefree((char*)ptr);
break;
case SAVEt_CLEARSV:
- ptr = SSPOPPTR;
+ ptr = (void*)&curpad[SSPOPLONG];
sv = *(SV**)ptr;
if (SvREFCNT(sv) <= 1) { /* Can clear pad variable in place. */
if (SvTHINKFIRST(sv)) {
}
}
else { /* Someone has a claim on this, so abandon it. */
+ U32 padflags = SvFLAGS(sv) & (SVs_PADBUSY|SVs_PADMY|SVs_PADTMP);
SvREFCNT_dec(sv); /* Cast current value to the winds. */
switch (SvTYPE(sv)) { /* Console ourselves with a new value */
case SVt_PVAV: *(SV**)ptr = (SV*)newAV(); break;
case SVt_PVHV: *(SV**)ptr = (SV*)newHV(); break;
default: *(SV**)ptr = NEWSV(0,0); break;
}
+ SvFLAGS(*(SV**)ptr) |= padflags; /* preserve pad nature */
}
break;
case SAVEt_DELETE:
ptr = SSPOPPTR;
hv = (HV*)ptr;
ptr = SSPOPPTR;
- hv_delete(hv, (char*)ptr, (U32)SSPOPINT);
+ (void)hv_delete(hv, (char*)ptr, (U32)SSPOPINT, G_DISCARD);
+ Safefree(ptr);
break;
case SAVEt_DESTRUCTOR:
ptr = SSPOPPTR;
(*SSPOPDPTR)(ptr);
break;
case SAVEt_REGCONTEXT:
- savestack_ix -= SSPOPINT; /* regexp must have croaked */
+ {
+ I32 delta = SSPOPINT;
+ savestack_ix -= delta; /* regexp must have croaked */
+ }
break;
default:
croak("panic: leave_scope inconsistency");