diff options
author | Nicholas Clark <nick@ccl4.org> | 2008-09-12 09:25:55 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2008-09-12 09:25:55 +0000 |
commit | 6e4aef591331d48363634d9ad4a01d6c6b5f5577 (patch) | |
tree | 05af6b3137bd0f80e535f9f3f2a468126ef514b2 /mro.c | |
parent | 5782d502273e5b6d06607ebe625248c4c102d93b (diff) | |
download | perl-6e4aef591331d48363634d9ad4a01d6c6b5f5577.tar.gz |
Build the isa cache from any linear ISA, rather than forcing the use
of dfs. This avoids calling dfs on a C3 class (and all its parents),
which won't break anything, but is more work than is needed.
p4raw-id: //depot/perl@34356
Diffstat (limited to 'mro.c')
-rw-r--r-- | mro.c | 25 |
1 files changed, 22 insertions, 3 deletions
@@ -105,9 +105,28 @@ Perl_get_isa_hash(pTHX_ HV *const stash) PERL_ARGS_ASSERT_GET_ISA_HASH; - if (!meta->isa) - mro_get_linear_isa_dfs(stash, 0); - assert(meta->isa); + if (!meta->isa) { + AV *const isa = mro_get_linear_isa(stash); + if (!meta->isa) { + HV *const isa_hash = newHV(); + /* Linearisation didn't build it for us, so do it here. */ + SV *const *svp = AvARRAY(isa); + SV *const *const svp_end = svp + AvFILLp(isa) + 1; + const HEK *const canon_name = HvNAME_HEK(stash); + + while (svp < svp_end) { + (void) hv_store_ent(isa_hash, *svp++, &PL_sv_undef, 0); + } + + (void) hv_common(isa_hash, NULL, HEK_KEY(canon_name), + HEK_LEN(canon_name), HEK_FLAGS(canon_name), + HV_FETCH_ISSTORE, &PL_sv_undef, + HEK_HASH(canon_name)); + (void) hv_store(isa_hash, "UNIVERSAL", 9, &PL_sv_undef, 0); + + meta->isa = isa_hash; + } + } return meta->isa; } |