diff options
author | Brandon Black <blblack@gmail.com> | 2007-06-27 05:07:54 -0500 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2007-06-28 06:32:01 +0000 |
commit | 5be5c7a687aa37f2ea9dec7988eb57cad1f1ec24 (patch) | |
tree | 99d8d6a8bdf7da9c442f53ad4ea7ffb2d72e9f48 /hv.c | |
parent | 09576c7db8c59458f52d7746e7f4062d64ff34e7 (diff) | |
download | perl-5be5c7a687aa37f2ea9dec7988eb57cad1f1ec24.tar.gz |
Re: [perl #43357] *DESTROY = sub {} at runtime
From: "Brandon Black" <blblack@gmail.com>
Message-ID: <84621a60706270807r7af65546x8d959b131ffa28e6@mail.gmail.com>
p4raw-id: //depot/perl@31489
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 28 |
1 files changed, 25 insertions, 3 deletions
@@ -1518,12 +1518,19 @@ Perl_hv_free_ent(pTHX_ HV *hv, register HE *entry) { dVAR; SV *val; + I32 isa_changing = 0; if (!entry) return; val = HeVAL(entry); - if (val && isGV(val) && GvCVu(val) && HvNAME_get(hv)) - mro_method_changed_in(hv); /* deletion of method from stash */ + + if(HvNAME_get(hv) && val && isGV(val)) { + if(GvCVu((GV*)val)) + mro_method_changed_in(hv); /* deletion of method from stash */ + else if(GvAV((GV*)val) && strEQ(GvNAME((GV*)val), "ISA")) + isa_changing = 1; + } + SvREFCNT_dec(val); if (HeKLEN(entry) == HEf_SVKEY) { SvREFCNT_dec(HeKEY_sv(entry)); @@ -1534,6 +1541,8 @@ Perl_hv_free_ent(pTHX_ HV *hv, register HE *entry) else Safefree(HeKEY_hek(entry)); del_HE(entry); + + if(isa_changing) mro_isa_changed_in(hv); /* deletion of @ISA from stash */ } void @@ -1844,8 +1853,21 @@ Perl_hv_undef(pTHX_ HV *hv) DEBUG_A(Perl_hv_assert(aTHX_ hv)); xhv = (XPVHV*)SvANY(hv); - if ((name = HvNAME_get(hv)) && !PL_dirty) + /* If it's a stash, undef the @ISA and call + mro_isa_changed_in before proceeding with + the rest of the destruction */ + if ((name = HvNAME_get(hv)) && !PL_dirty) { + GV** gvp; + GV* gv; + AV* isa; + + gvp = (GV**)hv_fetchs(hv, "ISA", FALSE); + gv = gvp ? *gvp : NULL; + isa = (gv && isGV_with_GP(gv)) ? GvAV(gv) : NULL; + + if(isa) av_undef(isa); mro_isa_changed_in(hv); + } hfreeentries(hv); if (name) { |