On 29 August 2010 23:09, Father Chrysostomos <sprout@cpan.org> wrote: > > On Aug 22, 2010, at 5:46 PM, Father Chrysostomos wrote: > > Initially I planned to fix the isarev leaks by making appropriate > adjustments to it whenever an @ISA is modified or a stash is freed. But, > since stashes can be detached from the main tree of stashes ($stash = delete > $::{"it::"}), they need to know whether they are still attached, so detached > stashes don’t muddle up isarev and delete entries that are still needed > (which would be worse than leaking). > > In the process of experimenting with that, I found that such stash > manipulations already fail to update isa caches, which, too, would cause my > proposed isarev changes to introduce regressions. So that’s what this patch > is for. > > Here is a patch that deals with a couple more ways of manipulating stashes. > I plan to work on assignment to empty stash elements next (or any stash > elements that are not globs). I can do this by using PVLVs. But there are > two approaches: > 1. Do it just for access from Perl by adding it to pp_helem. > 2. Do it for XS access as well, by modifying hv_fetch_ent instead (or > hv_common, or wherever the actual code is). > Number 1 makes it too easy for XS code to make changes without triggering > mro_package_moved. mro_package_moved will also have to be made public (and > probably given a better name). > Number 2 is probably more reliable. perl’s internals can pass a flag to > avoid the PVLVs. XS code that assumes that stash elements are never magical > will be broken (code that specifically calls the _nomg forms to avoid the > magic checks). Most XS code will continue to work. > So in both cases, XS code will have to be modified (if there is any that > plays with stashes). But in case 2 only code that is currently potentially > buggy will have to change. > I prefer number 2. + 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); + } Did you miss a { } there? From the indenting it looks like the if () applies to both of the following ifs, but it is an if (EXPR) STMT; not an IF (EXPR) BLOCK yves -- perl -Mre=debug -e "/just|another|perl|hacker/"Thread Previous | Thread Next