X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/d57ce4dfca04719829a488a820a1248efb7e81a7..a30585c71699142f26d0acd91456fddcae948304:/scope.c?ds=sidebyside diff --git a/scope.c b/scope.c index 93ef4b3..2a9b3d5 100644 --- a/scope.c +++ b/scope.c @@ -181,15 +181,13 @@ S_save_scalar_at(pTHX_ SV **sptr, const U32 flags) 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)) { - const bool oldtainted = PL_tainted; SvFLAGS(osv) |= (SvFLAGS(osv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT; - PL_tainted = oldtainted; } if (!(flags & SAVEf_KEEPOLDELEM)) - mg_localize(osv, sv, (flags & SAVEf_SETMAGIC) != 0); + mg_localize(osv, sv, cBOOL(flags & SAVEf_SETMAGIC)); } return sv; @@ -281,15 +279,7 @@ Perl_save_gp(pTHX_ GV *gv, I32 empty) PERL_ARGS_ASSERT_SAVE_GP; - SSCHECK(4); - SSPUSHINT(SvFAKE(gv)); - SSPUSHPTR(GvGP(gv)); - SSPUSHPTR(SvREFCNT_inc(gv)); - SSPUSHUV(SAVEt_GP); - - /* Don't let the localized GV coerce into non-glob, otherwise we would - * not be able to restore GP upon leave from context if that happened */ - SvFAKE_off(gv); + save_pushptrptr(SvREFCNT_inc(gv), GvGP(gv), SAVEt_GP); if (empty) { GP *gp = Perl_newGP(aTHX_ gv); @@ -308,7 +298,7 @@ Perl_save_gp(pTHX_ GV *gv, I32 empty) gp->gp_sv = newSV(0); } #endif - GvGP(gv) = gp; + GvGP_set(gv,gp); } else { gp_ref(GvGP(gv)); @@ -327,7 +317,7 @@ Perl_save_ary(pTHX_ GV *gv) if (!AvREAL(oav) && AvREIFY(oav)) av_reify(oav); - save_pushptrptr(gv, oav, SAVEt_AV); + save_pushptrptr(SvREFCNT_inc_simple_NN(gv), oav, SAVEt_AV); GvAV(gv) = NULL; av = GvAVn(gv); @@ -344,7 +334,9 @@ Perl_save_hash(pTHX_ GV *gv) PERL_ARGS_ASSERT_SAVE_HASH; - save_pushptrptr(gv, (ohv = GvHVn(gv)), SAVEt_HV); + save_pushptrptr( + SvREFCNT_inc_simple_NN(gv), (ohv = GvHVn(gv)), SAVEt_HV + ); GvHV(gv) = NULL; hv = GvHVn(gv); @@ -600,17 +592,14 @@ void Perl_save_hints(pTHX) { dVAR; - if (PL_compiling.cop_hints_hash) { - HINTS_REFCNT_LOCK; - PL_compiling.cop_hints_hash->refcounted_he_refcnt++; - HINTS_REFCNT_UNLOCK; - } + COPHH *save_cophh = cophh_copy(CopHINTHASH_get(&PL_compiling)); if (PL_hints & HINT_LOCALIZE_HH) { - save_pushptri32ptr(GvHV(PL_hintgv), PL_hints, - PL_compiling.cop_hints_hash, SAVEt_HINTS); - GvHV(PL_hintgv) = Perl_hv_copy_hints_hv(aTHX_ 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, PL_compiling.cop_hints_hash, SAVEt_HINTS); + save_pushi32ptr(PL_hints, save_cophh, SAVEt_HINTS); } } @@ -722,10 +711,10 @@ Perl_leave_scope(pTHX_ I32 base) 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) { @@ -755,8 +744,7 @@ Perl_leave_scope(pTHX_ I32 base) SvSETMAGIC(value); PL_localizing = 0; SvREFCNT_dec(value); - if (av) /* actually an av, hv or gv */ - SvREFCNT_dec(av); + SvREFCNT_dec(av); /* av may actually be an AV, HV or GV */ break; case SAVEt_GENERIC_PVREF: /* generic pv */ ptr = SSPOPPTR; @@ -778,9 +766,15 @@ Perl_leave_scope(pTHX_ I32 base) *(char**)ptr = str; } break; + case SAVEt_GVSV: /* scalar slot in GV */ + value = MUTABLE_SV(SSPOPPTR); + gv = MUTABLE_GV(SSPOPPTR); + ptr = &GvSV(gv); + goto restore_svp; case SAVEt_GENERIC_SVREF: /* generic sv */ value = MUTABLE_SV(SSPOPPTR); ptr = SSPOPPTR; + restore_svp: sv = *(SV**)ptr; *(SV**)ptr = value; SvREFCNT_dec(sv); @@ -796,6 +790,7 @@ Perl_leave_scope(pTHX_ I32 base) SvSETMAGIC(MUTABLE_SV(av)); PL_localizing = 0; } + SvREFCNT_dec(gv); break; case SAVEt_HV: /* hash reference */ hv = MUTABLE_HV(SSPOPPTR); @@ -807,6 +802,7 @@ Perl_leave_scope(pTHX_ I32 base) SvSETMAGIC(MUTABLE_SV(hv)); PL_localizing = 0; } + SvREFCNT_dec(gv); break; case SAVEt_INT_SMALL: ptr = SSPOPPTR; @@ -819,6 +815,15 @@ Perl_leave_scope(pTHX_ I32 base) case SAVEt_BOOL: /* bool reference */ ptr = SSPOPPTR; *(bool*)ptr = cBOOL(uv >> 8); + + if (ptr == &PL_tainted) { + /* If we don't update , 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; @@ -854,13 +859,12 @@ Perl_leave_scope(pTHX_ I32 base) *(AV**)ptr = MUTABLE_AV(SSPOPPTR); break; case SAVEt_GP: /* scalar reference */ + ptr = SSPOPPTR; gv = MUTABLE_GV(SSPOPPTR); gp_free(gv); - GvGP(gv) = (GP*)SSPOPPTR; - if (SSPOPINT) - SvFAKE_on(gv); + GvGP_set(gv, (GP*)ptr); /* putting a method back into circulation ("local")*/ - if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvNAME_get(hv)) + if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvENAME_get(hv)) mro_method_changed_in(hv); SvREFCNT_dec(gv); break; @@ -868,6 +872,10 @@ Perl_leave_scope(pTHX_ I32 base) ptr = SSPOPPTR; SvREFCNT_dec(MUTABLE_SV(ptr)); break; + case SAVEt_FREECOPHH: + ptr = SSPOPPTR; + cophh_free((COPHH *)ptr); + break; case SAVEt_MORTALIZESV: ptr = SSPOPPTR; sv_2mortal(MUTABLE_SV(ptr)); @@ -904,7 +912,10 @@ Perl_leave_scope(pTHX_ I32 base) 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)) { @@ -925,7 +936,8 @@ Perl_leave_scope(pTHX_ I32 base) 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; @@ -934,7 +946,7 @@ Perl_leave_scope(pTHX_ I32 base) 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: @@ -1011,33 +1023,23 @@ Perl_leave_scope(pTHX_ I32 base) 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)); + } } - Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints_hash); - PL_compiling.cop_hints_hash = (struct refcounted_he *) SSPOPPTR; + cophh_free(CopHINTHASH_get(&PL_compiling)); + CopHINTHASH_set(&PL_compiling, (COPHH*)SSPOPPTR); *(I32*)&PL_hints = (I32)SSPOPINT; 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; @@ -1118,11 +1120,6 @@ Perl_leave_scope(pTHX_ I32 base) ptr = SSPOPPTR; (*SSPOPDPTR)(ptr); break; - case SAVEt_COP_ARYBASE: - ptr = SSPOPPTR; - i = SSPOPINT; - CopARYBASE_set((COP *)ptr, i); - break; case SAVEt_COMPILE_WARNINGS: ptr = SSPOPPTR; @@ -1139,9 +1136,6 @@ Perl_leave_scope(pTHX_ I32 base) - 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); } @@ -1153,7 +1147,7 @@ Perl_leave_scope(pTHX_ I32 base) parser_free((yy_parser *) ptr); break; default: - Perl_croak(aTHX_ "panic: leave_scope inconsistency"); + Perl_croak(aTHX_ "panic: leave_scope inconsistency %u", type); } } @@ -1276,8 +1270,8 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx) * 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: */