summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2010-11-13 17:28:46 -0800
committerFather Chrysostomos <sprout@cpan.org>2010-11-13 17:36:16 -0800
commit6624142a770b3cb9a18e1968e0294117f8f8efa1 (patch)
tree025158923d66c7a1cc78ebe5ee48c97fb0b95d86 /mg.c
parent578895fb2f0e19d2b8092cb6d9ea802f07e7ff02 (diff)
downloadperl-6624142a770b3cb9a18e1968e0294117f8f8efa1.tar.gz
[perl #77238] Aliased @ISA does not work
This makes aliased @ISA arrays work by storing a non-magical AV as the mg_obj if there need to be multiple entries.
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/mg.c b/mg.c
index abd4a9d4d2..334eb80c95 100644
--- a/mg.c
+++ b/mg.c
@@ -1616,18 +1616,24 @@ Perl_magic_clearisa(pTHX_ SV *sv, MAGIC *mg)
if (sv)
av_clear(MUTABLE_AV(sv));
- /* XXX Once it's possible, we need to
- detect that our @ISA is aliased in
- other stashes, and act on the stashes
- of all of the aliases */
-
- /* The first case occurs via setisa,
- the second via setisa_elem, which
- calls this same magic */
+ if (SvTYPE(mg->mg_obj) != SVt_PVGV && SvSMAGICAL(mg->mg_obj))
+ /* This occurs with setisa_elem magic, which calls this
+ same function. */
+ mg = mg_find(mg->mg_obj, PERL_MAGIC_isa);
+
+ if (SvTYPE(mg->mg_obj) == SVt_PVAV) { /* multiple stashes */
+ SV **svp = AvARRAY((AV *)mg->mg_obj);
+ I32 items = AvFILLp((AV *)mg->mg_obj) + 1;
+ while (items--) {
+ stash = GvSTASH((GV *)*svp++);
+ if (stash && HvENAME(stash)) mro_isa_changed_in(stash);
+ }
+
+ return 0;
+ }
+
stash = GvSTASH(
- SvTYPE(mg->mg_obj) == SVt_PVGV
- ? (const GV *)mg->mg_obj
- : (const GV *)mg_find(mg->mg_obj, PERL_MAGIC_isa)->mg_obj
+ (const GV *)mg->mg_obj
);
/* The stash may have been detached from the symbol table, so check its