summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/sv.c b/sv.c
index c651eb0c24..abb4f32b0a 100644
--- a/sv.c
+++ b/sv.c
@@ -3772,7 +3772,15 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr)
&& CopSTASH_ne(PL_curcop, GvSTASH(dstr))) {
GvFLAGS(dstr) |= import_flag;
}
- if (stype == SVt_PVAV && strEQ(GvNAME((GV*)dstr), "ISA")) {
+ if (stype == SVt_PVHV) {
+ const char * const name = GvNAME((GV*)dstr);
+ const STRLEN len = GvNAMELEN(dstr);
+ if (len > 1 && name[len-2] == ':' && name[len-1] == ':') {
+ if(HvNAME(dref)) mro_package_moved((HV *)dref);
+ if(HvNAME(sref)) mro_package_moved((HV *)sref);
+ }
+ }
+ else if (stype == SVt_PVAV && strEQ(GvNAME((GV*)dstr), "ISA")) {
sv_magic(sref, dstr, PERL_MAGIC_isa, NULL, 0);
mro_isa_changed_in(GvSTASH(dstr));
}
@@ -4016,9 +4024,27 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags)
else {
GV *gv = gv_fetchsv(sstr, GV_ADD, SVt_PVGV);
if (dstr != (const SV *)gv) {
+ const char * const name = GvNAME((const GV *)dstr);
+ const STRLEN len = GvNAMELEN(dstr);
+ HV *old_stash = NULL;
+ bool reset_isa = FALSE;
+ if (len > 1 && name[len-2] == ':' && name[len-1] == ':') {
+ /* Set aside the old stash, so we can reset isa caches
+ on its subclasses. */
+ old_stash = GvHV(dstr);
+ reset_isa = TRUE;
+ }
+
if (GvGP(dstr))
gp_free(MUTABLE_GV(dstr));
GvGP(dstr) = gp_ref(GvGP(gv));
+
+ if (reset_isa) {
+ const HV * const stash = GvHV(dstr);
+ if(stash && HvNAME(stash)) mro_package_moved(stash);
+ if(old_stash && HvNAME(old_stash))
+ mro_package_moved(old_stash);
+ }
}
}
}