diff options
author | Father Chrysostomos <sprout@cpan.org> | 2010-10-09 18:42:01 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2010-10-09 18:42:40 -0700 |
commit | c8bbf675c3e9277e1dd4b1185d91c1aef2cd2594 (patch) | |
tree | ac43f29d32d5dce5d6a0e58a2ce6bf91454604ce /mro.c | |
parent | 314655b3bf3a78f53857298857fbdc053e783117 (diff) | |
download | perl-c8bbf675c3e9277e1dd4b1185d91c1aef2cd2594.tar.gz |
Reset isa on stash manipulation
This only applies to glob-to-glob assignments and deletions of stash
elements. Other types of stash manipulation are dealt with by subse-
quent patches.
It adds mro_package_moved, a private function that iterates through
subpackages, calling mro_isa_changed_in on each.
This is related to [perl #75176], but is not the same bug. It simply
got in the way of fixing [perl #75176].
Diffstat (limited to 'mro.c')
-rw-r--r-- | mro.c | 50 |
1 files changed, 50 insertions, 0 deletions
@@ -549,6 +549,56 @@ Perl_mro_isa_changed_in(pTHX_ HV* stash) } /* +=for apidoc mro_package_moved + +Invalidates isa caches on this stash, on all subpackages nested inside it, +and on the subclasses of all those. + +=cut +*/ +void +Perl_mro_package_moved(pTHX_ const HV *stash) +{ + register XPVHV* xhv; + register HE *entry; + I32 riter = -1; + + PERL_ARGS_ASSERT_MRO_PACKAGE_MOVED; + + mro_isa_changed_in((HV *)stash); + + if(!HvARRAY(stash)) return; + + /* This is partly based on code in hv_iternext_flags. We are not call- + ing that here, as we want to avoid resetting the hash iterator. */ + + xhv = (XPVHV*)SvANY(stash); + + /* Skip the entire loop if the hash is empty. */ + if (HvUSEDKEYS(stash)) { + while (++riter <= (I32)xhv->xhv_max) { + entry = (HvARRAY(stash))[riter]; + + /* Iterate through the entries in this list */ + for(; entry; entry = HeNEXT(entry)) { + const char* key; + I32 len; + + /* If this entry is not a glob, ignore it. + Try the next. */ + if (!isGV(HeVAL(entry))) continue; + + key = hv_iterkey(entry, &len); + if(len > 1 && key[len-2] == ':' && key[len-1] == ':') { + const HV * const stash = GvHV(HeVAL(entry)); + if(stash && HvNAME(stash)) mro_package_moved(stash); + } + } + } + } +} + +/* =for apidoc mro_method_changed_in Invalidates method caching on any child classes |