summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorBrandon Black <blblack@gmail.com>2007-06-27 05:07:54 -0500
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2007-06-28 06:32:01 +0000
commit5be5c7a687aa37f2ea9dec7988eb57cad1f1ec24 (patch)
tree99d8d6a8bdf7da9c442f53ad4ea7ffb2d72e9f48 /hv.c
parent09576c7db8c59458f52d7746e7f4062d64ff34e7 (diff)
downloadperl-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.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/hv.c b/hv.c
index cf0f3f4524..adbfbdf0e0 100644
--- a/hv.c
+++ b/hv.c
@@ -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) {