X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/7623d4262995987d3de73f116de43554c077f9c7..32878f30ba1216461c8932946f0868cda9920d62:/scope.c diff --git a/scope.c b/scope.c index 0923747..20e027f 100644 --- a/scope.c +++ b/scope.c @@ -505,11 +505,18 @@ Perl_save_delete(pTHX_ HV *hv, char *key, I32 klen) PERL_ARGS_ASSERT_SAVE_DELETE; - SSCHECK(4); - SSPUSHINT(klen); - SSPUSHPTR(key); - SSPUSHPTR(SvREFCNT_inc_simple(hv)); - SSPUSHINT(SAVEt_DELETE); + save_pushptri32ptr(key, klen, SvREFCNT_inc_simple(hv), SAVEt_DELETE); +} + +void +Perl_save_adelete(pTHX_ AV *av, I32 key) +{ + dVAR; + + PERL_ARGS_ASSERT_SAVE_ADELETE; + + SvREFCNT_inc_void(av); + save_pushi32ptr(key, av, SAVEt_ADELETE); } void @@ -536,6 +543,35 @@ Perl_save_destructor_x(pTHX_ DESTRUCTORFUNC_t f, void* p) } 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; + } + 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)); + } else { + save_pushi32ptr(PL_hints, PL_compiling.cop_hints_hash, SAVEt_HINTS); + } +} + +static void +S_save_pushptri32ptr(pTHX_ void *const ptr1, const I32 i, void *const ptr2, + const int type) +{ + SSCHECK(4); + SSPUSHPTR(ptr1); + SSPUSHINT(i); + SSPUSHPTR(ptr2); + SSPUSHINT(type); +} + +void Perl_save_aelem(pTHX_ AV *av, I32 idx, SV **sptr) { dVAR; @@ -544,11 +580,8 @@ Perl_save_aelem(pTHX_ AV *av, I32 idx, SV **sptr) PERL_ARGS_ASSERT_SAVE_AELEM; SvGETMAGIC(*sptr); - SSCHECK(4); - SSPUSHPTR(SvREFCNT_inc_simple(av)); - SSPUSHINT(idx); - SSPUSHPTR(SvREFCNT_inc(*sptr)); - SSPUSHINT(SAVEt_AELEM); + save_pushptri32ptr(SvREFCNT_inc_simple(av), idx, SvREFCNT_inc(*sptr), + SAVEt_AELEM); /* if it gets reified later, the restore will have the wrong refcnt */ if (!AvREAL(av) && AvREIFY(av)) SvREFCNT_inc_void(*sptr); @@ -626,6 +659,8 @@ Perl_leave_scope(pTHX_ I32 base) void* ptr; register char* str; I32 i; + /* Localise the effects of the TAINT_NOT inside the loop. */ + const bool was = PL_tainted; if (base < -1) Perl_croak(aTHX_ "panic: corrupt saved stack index"); @@ -834,11 +869,19 @@ Perl_leave_scope(pTHX_ I32 base) case SAVEt_DELETE: ptr = SSPOPPTR; hv = MUTABLE_HV(ptr); + i = SSPOPINT; ptr = SSPOPPTR; - (void)hv_delete(hv, (char*)ptr, (I32)SSPOPINT, G_DISCARD); + (void)hv_delete(hv, (char*)ptr, i, G_DISCARD); SvREFCNT_dec(hv); Safefree(ptr); break; + case SAVEt_ADELETE: + ptr = SSPOPPTR; + av = MUTABLE_AV(ptr); + i = SSPOPINT; + (void)av_delete(av, i, G_DISCARD); + SvREFCNT_dec(av); + break; case SAVEt_DESTRUCTOR_X: ptr = SSPOPPTR; (*SSPOPDXPTR)(aTHX_ ptr); @@ -879,19 +922,18 @@ Perl_leave_scope(pTHX_ I32 base) sv = MUTABLE_SV(SSPOPPTR); hv = MUTABLE_HV(SSPOPPTR); ptr = hv_fetch_ent(hv, sv, 1, 0); + SvREFCNT_dec(sv); if (ptr) { const SV * const oval = HeVAL((HE*)ptr); if (oval && oval != &PL_sv_undef) { ptr = &HeVAL((HE*)ptr); if (SvTIED_mg((const SV *)hv, PERL_MAGIC_tied)) SvREFCNT_inc_void(*(SV**)ptr); - SvREFCNT_dec(sv); av = MUTABLE_AV(hv); /* what to refcnt_dec */ goto restore_sv; } } SvREFCNT_dec(hv); - SvREFCNT_dec(sv); SvREFCNT_dec(value); break; case SAVEt_OP: @@ -902,9 +944,9 @@ Perl_leave_scope(pTHX_ I32 base) SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv))); GvHV(PL_hintgv) = NULL; } - *(I32*)&PL_hints = (I32)SSPOPINT; Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints_hash); PL_compiling.cop_hints_hash = (struct refcounted_he *) 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); @@ -1043,6 +1085,8 @@ Perl_leave_scope(pTHX_ I32 base) Perl_croak(aTHX_ "panic: leave_scope inconsistency"); } } + + PL_tainted = was; } void