This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Typo in perldelta
[perl5.git] / hv.h
diff --git a/hv.h b/hv.h
index e120dd4..6a41324 100644 (file)
--- a/hv.h
+++ b/hv.h
@@ -41,15 +41,21 @@ struct shared_he {
    Use the funcs in mro.c
 */
 
-
-/* structure may change, so not public yet */
-struct mro_alg;
+struct mro_alg {
+    AV *(*resolve)(pTHX_ HV* stash, U32 level);
+    const char *name;
+    U16 length;
+    U16        kflags; /* For the hash API - set HVhek_UTF8 if name is UTF-8 */
+    U32 hash; /* or 0 */
+};
 
 struct mro_meta {
-    /* repurposed as a hash holding the different MROs private data. */
-    AV      *mro_linear_dfs; /* cached dfs @ISA linearization */
-    /* repurposed as a pointer directly to the current MROs private data.  */
-    AV      *mro_linear_c3;  /* cached c3 @ISA linearization */
+    /* a hash holding the different MROs private data.  */
+    HV      *mro_linear_all;
+    /* a pointer directly to the current MROs private data.  If mro_linear_all
+       is NULL, this owns the SV reference, else it is just a pointer to a
+       value stored in and owned by mro_linear_all.  */
+    SV      *mro_linear_current;
     HV      *mro_nextmethod; /* next::method caching */
     U32     cache_gen;       /* Bumping this invalidates our method cache */
     U32     pkg_gen;         /* Bumps when local methods/@ISA change */
@@ -59,7 +65,7 @@ struct mro_meta {
 
 #define MRO_GET_PRIVATE_DATA(smeta, which)                \
     (((smeta)->mro_which && (which) == (smeta)->mro_which) \
-     ? MUTABLE_SV((smeta)->mro_linear_c3)                 \
+     ? (smeta)->mro_linear_current                        \
      : Perl_mro_get_private_data(aTHX_ (smeta), (which)))
 
 /* Subject to change.
@@ -71,34 +77,25 @@ struct xpvhv_aux {
     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 
+ * 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.
+ */
+    I32                xhv_name_count;
     struct mro_meta *xhv_mro_meta;
 };
 
-#define _XPVHV_ALLOCATED_HEAD                                              \
-    STRLEN     xhv_fill;       /* how full xhv_array currently is */       \
-    STRLEN     xhv_max         /* subscript of last element of xhv_array */
-
-#define _XPVHV_HEAD    \
-    union _xnvu xnv_u; \
-    _XPVHV_ALLOCATED_HEAD
-
 /* hash structure: */
 /* This structure must match the beginning of struct xpvmg in sv.h. */
 struct xpvhv {
-    _XPVHV_HEAD;
-    _XPVMG_HEAD;
+    HV*                xmg_stash;      /* class package */
+    union _xmgu        xmg_u;
+    STRLEN      xhv_keys;       /* total keys, including placeholders */
+    STRLEN      xhv_max;        /* subscript of last element of xhv_array */
 };
 
-#define xhv_keys xiv_u.xivu_iv
-
-typedef struct {
-    _XPVHV_ALLOCATED_HEAD;
-    _XPVMG_HEAD;
-} xpvhv_allocated;
-
-#undef _XPVHV_ALLOCATED_HEAD
-#undef _XPVHV_HEAD
-
 /* hash a key */
 /* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins
  * from requirements by Colin Plumb.
@@ -181,6 +178,14 @@ Null HV pointer.
 Returns the package name of a stash, or NULL if C<stash> isn't a stash.
 See C<SvSTASH>, C<CvSTASH>.
 
+=for apidoc Am|char*|HvENAME|HV* stash
+Returns the effective name of a stash, or NULL if there is none. The
+effective name represents a location in the symbol table where this stash
+resides. It is updated automatically when packages are aliased or deleted.
+A stash that is no longer in the symbol table has no effective name. This
+name is preferable to C<HvNAME> for use in MRO linearisations and isa
+caches.
+
 =for apidoc Am|void*|HeKEY|HE* he
 Returns the actual pointer stored in the key slot of the hash entry. The
 pointer may be either C<char*> or C<SV*>, depending on the value of
@@ -214,7 +219,7 @@ If you are using C<HePV> to get values to pass to C<newSVpvn()> to create a
 new SV, you should consider using C<newSVhek(HeKEY_hek(he))> as it is more
 efficient.
 
-=for apidoc Am|char*|HeUTF8|HE* he|STRLEN len
+=for apidoc Am|char*|HeUTF8|HE* he
 Returns whether the C<char *> value returned by C<HePV> is encoded in UTF-8,
 doing any necessary dereferencing of possibly C<SV*> keys.  The value returned
 will be 0 or non-0, not necessarily 1 (or even a value with any low bits set),
@@ -244,7 +249,7 @@ C<SV*>.
 #  define Nullhv Null(HV*)
 #endif
 #define HvARRAY(hv)    ((hv)->sv_u.svu_hash)
-#define HvFILL(hv)     ((XPVHV*)  SvANY(hv))->xhv_fill
+#define HvFILL(hv)     Perl_hv_fill(aTHX_ (const HV *)(hv))
 #define HvMAX(hv)      ((XPVHV*)  SvANY(hv))->xhv_max
 /* This quite intentionally does no flag checking first. That's your
    responsibility.  */
@@ -256,6 +261,7 @@ C<SV*>.
 #define HvRITER_get(hv)        (SvOOK(hv) ? HvAUX(hv)->xhv_riter : -1)
 #define HvEITER_get(hv)        (SvOOK(hv) ? HvAUX(hv)->xhv_eiter : NULL)
 #define HvNAME(hv)     HvNAME_get(hv)
+#define HvENAME(hv)    HvENAME_get(hv)
 
 /* Checking that hv is a valid package stash is the
    caller's responsibility */
@@ -265,12 +271,36 @@ 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           \
+ )
 /* This macro may go away without notice.  */
-#define HvNAME_HEK(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_name : NULL)
-#define HvNAME_get(hv) ((SvOOK(hv) && (HvAUX(hv)->xhv_name)) \
-                        ? HEK_KEY(HvAUX(hv)->xhv_name) : NULL)
-#define HvNAMELEN_get(hv)      ((SvOOK(hv) && (HvAUX(hv)->xhv_name)) \
-                                ? HEK_LEN(HvAUX(hv)->xhv_name) : 0)
+#define HvNAME_HEK(hv) \
+       (SvOOK(hv) && HvAUX(hv)->xhv_name ? HvNAME_HEK_NN(hv) : NULL)
+#define HvNAME_get(hv) \
+       ((SvOOK(hv) && (HvAUX(hv)->xhv_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)) \
+                                ? 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 == -1 ? NULL                              : \
+                                    HvAUX(hv)->xhv_name                 \
+ )
+#define HvENAME_HEK(hv) \
+       (SvOOK(hv) && HvAUX(hv)->xhv_name ? HvENAME_HEK_NN(hv) : NULL)
+#define HvENAME_get(hv) \
+       ((SvOOK(hv) && (HvAUX(hv)->xhv_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)) \
+                                ? HEK_LEN(HvENAME_HEK_NN(hv)) : 0)
 
 /* the number of keys (including any placeholers) */
 #define XHvTOTALKEYS(xhv)      ((xhv)->xhv_keys)
@@ -361,6 +391,9 @@ C<SV*>.
 #define HVhek_FREEKEY  0x100 /* Internal flag to say key is malloc()ed.  */
 #define HVhek_PLACEHOLD        0x200 /* Internal flag to create placeholder.
                                * (may change, but Storable is a core module) */
+#define HVhek_KEYCANONICAL 0x400 /* Internal flag - key is in canonical form.
+                                   If the string is UTF-8, it cannot be
+                                   converted to bytes. */
 #define HVhek_MASK     0xFF
 
 /* Which flags enable HvHASKFLAGS? Somewhat a hack on a hack, as
@@ -459,6 +492,9 @@ C<SV*>.
 
 struct refcounted_he;
 
+/* flags for the refcounted_he API */
+#define REFCOUNTED_HE_KEY_UTF8         0x00000001
+
 #ifdef PERL_CORE
 
 /* Gosh. This really isn't a good name any longer.  */
@@ -482,6 +518,30 @@ struct refcounted_he {
     char                  refcounted_he_data[1];
 };
 
+/*
+=for apidoc m|SV *|refcounted_he_fetch_pvs|const struct refcounted_he *chain|const char *key|U32 flags
+
+Like L</refcounted_he_fetch_pvn>, but takes a literal string instead of
+a string/length pair, and no precomputed hash.
+
+=cut
+*/
+
+#define refcounted_he_fetch_pvs(chain, key, flags) \
+    Perl_refcounted_he_fetch_pvn(aTHX_ chain, STR_WITH_LEN(key), 0, flags)
+
+/*
+=for apidoc m|struct refcounted_he *|refcounted_he_new_pvs|struct refcounted_he *parent|const char *key|SV *value|U32 flags
+
+Like L</refcounted_he_new_pvn>, but takes a literal string instead of
+a string/length pair, and no precomputed hash.
+
+=cut
+*/
+
+#define refcounted_he_new_pvs(parent, key, value, flags) \
+    Perl_refcounted_he_new_pvn(aTHX_ parent, STR_WITH_LEN(key), 0, value, flags)
+
 /* Flag bits are HVhek_UTF8, HVhek_WASUTF8, then */
 #define HVrhek_undef   0x00 /* Value is undef. */
 #define HVrhek_delete  0x10 /* Value is placeholder - signifies delete. */
@@ -529,6 +589,7 @@ struct refcounted_he {
 #define HV_FETCH_LVALUE                0x10
 #define HV_FETCH_JUST_SV       0x20
 #define HV_DELETE              0x40
+#define HV_FETCH_EMPTY_HE      0x80 /* Leave HeVAL null. */
 
 /*
 =for apidoc newHV