summaryrefslogtreecommitdiff
path: root/scope.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-11-28 13:46:07 -0800
committerFather Chrysostomos <sprout@cpan.org>2012-11-29 09:11:31 -0800
commit3d460042b1251a4b5e3b583fa6be358554dd3bcc (patch)
treeb030f3a2e7d42864f23b1fb1ca7c78e5da7dc1b9 /scope.c
parent959f7ad7c12f768f896b4dd48b5b7f41b6b087b5 (diff)
downloadperl-3d460042b1251a4b5e3b583fa6be358554dd3bcc.tar.gz
Fix two local *ISA bugs
These are regressions from 5.8. local *ISA was not updating isa caches. local *ISA = [] was updating caches, but scope unwinding was not. Both save_gp and leave_scope/SAVEt_GP need to check whether the glob is named ISA and call mro_isa_changed_in if appropriate.
Diffstat (limited to 'scope.c')
-rw-r--r--scope.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/scope.c b/scope.c
index c4a2222e75..31b990dec5 100644
--- a/scope.c
+++ b/scope.c
@@ -286,14 +286,21 @@ Perl_save_gp(pTHX_ GV *gv, I32 empty)
if (empty) {
GP *gp = Perl_newGP(aTHX_ gv);
HV * const stash = GvSTASH(gv);
-
- if (GvCVu(gv) && stash && HvENAME(stash))
- mro_method_changed_in(GvSTASH(gv)); /* taking a method out of circulation ("local")*/
+ bool isa_changed = 0;
+
+ if (stash && HvENAME(stash)) {
+ if (GvNAMELEN(gv) == 3 && strnEQ(GvNAME(gv), "ISA", 3))
+ isa_changed = TRUE;
+ else if (GvCVu(gv))
+ /* taking a method out of circulation ("local")*/
+ mro_method_changed_in(stash);
+ }
if (GvIOp(gv) && (IoFLAGS(GvIOp(gv)) & IOf_ARGV)) {
gp->gp_io = newIO();
IoFLAGS(gp->gp_io) |= IOf_ARGV|IOf_START;
}
GvGP_set(gv,gp);
+ if (isa_changed) mro_isa_changed_in(stash);
}
else {
gp_ref(GvGP(gv));
@@ -860,9 +867,13 @@ Perl_leave_scope(pTHX_ I32 base)
gv = MUTABLE_GV(SSPOPPTR);
gp_free(gv);
GvGP_set(gv, (GP*)ptr);
- /* putting a method back into circulation ("local")*/
- if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvENAME_get(hv))
+ if ((hv=GvSTASH(gv)) && HvENAME_get(hv)) {
+ if (GvNAMELEN(gv) == 3 && strnEQ(GvNAME(gv), "ISA", 3))
+ mro_isa_changed_in(hv);
+ else if (GvCVu(gv))
+ /* putting a method back into circulation ("local")*/
gv_method_changed(gv);
+ }
SvREFCNT_dec(gv);
break;
case SAVEt_FREESV: