In perl.git, the branch smueller/hash_vtable has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/b0cea599b731a826e4d9d9dd3fcc2640729dc125?hp=e854d9268d27d3194e7079943a767c4d0eba4cab>

- Log -----------------------------------------------------------------
commit b0cea599b731a826e4d9d9dd3fcc2640729dc125
Author: Steffen Mueller <smuel...@cpan.org>
Date:   Wed Jan 25 20:04:44 2017 +0100

    Hash vtables: Move vtable testing hook
    
    From newHV() to sv_upgrade() because that should now literally be the
    place all hash allocations go through. (Famous last...)

M       hv.h
M       sv.c

commit aca8800db04c3ea789952e8bce3595172c7535f2
Author: Steffen Mueller <smuel...@cpan.org>
Date:   Wed Jan 25 20:04:27 2017 +0100

    Hash vtables: exists shim

M       hv.c
M       hv_vtbl.c
M       hv_vtbl.h

commit b91bd5303e753e806c60bcb4e42a2931b17f8de8
Author: Steffen Mueller <smuel...@cpan.org>
Date:   Wed Jan 25 16:19:20 2017 +0100

    Hash vtables: Add hooks for init/destroy
    
    Also implements empty hooks in the mock example of the standard hash
    implementation.

M       hv.c
M       hv_vtbl.c
M       hv_vtbl.h
M       sv.c

commit cd12cb85e6629538704c6a52e98b3626ed79a7d2
Author: Steffen Mueller <smuel...@cpan.org>
Date:   Wed Jan 25 16:16:09 2017 +0100

    Hash vtables: Regen for previous commit

M       embed.h
M       proto.h

commit 2a66f22badde96dd439c22c42c8ee61a3e33c4d3
Author: Steffen Mueller <smuel...@cpan.org>
Date:   Wed Jan 25 16:15:50 2017 +0100

    Hash vtables: Fix warning: Introduce PERL_IN_HV_VTBL_C

M       embed.fnc
M       hv_vtbl.c
-----------------------------------------------------------------------

Summary of changes:
 embed.fnc |  4 +++-
 embed.h   |  4 +++-
 hv.c      |  8 +++++++-
 hv.h      |  4 +---
 hv_vtbl.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 hv_vtbl.h | 15 +++++++++++++++
 proto.h   |  4 +++-
 sv.c      | 14 ++++++++++++--
 8 files changed, 94 insertions(+), 10 deletions(-)

diff --git a/embed.fnc b/embed.fnc
index d6fc6c4bfd..a48851d8c7 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -2083,10 +2083,12 @@ rs      |void   |hv_notallowed  |int flags|NN const 
char *key|I32 klen|NN const char *ms
 in     |U32|ptr_hash|PTRV u
 s      |struct xpvhv_aux*|hv_auxinit|NN HV *hv
 sn     |struct xpvhv_aux*|hv_auxinit_internal|NN struct xpvhv_aux *iter
+sM     |void   |clear_placeholders     |NN HV *hv|U32 items
+#endif
+#if defined(PERL_IN_HV_C) || defined(PERL_IN_SV_C) || 
defined(PERL_IN_HV_VTBL_C)
 pM     |SV*    |hv_delete_common|NULLOK HV *hv|NULLOK SV *keysv \
                |NULLOK const char *key|STRLEN klen|int k_flags|I32 d_flags \
                |U32 hash
-sM     |void   |clear_placeholders     |NN HV *hv|U32 items
 #endif
 
 #if defined(PERL_IN_MG_C)
diff --git a/embed.h b/embed.h
index 530f93a6f4..8df48650f0 100644
--- a/embed.h
+++ b/embed.h
@@ -1576,7 +1576,6 @@
 #define hsplit(a,b,c)          S_hsplit(aTHX_ a,b,c)
 #define hv_auxinit(a)          S_hv_auxinit(aTHX_ a)
 #define hv_auxinit_internal    S_hv_auxinit_internal
-#define hv_delete_common(a,b,c,d,e,f,g)        Perl_hv_delete_common(aTHX_ 
a,b,c,d,e,f,g)
 #define hv_free_ent_ret(a,b)   S_hv_free_ent_ret(aTHX_ a,b)
 #define hv_magic_check         S_hv_magic_check
 #define hv_notallowed(a,b,c,d) S_hv_notallowed(aTHX_ a,b,c,d)
@@ -1587,6 +1586,9 @@
 #define share_hek_flags(a,b,c,d)       S_share_hek_flags(aTHX_ a,b,c,d)
 #define unshare_hek_or_pvn(a,b,c,d)    S_unshare_hek_or_pvn(aTHX_ a,b,c,d)
 #  endif
+#  if defined(PERL_IN_HV_C) || defined(PERL_IN_SV_C) || 
defined(PERL_IN_HV_VTBL_C)
+#define hv_delete_common(a,b,c,d,e,f,g)        Perl_hv_delete_common(aTHX_ 
a,b,c,d,e,f,g)
+#  endif
 #  if defined(PERL_IN_LOCALE_C) || defined(PERL_IN_SV_C) || 
defined(PERL_IN_MATHOMS_C)
 #    if defined(USE_LOCALE_COLLATE)
 #define _mem_collxfrm(a,b,c,d) Perl__mem_collxfrm(aTHX_ a,b,c,d)
diff --git a/hv.c b/hv.c
index ab97d09624..d5f6b51dd7 100644
--- a/hv.c
+++ b/hv.c
@@ -229,13 +229,15 @@ hash type (thus C<newHV_type(NULL)> is equivalent to 
C<newHV()>.
 HV *
 Perl_newHV_type(pTHX_ HV_VTBL *type)
 {
-
     /*HV *hv = newHV();*/
     /* FIXME just temporary for testing: */
     HV *hv = MUTABLE_HV(newSV_type(SVt_PVHV));
 
     XPVHV *xhv = (XPVHV*)SvANY(hv);
     xhv->xhv_vtbl = type;
+
+    type->hvt_init(aTHX_ hv);
+
     return hv;
 }
 
@@ -432,6 +434,10 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, 
STRLEN klen,
            return (void *)vtable->hvt_delete(hv, keysv, key, klen,
                                                flags, action, hash);
         }
+        else if (action & HV_FETCH_ISEXISTS) {
+           return (void *)vtable->hvt_exists(hv, keysv, key, klen,
+                                               flags, hash);
+        }
     }
 
     if (action & HV_DELETE) {
diff --git a/hv.h b/hv.h
index a80a135971..a7ccc6b685 100644
--- a/hv.h
+++ b/hv.h
@@ -655,9 +655,7 @@ Creates a new HV.  The reference count is set to 1.
 */
 
 /* regular newHV implementation */
-/*#define newHV()      MUTABLE_HV(newSV_type(SVt_PVHV))*/
-/* FIXME just temporary for testing: newHV implementation for testing the 
no-op vtable logic */
-#define newHV()        ({ HV *_p = newHV_type(&PL_mock_std_vtable); _p; })
+#define newHV()        MUTABLE_HV(newSV_type(SVt_PVHV))
 
 #include "hv_func.h"
 
diff --git a/hv_vtbl.c b/hv_vtbl.c
index dc6370dc1f..6266b96ccc 100644
--- a/hv_vtbl.c
+++ b/hv_vtbl.c
@@ -10,10 +10,24 @@
 /* TODO: Insert LotR quote here. */
 
 #include "EXTERN.h"
-#define PERL_IN_HV_C
+#define PERL_IN_HV_VTBL_C
 #define PERL_HASH_INTERNAL_ACCESS
 #include "perl.h"
 
+STATIC void
+S_hv_mock_std_vtable_init(pTHX_ HV *hv)
+{
+    PERL_UNUSED_CONTEXT;
+    PERL_UNUSED_ARG(hv);
+}
+
+STATIC void
+S_hv_mock_std_vtable_destroy(pTHX_ HV *hv)
+{
+    PERL_UNUSED_CONTEXT;
+    PERL_UNUSED_ARG(hv);
+}
+
 STATIC SV *
 S_hv_mock_std_vtable_delete(pTHX_ HV *hv, SV *keysv, const char *key,
                             STRLEN klen, int key_flags, I32 delete_flags,
@@ -23,7 +37,42 @@ S_hv_mock_std_vtable_delete(pTHX_ HV *hv, SV *keysv, const 
char *key,
                            key_flags, delete_flags, hash);
 }
 
+/*
+STATIC SV **
+S_hv_mock_std_vtable_fetch(pTHX_ HV *hv, SV *keysv, const char *key,
+                            STRLEN klen, int key_flags,
+                            I32 is_lvalue_fetch, U32 hash)
+{
+    return NULL;
+}
+*/
+
+STATIC bool
+S_hv_mock_std_vtable_exists(pTHX_ HV *hv, SV *keysv, const char *key,
+                            STRLEN klen, int key_flags, U32 hash)
+{
+    /* THIS IS PURELY FOR TESTING! */
+    bool retval;
+    XPVHV* xhv = (XPVHV *)SvANY(hv);
+    HV_VTBL *vtable = xhv->xhv_vtbl;
+    ENTER;
+    SAVEPPTR(vtable);
+    xhv->xhv_vtbl = NULL;
+    if (keysv)
+        retval = hv_exists_ent(hv, keysv, hash);
+    else {
+        I32 my_klen = (key_flags & HVhek_UTF8) ? -(I32)klen : (I32)klen;
+        retval = hv_exists(hv, key, my_klen);
+    }
+    LEAVE;
+    return retval;
+}
+
 HV_VTBL PL_mock_std_vtable = {
+        S_hv_mock_std_vtable_init,
+        S_hv_mock_std_vtable_destroy,
+        /* S_hv_mock_std_vtable_fetch, */
+        S_hv_mock_std_vtable_exists,
        S_hv_mock_std_vtable_delete
 };
 
diff --git a/hv_vtbl.h b/hv_vtbl.h
index 18f8be3487..39558182e1 100644
--- a/hv_vtbl.h
+++ b/hv_vtbl.h
@@ -8,7 +8,22 @@
  */
 
 struct hv_vtbl {
+    /* Called when allocating a new HV of this type */
+    void       (*hvt_init)(pTHX_ HV *hv);
+    /* Called before deallocating the HV in the traditional HV implementation. 
*/
+    void       (*hvt_destroy)(pTHX_ HV *hv);
+
+    /* Implements the various forms of hv_fetch/etc */
+    /* SV **   (*hvt_fetch)(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN 
klen, int key_flags, I32 is_lvalue_fetch, U32 hash); */
+
+    /* store */
+
+    /* exists */
+    bool       (*hvt_exists)(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN 
klen, int key_flags, U32 hash);
+
+    /* Implements the various forms of hv_delete/etc */
     SV *       (*hvt_delete)(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN 
klen, int key_flags, I32 delete_flags, U32 hash);
+    /* clear */
 };
 typedef struct hv_vtbl HV_VTBL;
 
diff --git a/proto.h b/proto.h
index ad804aa8d1..679f960070 100644
--- a/proto.h
+++ b/proto.h
@@ -4443,7 +4443,6 @@ STATIC struct xpvhv_aux*  S_hv_auxinit(pTHX_ HV *hv);
 STATIC struct xpvhv_aux*       S_hv_auxinit_internal(struct xpvhv_aux *iter);
 #define PERL_ARGS_ASSERT_HV_AUXINIT_INTERNAL   \
        assert(iter)
-PERL_CALLCONV SV*      Perl_hv_delete_common(pTHX_ HV *hv, SV *keysv, const 
char *key, STRLEN klen, int k_flags, I32 d_flags, U32 hash);
 STATIC SV*     S_hv_free_ent_ret(pTHX_ HV *hv, HE *entry);
 #define PERL_ARGS_ASSERT_HV_FREE_ENT_RET       \
        assert(hv); assert(entry)
@@ -4485,6 +4484,9 @@ PERL_CALLCONV SV* Perl_hfree_next_entry(pTHX_ HV *hv, 
STRLEN *indexp);
 #define PERL_ARGS_ASSERT_HFREE_NEXT_ENTRY      \
        assert(hv); assert(indexp)
 #endif
+#if defined(PERL_IN_HV_C) || defined(PERL_IN_SV_C) || 
defined(PERL_IN_HV_VTBL_C)
+PERL_CALLCONV SV*      Perl_hv_delete_common(pTHX_ HV *hv, SV *keysv, const 
char *key, STRLEN klen, int k_flags, I32 d_flags, U32 hash);
+#endif
 #if defined(PERL_IN_LOCALE_C) || defined(PERL_IN_SV_C) || 
defined(PERL_IN_MATHOMS_C)
 #  if defined(USE_LOCALE_COLLATE)
 PERL_CALLCONV char*    Perl__mem_collxfrm(pTHX_ const char* input_string, 
STRLEN len, STRLEN* xlen, bool utf8);
diff --git a/sv.c b/sv.c
index 42e34410ed..964321908b 100644
--- a/sv.c
+++ b/sv.c
@@ -1370,6 +1370,8 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type)
 #endif
             /* start with PERL_HASH_DEFAULT_HvMAX+1 buckets: */
            HvMAX(sv) = PERL_HASH_DEFAULT_HvMAX;
+            /* FIXME just temporary for testing: newHV implementation for 
testing the no-op vtable logic */
+            ((XPVHV*)  SvANY(sv))->xhv_vtbl = &PL_mock_std_vtable;
        }
 
        /* SVt_NULL isn't the only thing upgraded to AV or HV.
@@ -6564,10 +6566,18 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
                if (!curse(sv, 1)) goto get_next_sv;
                type = SvTYPE(sv); /* destructor may have changed it */
            }
-           /* Free back-references before magic, in case the magic calls
-            * Perl code that has weak references to sv. */
            if (type == SVt_PVHV) {
+                HV_VTBL *vtbl;
+                HV *hv = MUTABLE_HV(sv);
+
+                /* Free back-references before magic, in case the magic calls
+                 * Perl code that has weak references to sv. */
                Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
+                /* TODO: Before or after invoking magic on the HV?
+                 *       I think before. */
+                vtbl = ( (XPVHV*)SvANY(hv) )->xhv_vtbl;
+                if (vtbl != NULL)
+                    vtbl->hvt_destroy(aTHX_ hv);
                if (SvMAGIC(sv))
                    mg_free(sv);
            }

--
Perl5 Master Repository

Reply via email to