/* mro.c
*
* Copyright (c) 2007 Brandon L Black
- * Copyright (c) 2007, 2008 Larry Wall and others
+ * Copyright (c) 2007, 2008, 2009, 2010, 2011 Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
sv_upgrade(val, SVt_PV);
SvPV_set(val, HEK_KEY(share_hek_hek(key)));
SvCUR_set(val, HEK_LEN(key));
- SvREADONLY_on(val);
- SvFAKE_on(val);
+ SvIsCOW_on(val);
SvPOK_on(val);
if (HEK_UTF8(key))
SvUTF8_on(val);
/* wipe next::method cache too */
if(meta->mro_nextmethod) hv_clear(meta->mro_nextmethod);
+ /* Changes to @ISA might turn overloading on */
+ HvAMAGIC_on(stash);
+
+ /* DESTROY can be cached in SvSTASH. */
+ if (!SvOBJECT(stash)) SvSTASH(stash) = NULL;
+
/* Iterate the isarev (classes that are our children),
wiping out their linearization, method and isa caches
and upating PL_isarev. */
revmeta->cache_gen++;
if(revmeta->mro_nextmethod)
hv_clear(revmeta->mro_nextmethod);
+ if (!SvOBJECT(revstash)) SvSTASH(revstash) = NULL;
(void)
hv_store(
S_mro_gather_and_rename(pTHX_ HV * const stashes, HV * const seen_stashes,
HV *stash, HV *oldstash, SV *namesv)
{
- register XPVHV* xhv;
- register HE *entry;
+ XPVHV* xhv;
+ HE *entry;
I32 riter = -1;
I32 items = 0;
const bool stash_had_name = stash && HvENAME(stash);
while (items--) {
const U32 name_utf8 = SvUTF8(*svp);
STRLEN len;
- const char *name = SvPVx_const(*svp++, len);
- if(PL_stashcache)
+ const char *name = SvPVx_const(*svp, len);
+ if(PL_stashcache) {
+ DEBUG_o(Perl_deb(aTHX_ "mro_gather_and_rename clearing PL_stashcache for '%"SVf"'\n",
+ *svp));
(void)hv_delete(PL_stashcache, name, name_utf8 ? -(I32)len : (I32)len, G_DISCARD);
+ }
+ ++svp;
hv_ename_delete(oldstash, name, len, name_utf8);
if (!fetched_isarev) {
/* Inc the package generation, since a local method changed */
HvMROMETA(stash)->pkg_gen++;
+ /* DESTROY can be cached in SvSTASH. */
+ if (!SvOBJECT(stash)) SvSTASH(stash) = NULL;
+
/* If stash is UNIVERSAL, or one of UNIVERSAL's parents,
invalidate all method caches globally */
if((stashname_len == 9 && strEQ(stashname, "UNIVERSAL"))
mrometa->cache_gen++;
if(mrometa->mro_nextmethod)
hv_clear(mrometa->mro_nextmethod);
+ if (!SvOBJECT(revstash)) SvSTASH(revstash) = NULL;
}
}
+
+ /* The method change may be due to *{$package . "::()"} = \&nil; in
+ overload.pm. */
+ HvAMAGIC_on(stash);
}
void
* 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:
*/