This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Use a union for storing the shared hash key reference count, rather
[perl5.git] / hv.h
diff --git a/hv.h b/hv.h
index 1ec5d56..fd0cf2e 100644 (file)
--- a/hv.h
+++ b/hv.h
@@ -15,7 +15,10 @@ struct he {
        body arenas  */
     HE         *hent_next;     /* next entry in chain */
     HEK                *hent_hek;      /* hash key */
-    SV         *hent_val;      /* scalar value that was hashed */
+    union {
+       SV      *hent_val;      /* scalar value that was hashed */
+       Size_t  hent_refcount;  /* references for this shared hash key */
+    } he_valu;
 };
 
 /* hash key -- defined separately for use as shared pointer */
@@ -38,6 +41,7 @@ struct shared_he {
 */
 struct xpvhv_aux {
     HEK                *xhv_name;      /* 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 */
 };
@@ -82,7 +86,7 @@ typedef struct {
 /* The use of a temporary pointer and the casting games
  * is needed to serve the dual purposes of
  * (a) the hashed data being interpreted as "unsigned char" (new since 5.8,
- *     a "char" can be either signed or signed, depending on the compiler)
+ *     a "char" can be either signed or unsigned, depending on the compiler)
  * (b) catering for old code that uses a "char"
  *
  * The "hash seed" feature was added in Perl 5.8.1 to perturb the results
@@ -103,7 +107,7 @@ typedef struct {
 #endif
 #define PERL_HASH(hash,str,len) \
      STMT_START        { \
-       register const char *s_PeRlHaSh_tmp = str; \
+       register const char * const s_PeRlHaSh_tmp = str; \
        register const unsigned char *s_PeRlHaSh = (const unsigned char *)s_PeRlHaSh_tmp; \
        register I32 i_PeRlHaSh = len; \
        register U32 hash_PeRlHaSh = PERL_HASH_SEED; \
@@ -121,7 +125,7 @@ typedef struct {
 #ifdef PERL_HASH_INTERNAL_ACCESS
 #define PERL_HASH_INTERNAL(hash,str,len) \
      STMT_START        { \
-       register const char *s_PeRlHaSh_tmp = str; \
+       register const char * const s_PeRlHaSh_tmp = str; \
        register const unsigned char *s_PeRlHaSh = (const unsigned char *)s_PeRlHaSh_tmp; \
        register I32 i_PeRlHaSh = len; \
        register U32 hash_PeRlHaSh = PL_rehash_seed; \
@@ -290,7 +294,7 @@ C<SV*>.
 #define HeKREHASH(he)  HEK_REHASH(HeKEY_hek(he))
 #define HeKLEN_UTF8(he)  (HeKUTF8(he) ? -HeKLEN(he) : HeKLEN(he))
 #define HeKFLAGS(he)  HEK_FLAGS(HeKEY_hek(he))
-#define HeVAL(he)              (he)->hent_val
+#define HeVAL(he)              (he)->he_valu.hent_val
 #define HeHASH(he)             HEK_HASH(HeKEY_hek(he))
 #define HePV(he,lp)            ((HeKLEN(he) == HEf_SVKEY) ?            \
                                 SvPV(HeKEY_sv(he),lp) :                \
@@ -360,6 +364,9 @@ C<SV*>.
 /* Flags for hv_iternext_flags.  */
 #define HV_ITERNEXT_WANTPLACEHOLDERS   0x01    /* Don't skip placeholders.  */
 
+#define hv_iternext(hv)        hv_iternext_flags(hv, 0)
+#define hv_magic(hv, gv, how) sv_magic((SV*)(hv), (SV*)(gv), how, Nullch, 0)
+
 /* available as a function in hv.c */
 #define Perl_sharepvn(sv, len, hash) HEK_KEY(share_hek(sv, len, hash))
 #define sharepvn(sv, len, hash)             Perl_sharepvn(sv, len, hash)
@@ -368,7 +375,7 @@ C<SV*>.
     (++(((struct shared_he *)(((char *)hek)                            \
                              - STRUCT_OFFSET(struct shared_he,         \
                                              shared_he_hek)))          \
-       ->shared_he_he.hent_val),                                       \
+       ->shared_he_he.he_valu.hent_refcount),                          \
      hek)
 
 /*