summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2010-11-24 11:36:36 +0000
committerNicholas Clark <nick@ccl4.org>2010-11-24 11:36:36 +0000
commit15d9236d3878cc5033b0e89e4a2fc65f07146ea5 (patch)
treea4c482005bc6578c19cf64e74da08c1346ac3c5a
parent68adb2b0c592afeb71b5a6a4f15af308d54a0db4 (diff)
downloadperl-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.c4
-rw-r--r--hv.c83
-rw-r--r--hv.h39
-rw-r--r--mro.c6
-rw-r--r--sv.c14
5 files changed, 82 insertions, 64 deletions
diff --git a/dump.c b/dump.c
index f13b9a2826..4bda943bff 100644
--- a/dump.c
+++ b/dump.c
@@ -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-
diff --git a/hv.c b/hv.c
index ee95b25add..18411d6a4f 100644
--- a/hv.c
+++ b/hv.c
@@ -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;
}
}
diff --git a/hv.h b/hv.h
index faa4bddbe6..399a7dfef7 100644
--- a/hv.h
+++ b/hv.h
@@ -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) */
diff --git a/mro.c b/mro.c
index 08320b7748..fd805d6516 100644
--- a/mro.c
+++ b/mro.c
@@ -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) {
diff --git a/sv.c b/sv.c
index b62eba9819..bf3b9b553d 100644
--- a/sv.c
+++ b/sv.c
@@ -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;