osv = *sptr;
sv = (flags & SAVEf_KEEPOLDELEM) ? osv : (*sptr = newSV(0));
- if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) {
+ if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv)) {
if (SvGMAGICAL(osv)) {
SvFLAGS(osv) |= (SvFLAGS(osv) &
(SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
dVAR;
COPHH *save_cophh = cophh_copy(CopHINTHASH_get(&PL_compiling));
if (PL_hints & HINT_LOCALIZE_HH) {
- save_pushptri32ptr(GvHV(PL_hintgv), PL_hints, save_cophh, SAVEt_HINTS);
- GvHV(PL_hintgv) = hv_copy_hints_hv(GvHV(PL_hintgv));
+ HV *oldhh = GvHV(PL_hintgv);
+ save_pushptri32ptr(oldhh, PL_hints, save_cophh, SAVEt_HINTS);
+ GvHV(PL_hintgv) = NULL; /* in case copying dies */
+ GvHV(PL_hintgv) = hv_copy_hints_hv(oldhh);
} else {
save_pushi32ptr(PL_hints, save_cophh, SAVEt_HINTS);
}
register char* str;
I32 i;
/* Localise the effects of the TAINT_NOT inside the loop. */
- const bool was = PL_tainted;
+ bool was = PL_tainted;
if (base < -1)
- Perl_croak(aTHX_ "panic: corrupt saved stack index");
+ Perl_croak(aTHX_ "panic: corrupt saved stack index %ld", (long) base);
DEBUG_l(Perl_deb(aTHX_ "savestack: releasing items %ld -> %ld\n",
(long)PL_savestack_ix, (long)base));
while (PL_savestack_ix > base) {
case SAVEt_BOOL: /* bool reference */
ptr = SSPOPPTR;
*(bool*)ptr = cBOOL(uv >> 8);
+
+ if (ptr == &PL_tainted) {
+ /* If we don't update <was>, to reflect what was saved on the
+ * stack for PL_tainted, then we will overwrite this attempt to
+ * restore it when we exit this routine. Note that this won't
+ * work if this value was saved in a wider-than necessary type,
+ * such as I32 */
+ was = *(bool*)ptr;
+ }
break;
case SAVEt_I32_SMALL:
ptr = SSPOPPTR;
if (SvTHINKFIRST(sv))
sv_force_normal_flags(sv, SV_IMMEDIATE_UNREF);
+ if (SvTYPE(sv) == SVt_PVHV)
+ Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
if (SvMAGICAL(sv))
+ sv_unmagic(sv, PERL_MAGIC_backref),
mg_free(sv);
switch (SvTYPE(sv)) {
SvPADSTALE_on(sv); /* mark as no longer live */
}
else { /* Someone has a claim on this, so abandon it. */
- const U32 padflags = SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP);
+ assert( SvFLAGS(sv) & SVs_PADMY);
+ assert(!(SvFLAGS(sv) & SVs_PADTMP));
switch (SvTYPE(sv)) { /* Console ourselves with a new value */
case SVt_PVAV: *(SV**)ptr = MUTABLE_SV(newAV()); break;
case SVt_PVHV: *(SV**)ptr = MUTABLE_SV(newHV()); break;
SvREFCNT_dec(sv); /* Cast current value to the winds. */
/* preserve pad nature, but also mark as not live
* for any closure capturing */
- SvFLAGS(*(SV**)ptr) |= padflags | SVs_PADSTALE;
+ SvFLAGS(*(SV**)ptr) |= (SVs_PADMY|SVs_PADSTALE);
}
break;
case SAVEt_DELETE:
PL_op = (OP*)SSPOPPTR;
break;
case SAVEt_HINTS:
- if ((PL_hints & HINT_LOCALIZE_HH) && GvHV(PL_hintgv)) {
- SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv)));
+ if ((PL_hints & HINT_LOCALIZE_HH)) {
+ while (GvHV(PL_hintgv)) {
+ HV *hv = GvHV(PL_hintgv);
GvHV(PL_hintgv) = NULL;
+ SvREFCNT_dec(MUTABLE_SV(hv));
+ }
}
cophh_free(CopHINTHASH_get(&PL_compiling));
CopHINTHASH_set(&PL_compiling, (COPHH*)SSPOPPTR);
if (PL_hints & HINT_LOCALIZE_HH) {
SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv)));
GvHV(PL_hintgv) = MUTABLE_HV(SSPOPPTR);
- assert(GvHV(PL_hintgv));
- } else if (!GvHV(PL_hintgv)) {
- /* Need to add a new one manually, else gv_fetchpv() can
- add one in this code:
-
- if (SvTYPE(gv) == SVt_PVGV) {
- if (add) {
- GvMULTI_on(gv);
- gv_init_sv(gv, sv_type);
- if (*name=='!' && sv_type == SVt_PVHV && len==1)
- require_errno(gv);
- }
- return gv;
- }
-
- and it won't have the magic set. */
-
+ }
+ if (!GvHV(PL_hintgv)) {
+ /* Need to add a new one manually, else rv2hv can
+ add one via GvHVn and it won't have the magic set. */
HV *const hv = newHV();
hv_magic(hv, NULL, PERL_MAGIC_hints);
GvHV(PL_hintgv) = hv;
- SAVESTACK_ALLOC_FOR_RE_SAVE_STATE);
PL_savestack_ix -= SAVESTACK_ALLOC_FOR_RE_SAVE_STATE;
- if (PL_reg_start_tmp != state->re_state_reg_start_tmp) {
- Safefree(PL_reg_start_tmp);
- }
if (PL_reg_poscache != state->re_state_reg_poscache) {
Safefree(PL_reg_poscache);
}
parser_free((yy_parser *) ptr);
break;
default:
- Perl_croak(aTHX_ "panic: leave_scope inconsistency");
+ Perl_croak(aTHX_ "panic: leave_scope inconsistency %u", type);
}
}
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
- * indent-tabs-mode: t
+ * indent-tabs-mode: nil
* End:
*
- * ex: set ts=8 sts=4 sw=4 noet:
+ * ex: set ts=8 sts=4 sw=4 et:
*/