diff options
author | Nicholas Clark <nick@ccl4.org> | 2010-11-24 11:36:36 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2010-11-24 11:36:36 +0000 |
commit | 15d9236d3878cc5033b0e89e4a2fc65f07146ea5 (patch) | |
tree | a4c482005bc6578c19cf64e74da08c1346ac3c5a | |
parent | 68adb2b0c592afeb71b5a6a4f15af308d54a0db4 (diff) | |
download | perl-15d9236d3878cc5033b0e89e4a2fc65f07146ea5.tar.gz |
Convert xhv_name in struct xpvhv_aux to be a union of HEK* and HEK**
This avoids a lot of casting. Nothing outside the perl core code is accessing
that member directly.
-rw-r--r-- | dump.c | 4 | ||||
-rw-r--r-- | hv.c | 83 | ||||
-rw-r--r-- | hv.h | 39 | ||||
-rw-r--r-- | mro.c | 6 | ||||
-rw-r--r-- | sv.c | 14 |
5 files changed, 82 insertions, 64 deletions
@@ -1862,10 +1862,10 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo level, file, " NAMECOUNT = %"IVdf"\n", (IV)HvAUX(sv)->xhv_name_count ); - if (HvAUX(sv)->xhv_name && HvENAME_HEK_NN(sv)) { + if (HvAUX(sv)->xhv_name_u.xhvnameu_name && HvENAME_HEK_NN(sv)) { if (HvAUX(sv)->xhv_name_count) { SV * const names = sv_newmortal(); - HEK ** const namep = (HEK **)HvAUX(sv)->xhv_name; + HEK ** const namep = HvAUX(sv)->xhv_name_u.xhvnameu_names; const I32 count = HvAUX(sv)->xhv_name_count; /* This line sets hekp to one element before the first name, so the ++hekp below will put us at the start- @@ -1681,11 +1681,17 @@ S_hfreeentries(pTHX_ HV *hv) /* Copy the name and MRO stuff to a new aux structure if present. */ - if (iter->xhv_name || iter->xhv_mro_meta) { + if (iter->xhv_name_u.xhvnameu_name || iter->xhv_mro_meta) { struct xpvhv_aux * const newaux = hv_auxinit(hv); - newaux->xhv_name = iter->xhv_name; newaux->xhv_name_count = iter->xhv_name_count; - iter->xhv_name = NULL; + if (newaux->xhv_name_count) + newaux->xhv_name_u.xhvnameu_names + = iter->xhv_name_u.xhvnameu_names; + else + newaux->xhv_name_u.xhvnameu_name + = iter->xhv_name_u.xhvnameu_name; + + iter->xhv_name_u.xhvnameu_name = NULL; newaux->xhv_mro_meta = iter->xhv_mro_meta; iter->xhv_mro_meta = NULL; } @@ -1813,8 +1819,13 @@ S_hfreeentries(pTHX_ HV *hv) if (current_aux) { struct xpvhv_aux * const aux = SvOOK(hv) ? HvAUX(hv) : hv_auxinit(hv); - aux->xhv_name = current_aux->xhv_name; aux->xhv_name_count = current_aux->xhv_name_count; + if(aux->xhv_name_count) + aux->xhv_name_u.xhvnameu_names + = current_aux->xhv_name_u.xhvnameu_names; + else + aux->xhv_name_u.xhvnameu_name + = current_aux->xhv_name_u.xhvnameu_name; aux->xhv_mro_meta = current_aux->xhv_mro_meta; } @@ -1878,7 +1889,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) /* If this call originated from sv_clear, then we must check for * effective names that need freeing, as well as the usual name. */ name = HvNAME(hv); - if (flags & HV_NAME_SETALL ? (const char *)aux->xhv_name : name) { + if (flags & HV_NAME_SETALL ? !!aux->xhv_name_u.xhvnameu_name : !!name) { if (name && PL_stashcache) (void)hv_delete(PL_stashcache, name, HvNAMELEN_get(hv), G_DISCARD); hv_name_set(hv, NULL, 0, flags); @@ -1900,7 +1911,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) Safefree(meta); aux->xhv_mro_meta = NULL; } - if (!aux->xhv_name) + if (!aux->xhv_name_u.xhvnameu_name) SvFLAGS(hv) &= ~SVf_OOK; else if (!zeroed) Zero(HvARRAY(hv), xhv->xhv_max+1 /* HvMAX(hv)+1 */, HE*); @@ -1970,7 +1981,7 @@ S_hv_auxinit(HV *hv) { iter->xhv_riter = -1; /* HvRITER(hv) = -1 */ iter->xhv_eiter = NULL; /* HvEITER(hv) = NULL */ - iter->xhv_name = 0; + iter->xhv_name_u.xhvnameu_name = 0; iter->xhv_name_count = 0; iter->xhv_backreferences = 0; iter->xhv_mro_meta = NULL; @@ -2103,10 +2114,10 @@ Perl_hv_name_set(pTHX_ HV *hv, const char *name, U32 len, U32 flags) if (SvOOK(hv)) { iter = HvAUX(hv); - if (iter->xhv_name) { + if (iter->xhv_name_u.xhvnameu_name) { if(iter->xhv_name_count) { if(flags & HV_NAME_SETALL) { - HEK ** const name = (HEK **)HvAUX(hv)->xhv_name; + HEK ** const name = HvAUX(hv)->xhv_name_u.xhvnameu_names; HEK **hekp = name + ( iter->xhv_name_count < 0 ? -iter->xhv_name_count @@ -2117,44 +2128,44 @@ Perl_hv_name_set(pTHX_ HV *hv, const char *name, U32 len, U32 flags) /* The first elem may be null. */ if(*name) unshare_hek_or_pvn(*name, 0, 0, 0); Safefree(name); - spot = &iter->xhv_name; + spot = &iter->xhv_name_u.xhvnameu_name; iter->xhv_name_count = 0; } else { if(iter->xhv_name_count > 0) { /* shift some things over */ - Renewc( - iter->xhv_name, iter->xhv_name_count + 1, HEK *, HEK + Renew( + iter->xhv_name_u.xhvnameu_names, iter->xhv_name_count + 1, HEK * ); - spot = (HEK **)iter->xhv_name; + spot = iter->xhv_name_u.xhvnameu_names; spot[iter->xhv_name_count] = spot[1]; spot[1] = spot[0]; iter->xhv_name_count = -(iter->xhv_name_count + 1); } - else if(*(spot = (HEK **)iter->xhv_name)) { + else if(*(spot = iter->xhv_name_u.xhvnameu_names)) { unshare_hek_or_pvn(*spot, 0, 0, 0); } } } else if (flags & HV_NAME_SETALL) { - unshare_hek_or_pvn(iter->xhv_name, 0, 0, 0); - spot = &iter->xhv_name; + unshare_hek_or_pvn(iter->xhv_name_u.xhvnameu_name, 0, 0, 0); + spot = &iter->xhv_name_u.xhvnameu_name; } else { - HEK * const existing_name = iter->xhv_name; - Newxc(iter->xhv_name, 2, HEK *, HEK); + HEK * const existing_name = iter->xhv_name_u.xhvnameu_name; + Newx(iter->xhv_name_u.xhvnameu_names, 2, HEK *); iter->xhv_name_count = -2; - spot = (HEK **)iter->xhv_name; + spot = iter->xhv_name_u.xhvnameu_names; spot[1] = existing_name; } } - else { spot = &iter->xhv_name; iter->xhv_name_count = 0; } + else { spot = &iter->xhv_name_u.xhvnameu_name; iter->xhv_name_count = 0; } } else { if (name == 0) return; iter = hv_auxinit(hv); - spot = &iter->xhv_name; + spot = &iter->xhv_name_u.xhvnameu_name; } PERL_HASH(hash, name, len); *spot = name ? share_hek(name, len, hash) : NULL; @@ -2188,7 +2199,7 @@ Perl_hv_ename_add(pTHX_ HV *hv, const char *name, U32 len, U32 flags) PERL_HASH(hash, name, len); if (aux->xhv_name_count) { - HEK ** const xhv_name = (HEK **)aux->xhv_name; + HEK ** const xhv_name = aux->xhv_name_u.xhvnameu_names; I32 count = aux->xhv_name_count; HEK **hekp = xhv_name + (count < 0 ? -count : count); while (hekp-- > xhv_name) @@ -2201,19 +2212,19 @@ Perl_hv_ename_add(pTHX_ HV *hv, const char *name, U32 len, U32 flags) } if (count < 0) aux->xhv_name_count--, count = -count; else aux->xhv_name_count++; - Renewc(aux->xhv_name, count + 1, HEK *, HEK); - ((HEK **)aux->xhv_name)[count] = share_hek(name, len, hash); + Renew(aux->xhv_name_u.xhvnameu_names, count + 1, HEK *); + (aux->xhv_name_u.xhvnameu_names)[count] = share_hek(name, len, hash); } else { - HEK *existing_name = aux->xhv_name; + HEK *existing_name = aux->xhv_name_u.xhvnameu_name; if ( existing_name && HEK_LEN(existing_name) == (I32)len && memEQ(HEK_KEY(existing_name), name, len) ) return; - Newxc(aux->xhv_name, 2, HEK *, HEK); + Newx(aux->xhv_name_u.xhvnameu_names, 2, HEK *); aux->xhv_name_count = existing_name ? 2 : -2; - *(HEK **)aux->xhv_name = existing_name; - ((HEK **)aux->xhv_name)[1] = share_hek(name, len, hash); + *aux->xhv_name_u.xhvnameu_names = existing_name; + (aux->xhv_name_u.xhvnameu_names)[1] = share_hek(name, len, hash); } } @@ -2244,10 +2255,10 @@ Perl_hv_ename_delete(pTHX_ HV *hv, const char *name, U32 len, U32 flags) if (!SvOOK(hv)) return; aux = HvAUX(hv); - if (!aux->xhv_name) return; + if (!aux->xhv_name_u.xhvnameu_name) return; if (aux->xhv_name_count) { - HEK ** const namep = (HEK **)aux->xhv_name; + HEK ** const namep = aux->xhv_name_u.xhvnameu_names; I32 const count = aux->xhv_name_count; HEK **victim = namep + (count < 0 ? -count : count); while (victim-- > namep + 1) @@ -2263,7 +2274,7 @@ Perl_hv_ename_delete(pTHX_ HV *hv, const char *name, U32 len, U32 flags) && !*namep ) { /* if there are none left */ Safefree(namep); - aux->xhv_name = NULL; + aux->xhv_name_u.xhvnameu_names = NULL; aux->xhv_name_count = 0; } else { @@ -2281,12 +2292,12 @@ Perl_hv_ename_delete(pTHX_ HV *hv, const char *name, U32 len, U32 flags) } } else if( - HEK_LEN(aux->xhv_name) == (I32)len - && memEQ(HEK_KEY(aux->xhv_name), name, len) + HEK_LEN(aux->xhv_name_u.xhvnameu_name) == (I32)len + && memEQ(HEK_KEY(aux->xhv_name_u.xhvnameu_name), name, len) ) { - const HEK * const namehek = aux->xhv_name; - Newxc(aux->xhv_name, 1, HEK *, HEK); - *(const HEK **)aux->xhv_name = namehek; + HEK * const namehek = aux->xhv_name_u.xhvnameu_name; + Newx(aux->xhv_name_u.xhvnameu_names, 1, HEK *); + *aux->xhv_name_u.xhvnameu_names = namehek; aux->xhv_name_count = -1; } } @@ -72,16 +72,21 @@ struct mro_meta { Don't access this directly. */ +union _xhvnameu { + HEK *xhvnameu_name; /* When xhv_name_count is 0 */ + HEK **xhvnameu_names; /* When xhv_name_count is non-0 */ +}; + struct xpvhv_aux { - HEK *xhv_name; /* name, if a symbol table */ + union _xhvnameu xhv_name_u; /* name, if a symbol table */ AV *xhv_backreferences; /* back references for weak references */ HE *xhv_eiter; /* current entry of iterator */ I32 xhv_riter; /* current root of iterator */ -/* Concerning xhv_name_count: When non-zero, xhv_name is actually a pointer +/* Concerning xhv_name_count: When non-zero, xhv_name_u contains a pointer * to an array of HEK pointers, this being the length. The first element is * the name of the stash, which may be NULL. If xhv_name_count is positive, * then *xhv_name is one of the effective names. If xhv_name_count is nega- - * tive, then xhv_name[1] is the first effective name. + * tive, then xhv_name_u.xhvnameu_names[1] is the first effective name. */ I32 xhv_name_count; struct mro_meta *xhv_mro_meta; @@ -271,35 +276,35 @@ C<SV*>. /* FIXME - all of these should use a UTF8 aware API, which should also involve getting the length. */ -#define HvNAME_HEK_NN(hv) \ - ( \ - HvAUX(hv)->xhv_name_count \ - ? *(HEK **)HvAUX(hv)->xhv_name \ - : HvAUX(hv)->xhv_name \ +#define HvNAME_HEK_NN(hv) \ + ( \ + HvAUX(hv)->xhv_name_count \ + ? *HvAUX(hv)->xhv_name_u.xhvnameu_names \ + : HvAUX(hv)->xhv_name_u.xhvnameu_name \ ) /* This macro may go away without notice. */ #define HvNAME_HEK(hv) \ - (SvOOK(hv) && HvAUX(hv)->xhv_name ? HvNAME_HEK_NN(hv) : NULL) + (SvOOK(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name ? HvNAME_HEK_NN(hv) : NULL) #define HvNAME_get(hv) \ - ((SvOOK(hv) && (HvAUX(hv)->xhv_name) && HvNAME_HEK_NN(hv)) \ + ((SvOOK(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name && HvNAME_HEK_NN(hv)) \ ? HEK_KEY(HvNAME_HEK_NN(hv)) : NULL) #define HvNAMELEN_get(hv) \ - ((SvOOK(hv) && (HvAUX(hv)->xhv_name) && HvNAME_HEK_NN(hv)) \ + ((SvOOK(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name && HvNAME_HEK_NN(hv)) \ ? HEK_LEN(HvNAME_HEK_NN(hv)) : 0) #define HvENAME_HEK_NN(hv) \ ( \ - HvAUX(hv)->xhv_name_count > 0 ? *(HEK **)HvAUX(hv)->xhv_name : \ - HvAUX(hv)->xhv_name_count < -1 ? ((HEK **)HvAUX(hv)->xhv_name)[1] : \ + HvAUX(hv)->xhv_name_count > 0 ? HvAUX(hv)->xhv_name_u.xhvnameu_names[0] : \ + HvAUX(hv)->xhv_name_count < -1 ? HvAUX(hv)->xhv_name_u.xhvnameu_names[1] : \ HvAUX(hv)->xhv_name_count == -1 ? NULL : \ - HvAUX(hv)->xhv_name \ + HvAUX(hv)->xhv_name_u.xhvnameu_name \ ) #define HvENAME_HEK(hv) \ - (SvOOK(hv) && HvAUX(hv)->xhv_name ? HvENAME_HEK_NN(hv) : NULL) + (SvOOK(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name ? HvENAME_HEK_NN(hv) : NULL) #define HvENAME_get(hv) \ - ((SvOOK(hv) && (HvAUX(hv)->xhv_name) && HvENAME_HEK_NN(hv)) \ + ((SvOOK(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name && HvENAME_HEK_NN(hv)) \ ? HEK_KEY(HvENAME_HEK_NN(hv)) : NULL) #define HvENAMELEN_get(hv) \ - ((SvOOK(hv) && (HvAUX(hv)->xhv_name) && HvENAME_HEK_NN(hv)) \ + ((SvOOK(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name && HvENAME_HEK_NN(hv)) \ ? HEK_LEN(HvENAME_HEK_NN(hv)) : 0) /* the number of keys (including any placeholers) */ @@ -216,7 +216,7 @@ S_mro_get_linear_isa_dfs(pTHX_ HV *stash, U32 level) assert(HvAUX(stash)); stashhek - = HvAUX(stash)->xhv_name && HvENAME_HEK_NN(stash) + = HvAUX(stash)->xhv_name_u.xhvnameu_name && HvENAME_HEK_NN(stash) ? HvENAME_HEK_NN(stash) : HvNAME_HEK(stash); @@ -744,10 +744,10 @@ Perl_mro_package_moved(pTHX_ HV * const stash, HV * const oldstash, name_count = HvAUX(GvSTASH(gv))->xhv_name_count; if (!name_count) { name_count = 1; - namep = &HvAUX(GvSTASH(gv))->xhv_name; + namep = &HvAUX(GvSTASH(gv))->xhv_name_u.xhvnameu_name; } else { - namep = (HEK **)HvAUX(GvSTASH(gv))->xhv_name; + namep = HvAUX(GvSTASH(gv))->xhv_name_u.xhvnameu_names; if (name_count < 0) ++namep, name_count = -name_count - 1; } if (name_count == 1) { @@ -11819,30 +11819,32 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) ++i; } if (SvOOK(sstr)) { - HEK *hvname; const struct xpvhv_aux * const saux = HvAUX(sstr); struct xpvhv_aux * const daux = HvAUX(dstr); /* This flag isn't copied. */ /* SvOOK_on(hv) attacks the IV flags. */ SvFLAGS(dstr) |= SVf_OOK; - hvname = saux->xhv_name; if (saux->xhv_name_count) { - HEK ** const sname = (HEK **)saux->xhv_name; + HEK ** const sname = saux->xhv_name_u.xhvnameu_name; const I32 count = saux->xhv_name_count < 0 ? -saux->xhv_name_count : saux->xhv_name_count; HEK **shekp = sname + count; HEK **dhekp; - Newxc(daux->xhv_name, count, HEK *, HEK); - dhekp = (HEK **)daux->xhv_name + count; + Newx(daux->xhv_name_u.xhvnameu_names, count, HEK *); + dhekp = daux->xhv_name_u.xhvnameu_names + count; while (shekp-- > sname) { dhekp--; *dhekp = hek_dup(*shekp, param); } } - else daux->xhv_name = hek_dup(hvname, param); + else { + daux->xhv_name_u.xhvnameu_name + = hek_dup(saux->xhv_name_u.xhvnameu_name, + param); + } daux->xhv_name_count = saux->xhv_name_count; daux->xhv_riter = saux->xhv_riter; |