[svn:parrot] r48711 - in trunk: compilers/imcc include/parrot src src/pmc

nwellnhof at svn.parrot.org nwellnhof at svn.parrot.org
Sat Aug 28 13:14:03 UTC 2010


Author: nwellnhof
Date: Sat Aug 28 13:14:03 2010
New Revision: 48711
URL: https://trac.parrot.org/parrot/changeset/48711

Log:
Hash cleanup

- Rename hash comparison functions to something less clash-prone
- Make get_*_pmc static
- Cleanup and fix [gs]et_*_keyed functions in Hash PMC
- Fix other bugs in Hash PMC

Modified:
   trunk/compilers/imcc/pbc.c
   trunk/include/parrot/hash.h
   trunk/src/hash.c
   trunk/src/pmc/addrregistry.pmc
   trunk/src/pmc/callcontext.pmc
   trunk/src/pmc/class.pmc
   trunk/src/pmc/hash.pmc

Modified: trunk/compilers/imcc/pbc.c
==============================================================================
--- trunk/compilers/imcc/pbc.c	Sat Aug 28 11:44:33 2010	(r48710)
+++ trunk/compilers/imcc/pbc.c	Sat Aug 28 13:14:03 2010	(r48711)
@@ -363,7 +363,7 @@
         interp->code->const_table->string_hash =
             Parrot_pmc_new_init_int(interp, enum_class_Hash, enum_type_INTVAL);
         ((Hash *)VTABLE_get_pointer(interp, interp->code->const_table->string_hash))->compare =
-            (hash_comp_fn)STRING_compare_distinct_cs_enc;
+            (hash_comp_fn)hash_compare_string_distinct_enc;
 
         interp->code->const_table->constants =
             mem_gc_allocate_n_zeroed_typed(interp, newcount, PackFile_Constant);

Modified: trunk/include/parrot/hash.h
==============================================================================
--- trunk/include/parrot/hash.h	Sat Aug 28 11:44:33 2010	(r48710)
+++ trunk/include/parrot/hash.h	Sat Aug 28 13:14:03 2010	(r48711)
@@ -233,19 +233,40 @@
 Hash * parrot_new_pointer_hash(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-PARROT_CANNOT_RETURN_NULL
-PMC* get_integer_pmc(PARROT_INTERP, INTVAL value)
-        __attribute__nonnull__(1);
+PARROT_WARN_UNUSED_RESULT
+PARROT_CONST_FUNCTION
+int hash_compare_int(SHIM_INTERP,
+    ARGIN_NULLOK(const void *a),
+    ARGIN_NULLOK(const void *b));
 
-PARROT_CANNOT_RETURN_NULL
-PMC* get_number_pmc(PARROT_INTERP, FLOATVAL value)
-        __attribute__nonnull__(1);
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+int hash_compare_pmc(PARROT_INTERP, ARGIN(PMC *a), ARGIN(PMC *b))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
 
-PARROT_CANNOT_RETURN_NULL
-PMC * get_string_pmc(PARROT_INTERP, ARGIN(STRING *value))
+PARROT_WARN_UNUSED_RESULT
+PARROT_CONST_FUNCTION
+int hash_compare_pointer(SHIM_INTERP,
+    ARGIN_NULLOK(const void *a),
+    ARGIN_NULLOK(const void *b));
+
+PARROT_WARN_UNUSED_RESULT
+int hash_compare_string(PARROT_INTERP,
+    ARGIN(const void *search_key),
+    ARGIN_NULLOK(const void *bucket_key))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+PARROT_WARN_UNUSED_RESULT
+int hash_compare_string_distinct_enc(PARROT_INTERP,
+    ARGIN(const void *search_key),
+    ARGIN(const void *bucket_key))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
 PARROT_CAN_RETURN_NULL
 void* hash_key_from_int(PARROT_INTERP, ARGIN(const Hash *hash), INTVAL key)
         __attribute__nonnull__(1)
@@ -344,12 +365,6 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CONST_FUNCTION
-int int_compare(SHIM_INTERP,
-    ARGIN_NULLOK(const void *a),
-    ARGIN_NULLOK(const void *b));
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CONST_FUNCTION
 size_t key_hash_int(SHIM_INTERP,
     ARGIN_NULLOK(const void *value),
     size_t seed);
@@ -431,28 +446,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*info);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_PURE_FUNCTION
-int PMC_compare(PARROT_INTERP, ARGIN(PMC *a), ARGIN(PMC *b))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3);
-
-PARROT_WARN_UNUSED_RESULT
-int STRING_compare(PARROT_INTERP,
-    ARGIN(const void *search_key),
-    ARGIN_NULLOK(const void *bucket_key))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-int STRING_compare_distinct_cs_enc(PARROT_INTERP,
-    ARGIN(const void *search_key),
-    ARGIN(const void *bucket_key))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3);
-
 #define ASSERT_ARGS_parrot_dump_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_parrot_hash_clone __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
@@ -492,13 +485,20 @@
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_parrot_new_pointer_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_get_integer_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_get_number_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_get_string_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+#define ASSERT_ARGS_hash_compare_int __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
+#define ASSERT_ARGS_hash_compare_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(value))
+    , PARROT_ASSERT_ARG(a) \
+    , PARROT_ASSERT_ARG(b))
+#define ASSERT_ARGS_hash_compare_pointer __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
+#define ASSERT_ARGS_hash_compare_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(search_key))
+#define ASSERT_ARGS_hash_compare_string_distinct_enc \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(search_key) \
+    , PARROT_ASSERT_ARG(bucket_key))
 #define ASSERT_ARGS_hash_key_from_int __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(hash))
@@ -544,7 +544,6 @@
 #define ASSERT_ARGS_hash_value_to_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(hash))
-#define ASSERT_ARGS_int_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_key_hash_int __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_key_hash_PMC __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
@@ -578,18 +577,6 @@
 #define ASSERT_ARGS_Parrot_hash_thaw __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(info))
-#define ASSERT_ARGS_PMC_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(a) \
-    , PARROT_ASSERT_ARG(b))
-#define ASSERT_ARGS_STRING_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(search_key))
-#define ASSERT_ARGS_STRING_compare_distinct_cs_enc \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(search_key) \
-    , PARROT_ASSERT_ARG(bucket_key))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/hash.c */
 

Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c	Sat Aug 28 11:44:33 2010	(r48710)
+++ trunk/src/hash.c	Sat Aug 28 13:14:03 2010	(r48711)
@@ -35,19 +35,32 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
+static void expand_hash(PARROT_INTERP, ARGMOD(Hash *hash))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*hash);
+
+PARROT_CANNOT_RETURN_NULL
+static PMC* get_integer_pmc(PARROT_INTERP, INTVAL value)
+        __attribute__nonnull__(1);
+
+PARROT_CANNOT_RETURN_NULL
+static PMC* get_number_pmc(PARROT_INTERP, FLOATVAL value)
+        __attribute__nonnull__(1);
+
+PARROT_CANNOT_RETURN_NULL
+static PMC * get_string_pmc(PARROT_INTERP, ARGIN(STRING *value))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
-static int cstring_compare(SHIM_INTERP,
+static int hash_compare_cstring(SHIM_INTERP,
     ARGIN(const char *a),
     ARGIN(const char *b))
         __attribute__nonnull__(2)
         __attribute__nonnull__(3);
 
-static void expand_hash(PARROT_INTERP, ARGMOD(Hash *hash))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*hash);
-
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
 static size_t key_hash_cstring(SHIM_INTERP,
@@ -74,18 +87,19 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CONST_FUNCTION
-static int pointer_compare(SHIM_INTERP,
-    ARGIN_NULLOK(const void *a),
-    ARGIN_NULLOK(const void *b));
-
-#define ASSERT_ARGS_cstring_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(a) \
-    , PARROT_ASSERT_ARG(b))
 #define ASSERT_ARGS_expand_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(hash))
+#define ASSERT_ARGS_get_integer_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_get_number_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_get_string_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(value))
+#define ASSERT_ARGS_hash_compare_cstring __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(a) \
+    , PARROT_ASSERT_ARG(b))
 #define ASSERT_ARGS_key_hash_cstring __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(value))
 #define ASSERT_ARGS_key_hash_pointer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -99,7 +113,6 @@
 #define ASSERT_ARGS_parrot_mark_hash_values __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(hash))
-#define ASSERT_ARGS_pointer_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
@@ -131,8 +144,8 @@
 
 /*
 
-=item C<int STRING_compare(PARROT_INTERP, const void *search_key, const void
-*bucket_key)>
+=item C<int hash_compare_string(PARROT_INTERP, const void *search_key, const
+void *bucket_key)>
 
 Compares the two strings, returning 0 if they are identical.
 
@@ -142,9 +155,9 @@
 
 PARROT_WARN_UNUSED_RESULT
 int
-STRING_compare(PARROT_INTERP, ARGIN(const void *search_key), ARGIN_NULLOK(const void *bucket_key))
+hash_compare_string(PARROT_INTERP, ARGIN(const void *search_key), ARGIN_NULLOK(const void *bucket_key))
 {
-    ASSERT_ARGS(STRING_compare)
+    ASSERT_ARGS(hash_compare_string)
     STRING const *s1 = (STRING const *)search_key;
     STRING const *s2 = (STRING const *)bucket_key;
 
@@ -157,7 +170,7 @@
 
 /*
 
-=item C<int STRING_compare_distinct_cs_enc(PARROT_INTERP, const void
+=item C<int hash_compare_string_distinct_enc(PARROT_INTERP, const void
 *search_key, const void *bucket_key)>
 
 Compare two strings. Returns 0 if they are identical. Considers differing
@@ -167,10 +180,10 @@
 
 PARROT_WARN_UNUSED_RESULT
 int
-STRING_compare_distinct_cs_enc(PARROT_INTERP, ARGIN(const void *search_key),
+hash_compare_string_distinct_enc(PARROT_INTERP, ARGIN(const void *search_key),
                                                 ARGIN(const void *bucket_key))
 {
-    ASSERT_ARGS(STRING_compare_distinct_cs_enc)
+    ASSERT_ARGS(hash_compare_string_distinct_enc)
     STRING const *s1 = (STRING const *)search_key;
     STRING const *s2 = (STRING const *)bucket_key;
 
@@ -180,13 +193,13 @@
         return 1;
     }
 
-    return STRING_compare(interp, search_key, bucket_key);
+    return hash_compare_string(interp, search_key, bucket_key);
 }
 
 
 /*
 
-=item C<static int pointer_compare(PARROT_INTERP, const void *a, const void *b)>
+=item C<int hash_compare_pointer(PARROT_INTERP, const void *a, const void *b)>
 
 Compares the two pointers, returning 0 if they are identical
 
@@ -196,10 +209,10 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CONST_FUNCTION
-static int
-pointer_compare(SHIM_INTERP, ARGIN_NULLOK(const void *a), ARGIN_NULLOK(const void *b))
+int
+hash_compare_pointer(SHIM_INTERP, ARGIN_NULLOK(const void *a), ARGIN_NULLOK(const void *b))
 {
-    ASSERT_ARGS(pointer_compare)
+    ASSERT_ARGS(hash_compare_pointer)
     return a != b;
 }
 
@@ -261,7 +274,8 @@
 
 /*
 
-=item C<static int cstring_compare(PARROT_INTERP, const char *a, const char *b)>
+=item C<static int hash_compare_cstring(PARROT_INTERP, const char *a, const char
+*b)>
 
 Compares two C strings for equality, returning -1, 0, and 1 if the first string
 is less than, equal to, or greater than the second, respectively.
@@ -273,9 +287,9 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
 static int
-cstring_compare(SHIM_INTERP, ARGIN(const char *a), ARGIN(const char *b))
+hash_compare_cstring(SHIM_INTERP, ARGIN(const char *a), ARGIN(const char *b))
 {
-    ASSERT_ARGS(cstring_compare)
+    ASSERT_ARGS(hash_compare_cstring)
     return strcmp(a, b);
 }
 
@@ -301,7 +315,7 @@
 
 /*
 
-=item C<int PMC_compare(PARROT_INTERP, PMC *a, PMC *b)>
+=item C<int hash_compare_pmc(PARROT_INTERP, PMC *a, PMC *b)>
 
 Compares two PMC for equality, returning 0 if the first is equal to second.
 Uses void pointers to store the PMC, sadly.
@@ -313,9 +327,9 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
 int
-PMC_compare(PARROT_INTERP, ARGIN(PMC *a), ARGIN(PMC *b))
+hash_compare_pmc(PARROT_INTERP, ARGIN(PMC *a), ARGIN(PMC *b))
 {
-    ASSERT_ARGS(PMC_compare)
+    ASSERT_ARGS(hash_compare_pmc)
 
     /* If pointers are same - PMCs are same */
     if (a == b)
@@ -349,7 +363,7 @@
 
 /*
 
-=item C<int int_compare(PARROT_INTERP, const void *a, const void *b)>
+=item C<int hash_compare_int(PARROT_INTERP, const void *a, const void *b)>
 
 Compares two integers for equality, returning -1, 0, and 1 if the first is less
 than, equal to, or greater than the second, respectively.  Uses void pointers
@@ -362,9 +376,9 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CONST_FUNCTION
 int
-int_compare(SHIM_INTERP, ARGIN_NULLOK(const void *a), ARGIN_NULLOK(const void *b))
+hash_compare_int(SHIM_INTERP, ARGIN_NULLOK(const void *a), ARGIN_NULLOK(const void *b))
 {
-    ASSERT_ARGS(int_compare)
+    ASSERT_ARGS(hash_compare_int)
     return a != b;
 }
 
@@ -521,15 +535,15 @@
         switch (key_type) {
             case Hash_key_type_int:
                 key_fn = (hash_hash_key_fn)key_hash_int;
-                cmp_fn = (hash_comp_fn)int_compare;
+                cmp_fn = (hash_comp_fn)hash_compare_int;
                 break;
             case Hash_key_type_STRING:
                 key_fn = (hash_hash_key_fn)key_hash_STRING;
-                cmp_fn = (hash_comp_fn)STRING_compare;
+                cmp_fn = (hash_comp_fn)hash_compare_string;
                 break;
             case Hash_key_type_PMC:
                 key_fn = (hash_hash_key_fn)key_hash_PMC;
-                cmp_fn = (hash_comp_fn)PMC_compare;
+                cmp_fn = (hash_comp_fn)hash_compare_pmc;
                 break;
             default:
                 Parrot_ex_throw_from_c_args(interp, NULL, 1,
@@ -834,7 +848,7 @@
     return parrot_create_hash(interp,
             enum_type_PMC,
             Hash_key_type_STRING,
-            STRING_compare,
+            hash_compare_string,
             (hash_hash_key_fn)key_hash_STRING);
 }
 
@@ -858,7 +872,7 @@
     return parrot_create_hash(interp,
             enum_type_PMC,
             Hash_key_type_cstring,
-            (hash_comp_fn)cstring_compare,
+            (hash_comp_fn)hash_compare_cstring,
             (hash_hash_key_fn)key_hash_cstring);
 }
 
@@ -882,7 +896,7 @@
     return parrot_create_hash(interp,
             enum_type_ptr,
             Hash_key_type_ptr,
-            pointer_compare,
+            hash_compare_pointer,
             key_hash_pointer);
 }
 
@@ -909,7 +923,7 @@
     return parrot_create_hash(interp,
             enum_type_INTVAL,
             Hash_key_type_int,
-            int_compare,
+            hash_compare_int,
             key_hash_int);
 }
 
@@ -1141,7 +1155,7 @@
         return NULL;
 
     if (hash_val == (hash_hash_key_fn)key_hash_STRING
-    &&  compare == STRING_compare) {
+    &&  compare == hash_compare_string) {
         /* fast path for string keys */
         DECL_CONST_CAST;
         STRING * const s = (STRING *)PARROT_const_cast(void *, key);
@@ -1252,7 +1266,7 @@
     const hash_comp_fn     compare  = hash->compare;
 
     if (hash_val == (hash_hash_key_fn)key_hash_STRING
-    &&  compare == STRING_compare) {
+    &&  compare == hash_compare_string) {
         /* fast path for string keys */
         STRING *s = (STRING *)key;
 
@@ -1420,7 +1434,7 @@
 
 /*
 
-=item C<PMC* get_integer_pmc(PARROT_INTERP, INTVAL value)>
+=item C<static PMC* get_integer_pmc(PARROT_INTERP, INTVAL value)>
 
 Lookup the PMC type which is used for storing native integers.
 
@@ -1429,7 +1443,7 @@
 */
 
 PARROT_CANNOT_RETURN_NULL
-PMC*
+static PMC*
 get_integer_pmc(PARROT_INTERP, INTVAL value)
 {
     ASSERT_ARGS(get_integer_pmc)
@@ -1441,7 +1455,7 @@
 
 /*
 
-=item C<PMC* get_number_pmc(PARROT_INTERP, FLOATVAL value)>
+=item C<static PMC* get_number_pmc(PARROT_INTERP, FLOATVAL value)>
 
 Lookup the PMC type which is used for floating point numbers.
 
@@ -1450,7 +1464,7 @@
 */
 
 PARROT_CANNOT_RETURN_NULL
-PMC*
+static PMC*
 get_number_pmc(PARROT_INTERP, FLOATVAL value)
 {
     ASSERT_ARGS(get_number_pmc)
@@ -1461,7 +1475,7 @@
 
 /*
 
-=item C<PMC * get_string_pmc(PARROT_INTERP, STRING *value)>
+=item C<static PMC * get_string_pmc(PARROT_INTERP, STRING *value)>
 
 Lookup the PMC type which is used for storing strings.
 
@@ -1470,7 +1484,7 @@
 */
 
 PARROT_CANNOT_RETURN_NULL
-PMC *
+static PMC *
 get_string_pmc(PARROT_INTERP, ARGIN(STRING *value))
 {
     ASSERT_ARGS(get_string_pmc)

Modified: trunk/src/pmc/addrregistry.pmc
==============================================================================
--- trunk/src/pmc/addrregistry.pmc	Sat Aug 28 11:44:33 2010	(r48710)
+++ trunk/src/pmc/addrregistry.pmc	Sat Aug 28 13:14:03 2010	(r48711)
@@ -47,7 +47,7 @@
         Hash  *registry = parrot_create_hash(INTERP,
                 enum_type_int,
                 Hash_key_type_PMC,
-                int_compare,
+                hash_compare_int,
                 key_hash_int);
 
         SET_ATTR_hash(INTERP, SELF, registry);

Modified: trunk/src/pmc/callcontext.pmc
==============================================================================
--- trunk/src/pmc/callcontext.pmc	Sat Aug 28 11:44:33 2010	(r48710)
+++ trunk/src/pmc/callcontext.pmc	Sat Aug 28 13:14:03 2010	(r48711)
@@ -391,7 +391,7 @@
         hash = parrot_create_hash(interp,
             enum_type_ptr,
             Hash_key_type_STRING,
-            STRING_compare,
+            hash_compare_string,
             (hash_hash_key_fn)key_hash_STRING);
 
         SETATTR_CallContext_hash(interp, SELF, hash);
@@ -989,14 +989,14 @@
         else if (Parrot_str_equal(INTERP, key, CONST_STRING(INTERP, "handlers")))
             GET_ATTR_handlers(INTERP, SELF, value);
         else if (Parrot_str_equal(INTERP, key, CONST_STRING(INTERP, "current_HLL"))) {
-            /* This function from src/hash.c. */
-            /* We probably have to move it to more suitable place */
             GET_ATTR_current_HLL(INTERP, SELF, hll);
-            value = get_integer_pmc(INTERP, hll);
+            value = Parrot_pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_Integer));
+            VTABLE_set_integer_native(interp, value, hll);
         }
         else if (Parrot_str_equal(INTERP, key, CONST_STRING(INTERP, "current_hll"))) {
             GET_ATTR_current_HLL(INTERP, SELF, hll);
-            value = get_string_pmc(INTERP, Parrot_get_HLL_name(INTERP, hll));
+            value = Parrot_pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_String));
+            VTABLE_set_string_native(interp, value, Parrot_get_HLL_name(INTERP, hll));
         }
         else
             Parrot_ex_throw_from_c_args(INTERP, NULL,

Modified: trunk/src/pmc/class.pmc
==============================================================================
--- trunk/src/pmc/class.pmc	Sat Aug 28 11:44:33 2010	(r48710)
+++ trunk/src/pmc/class.pmc	Sat Aug 28 13:14:03 2010	(r48711)
@@ -151,10 +151,6 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static int pointer_compare(SHIM_INTERP,
-    ARGIN_NULLOK(const void *a),
-    ARGIN_NULLOK(const void *b));
-
 #define ASSERT_ARGS_build_attrib_index __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(self))
@@ -183,28 +179,11 @@
 #define ASSERT_ARGS_make_class_name __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(SELF))
-#define ASSERT_ARGS_pointer_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
 /*
 
-=item C<static int pointer_compare(PARROT_INTERP, const void *a, const void *b)>
-
-=cut
-
-*/
-
-static int
-pointer_compare(SHIM_INTERP, ARGIN_NULLOK(const void *a),
-    ARGIN_NULLOK(const void *b))
-{
-    ASSERT_ARGS(pointer_compare)
-    return a != b;
-}
-
-/*
-
 =item C<static size_t key_hash_pointer(PARROT_INTERP, const void *value, size_t
 seed)>
 
@@ -708,7 +687,7 @@
         _class->parent_overrides = Parrot_pmc_new(INTERP, enum_class_Hash);
         _class->isa_cache        = parrot_create_hash(INTERP,
             enum_type_INTVAL, Hash_key_type_PMC,
-            (hash_comp_fn)pointer_compare, (hash_hash_key_fn)key_hash_pointer);
+            (hash_comp_fn)hash_compare_pointer, (hash_hash_key_fn)key_hash_pointer);
 
         /* We put ourself on the all parents list. */
         VTABLE_push_pmc(INTERP, _class->all_parents, SELF);

Modified: trunk/src/pmc/hash.pmc
==============================================================================
--- trunk/src/pmc/hash.pmc	Sat Aug 28 11:44:33 2010	(r48710)
+++ trunk/src/pmc/hash.pmc	Sat Aug 28 13:14:03 2010	(r48711)
@@ -50,8 +50,61 @@
 
 /* HEADERIZER HFILE: none */
 /* HEADERIZER BEGIN: static */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+static PMC* get_next_hash(PARROT_INTERP,
+    ARGMOD(Hash *hash),
+    ARGIN(void *key))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*hash);
+
+#define ASSERT_ARGS_get_next_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(hash) \
+    , PARROT_ASSERT_ARG(key))
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
+/*
+
+=item C<void init()>
+
+Get the next hash for multipart keys. Autovivify a hash if it doesn't exist.
+
+=cut
+
+*/
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+static PMC*
+get_next_hash(PARROT_INTERP, ARGMOD(Hash *hash), ARGIN(void *key))
+{
+    PMC        *next_hash;
+    HashBucket *bucket;
+
+    if (hash->entry_type != enum_type_PMC)
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Hash entry type must be PMC for multipart keys.");
+
+    bucket = parrot_hash_get_bucket(interp, hash, key);
+
+    if (bucket) {
+        next_hash = (PMC *)bucket->value;
+    }
+    else {
+        /* autovivify a Hash */
+        next_hash = Parrot_pmc_new(interp, enum_class_Hash);
+        parrot_hash_put(interp, hash, key, next_hash);
+    }
+
+    return next_hash;
+}
+
 pmclass Hash provides hash auto_attrs {
     ATTR Hash *hash;
 
@@ -88,7 +141,7 @@
         attr->hash = parrot_create_hash(INTERP,
                 (PARROT_DATA_TYPE)value_type,
                 Hash_key_type_STRING,
-                STRING_compare,
+                hash_compare_string,
                 (hash_hash_key_fn)key_hash_STRING);
         PObj_custom_mark_destroy_SETALL(SELF);
     }
@@ -98,6 +151,7 @@
         if (hash)
             parrot_hash_destroy(INTERP, hash);
     }
+
 /*
 
 =item C<void mark()>
@@ -179,21 +233,21 @@
             new_hash = parrot_create_hash(INTERP,
                     entry_type,
                     Hash_key_type_STRING,
-                    STRING_compare,
+                    hash_compare_string,
                     (hash_hash_key_fn)key_hash_STRING);
         else if (type == Hash_key_type_int)
             /* new_int_hash set BOTH keys and values to INTVAL */
             new_hash = parrot_create_hash(INTERP,
                     entry_type,
                     Hash_key_type_int,
-                    int_compare,
+                    hash_compare_int,
                     key_hash_int);
         else if (type == Hash_key_type_PMC)
             /* new_int_hash set BOTH keys and values to INTVAL */
             new_hash = parrot_create_hash(INTERP,
                     entry_type,
                     Hash_key_type_PMC,
-                    (hash_comp_fn)PMC_compare,
+                    (hash_comp_fn)hash_compare_pmc,
                     (hash_hash_key_fn)key_hash_PMC);
         else
             /* We probably will not implement other types of keys. They are way
@@ -243,9 +297,9 @@
 
         /*
         If someone called Hash.set_pointer with NULL pointer...
-        It will create STRING* keys hash. Because we can't use STRING_compare
-        directly - it declared static in F<src/hash.c>
+        It will create STRING* keys hash.
         */
+
         if (old_hash && old_hash->entry_type == type)
             return;
 
@@ -256,7 +310,7 @@
             new_hash = parrot_create_hash(INTERP,
                         (PARROT_DATA_TYPE)type,
                         old_hash ? old_hash->key_type : Hash_key_type_STRING,
-                        old_hash ? old_hash->compare : STRING_compare,
+                        old_hash ? old_hash->compare  : hash_compare_string,
                         old_hash ? old_hash->hash_val : (hash_hash_key_fn)key_hash_STRING);
             break;
           default:
@@ -416,24 +470,25 @@
 
     /* Handling Keys */
     VTABLE INTVAL get_integer_keyed(PMC *key) {
-        const Hash * const hash = (Hash *)SELF.get_pointer();
-        HashBucket * const b = parrot_hash_get_bucket(INTERP, hash,
-                hash_key_from_pmc(INTERP, hash, key));
-        PMC        *valpmc;
-        PMC        *nextkey;
+        const Hash * const hash     = (Hash *)SELF.get_pointer();
+        const void * const hash_key = hash_key_from_pmc(INTERP, hash, key);
+        HashBucket * const b        = parrot_hash_get_bucket(INTERP, hash, hash_key);
 
         if (!b)
             return 0;
 
-        nextkey = key_next(INTERP, key);
-        valpmc  = hash_value_to_pmc(INTERP, hash, b->value);
+        key = key_next(INTERP, key);
 
         /* Stop recursion. This is last step */
-        if (!nextkey)
-            return VTABLE_get_integer(INTERP, valpmc);
+        if (!key)
+            return hash_value_to_int(INTERP, hash, b->value);
+
+        if (hash->entry_type != enum_type_PMC)
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                "Hash entry type must be PMC for multipart keys.");
 
-        /* Recusively call to enclosed aggregate */
-        return VTABLE_get_integer_keyed(INTERP, valpmc, nextkey);
+        /* Recursively call to enclosed aggregate */
+        return VTABLE_get_integer_keyed(INTERP, (PMC *)b->value, key);
     }
 
 /*
@@ -445,11 +500,8 @@
 */
 
     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
-        Hash   * const hash    = (Hash *)SELF.get_pointer();
-        void   * const keystr  = hash_key_from_pmc(INTERP, hash, key);
-        PMC    * const nextkey = key_next(INTERP, key);
-        PMC    *box;
-        HashBucket *b;
+        Hash * const hash     = (Hash *)SELF.get_pointer();
+        void * const hash_key = hash_key_from_pmc(INTERP, hash, key);
 
         if (PObj_constant_TEST(SELF)
         && !PObj_constant_TEST((PObj *)key))
@@ -457,23 +509,16 @@
                 EXCEPTION_INVALID_OPERATION,
                 "Used non-constant PMC key in constant hash.");
 
-        if (!nextkey) {
-            parrot_hash_put(INTERP, hash, keystr,
+        key = key_next(INTERP, key);
+
+        if (!key) {
+            parrot_hash_put(INTERP, hash, hash_key,
                     hash_value_from_int(INTERP, hash, value));
-            return;
         }
-
-        b = parrot_hash_get_bucket(INTERP, hash, keystr);
-        if (b)
-            box = hash_value_to_pmc(INTERP, hash, b->value);
         else {
-            /* autovivify an Hash */
-            box = Parrot_pmc_new(INTERP, SELF.type());
-            parrot_hash_put(INTERP, hash, keystr,
-                    hash_value_from_pmc(INTERP, hash, box));
+            PMC * const next_hash = get_next_hash(INTERP, hash, hash_key);
+            VTABLE_set_integer_keyed(INTERP, next_hash, key, value);
         }
-
-        VTABLE_set_integer_keyed(INTERP, box, nextkey, value);
     }
 
     VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
@@ -547,22 +592,23 @@
 
     /* I can't migrate this function right now. Some problem with JITting */
     VTABLE FLOATVAL get_number_keyed(PMC *key) {
-        PMC               *nextkey;
-        PMC               *valpmc;
-        const Hash * const hash   = (Hash *)SELF.get_pointer();
-        void       * const keystr = hash_key_from_pmc(INTERP, hash, key);
-        HashBucket * const b      = parrot_hash_get_bucket(INTERP, hash, keystr);
+        const Hash * const hash     = (Hash *)SELF.get_pointer();
+        void       * const hash_key = hash_key_from_pmc(INTERP, hash, key);
+        HashBucket * const b        = parrot_hash_get_bucket(INTERP, hash, hash_key);
 
         if (!b)
             return 0.0;
 
-        nextkey = key_next(INTERP, key);
-        valpmc  = hash_value_to_pmc(INTERP, hash, b->value);
+        key = key_next(INTERP, key);
+
+        if (!key)
+            return hash_value_to_number(INTERP, hash, b->value);
 
-        if (!nextkey)
-            return VTABLE_get_number(INTERP, valpmc);
+        if (hash->entry_type != enum_type_PMC)
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                "Hash entry type must be PMC for multipart keys.");
 
-        return VTABLE_get_number_keyed(INTERP, valpmc, nextkey);
+        return VTABLE_get_number_keyed(INTERP, (PMC *)b->value, key);
     }
 
 
@@ -609,24 +655,25 @@
 */
 
     VTABLE STRING *get_string_keyed(PMC *key) {
-        const Hash * const hash = (Hash *)SELF.get_pointer();
-        HashBucket * const b = parrot_hash_get_bucket(INTERP, hash,
-                hash_key_from_pmc(INTERP, hash, key));
-        PMC        *valpmc;
-        PMC        *nextkey;
+        const Hash * const hash     = (Hash *)SELF.get_pointer();
+        const void * const hash_key = hash_key_from_pmc(INTERP, hash, key);
+        HashBucket * const b        = parrot_hash_get_bucket(INTERP, hash, hash_key);
 
         if (!b)
             return Parrot_str_new_noinit(INTERP, enum_stringrep_one, 0);
 
-        nextkey = key_next(INTERP, key);
-        valpmc  = hash_value_to_pmc(INTERP, hash, b->value);
+        key = key_next(INTERP, key);
 
         /* Stop recursion. This is last step */
-        if (!nextkey)
-            return VTABLE_get_string(INTERP, valpmc);
+        if (!key)
+            return hash_value_to_string(INTERP, hash, b->value);
+
+        if (hash->entry_type != enum_type_PMC)
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                "Hash entry type must be PMC for multipart keys.");
 
-        /* Recusively call to enclosed aggregate */
-        return VTABLE_get_string_keyed(INTERP, valpmc, nextkey);
+        /* Recursively call to enclosed aggregate */
+        return VTABLE_get_string_keyed(INTERP, (PMC *)b->value, key);
     }
 
 /*
@@ -638,11 +685,8 @@
 */
 
     VTABLE void set_string_keyed(PMC *key, STRING *value) {
-        Hash   * const hash    = (Hash *)SELF.get_pointer();
-        void   * const keystr  = hash_key_from_pmc(INTERP, hash, key);
-        PMC    * const nextkey = key_next(INTERP, key);
-        PMC    *box;
-        HashBucket *b;
+        Hash * const hash     = (Hash *)SELF.get_pointer();
+        void * const hash_key = hash_key_from_pmc(INTERP, hash, key);
 
         if (PObj_constant_TEST(SELF)){
             if (!PObj_constant_TEST((PObj *)key))
@@ -655,23 +699,16 @@
                     "Used non-constant STRING value in constant hash.");
         }
 
-        if (!nextkey) {
-            parrot_hash_put(INTERP, hash, keystr,
+        key = key_next(INTERP, key);
+
+        if (!key) {
+            parrot_hash_put(INTERP, hash, hash_key,
                     hash_value_from_string(INTERP, hash, value));
-            return;
         }
-
-        b = parrot_hash_get_bucket(INTERP, hash, keystr);
-        if (b)
-            box = hash_value_to_pmc(INTERP, hash, b->value);
         else {
-            /* autovivify an Hash */
-            box = Parrot_pmc_new(INTERP, SELF.type());
-            parrot_hash_put(INTERP, hash, keystr,
-                    hash_value_from_pmc(INTERP, hash, box));
+            PMC * const next_hash = get_next_hash(INTERP, hash, hash_key);
+            VTABLE_set_string_keyed(INTERP, next_hash, key, value);
         }
-
-        VTABLE_set_string_keyed(INTERP, box, nextkey, value);
     }
 
 /*
@@ -696,8 +733,7 @@
                     "Used non-constant STRING value in constant hash.");
         }
 
-        parrot_hash_put(INTERP, hash,
-                hash_key_from_string(INTERP, hash, key),
+        parrot_hash_put(INTERP, hash, hash_key_from_string(INTERP, hash, key),
                 hash_value_from_string(INTERP, hash, value));
     }
 
@@ -731,14 +767,13 @@
 
     VTABLE PMC *get_pmc_keyed_str(STRING *key) {
         const Hash *hash;
-        HashBucket *b = NULL;
+        HashBucket *b;
 
         GET_ATTR_hash(INTERP, SELF, hash);
 
         /* special case the most likely key type, for speed */
-        key = hash->key_type == Hash_key_type_STRING
-            ? key
-            : (STRING *)hash_key_from_string(INTERP, hash, key);
+        if (hash->key_type != Hash_key_type_STRING)
+            key = (STRING *)hash_key_from_string(INTERP, hash, key);
 
         b = parrot_hash_get_bucket(INTERP, hash, key);
 
@@ -765,24 +800,25 @@
 
     /* Compound Key */
     VTABLE PMC *get_pmc_keyed(PMC *key) {
-        const Hash * const hash = (Hash *)SELF.get_pointer();
-        HashBucket * const b = parrot_hash_get_bucket(INTERP, hash,
-                hash_key_from_pmc(INTERP, hash, key));
-        PMC        *valpmc;
-        PMC        *nextkey;
+        const Hash * const hash     = (Hash *)SELF.get_pointer();
+        const void * const hash_key = hash_key_from_pmc(INTERP, hash, key);
+        HashBucket * const b        = parrot_hash_get_bucket(INTERP, hash, hash_key);
 
         if (!b)
             return PMCNULL;
 
-        nextkey = key_next(INTERP, key);
-        valpmc  = hash_value_to_pmc(INTERP, hash, b->value);
+        key = key_next(INTERP, key);
 
         /* Stop recursion. This is last step */
-        if (!nextkey)
-            return valpmc;
+        if (!key)
+            return hash_value_to_pmc(INTERP, hash, b->value);
 
-        /* Recusively call to enclosed aggregate */
-        return VTABLE_get_pmc_keyed(INTERP, valpmc, nextkey);
+        if (hash->entry_type != enum_type_PMC)
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                "Hash entry type must be PMC for multipart keys.");
+
+        /* Recursively call to enclosed aggregate */
+        return VTABLE_get_pmc_keyed(INTERP, (PMC *)b->value, key);
     }
 
 /*
@@ -794,11 +830,8 @@
 */
 
     VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
-        Hash   * const hash    = (Hash *)SELF.get_pointer();
-        void   * const keystr  = hash_key_from_pmc(INTERP, hash, key);
-        PMC    * const nextkey = key_next(INTERP, key);
-        PMC    *box            = PMCNULL;
-        HashBucket *b;
+        Hash * const hash     = (Hash *)SELF.get_pointer();
+        void * const hash_key = hash_key_from_pmc(INTERP, hash, key);
 
         if (PObj_constant_TEST(SELF)
         && !PObj_constant_TEST((PObj *)key))
@@ -806,21 +839,16 @@
                 EXCEPTION_INVALID_OPERATION,
                 "Used non-constant PMC key in constant hash.");
 
-        if (!nextkey) {
-            PMC * const val = get_number_pmc(INTERP, value);
-            parrot_hash_put(INTERP, hash, keystr, hash_value_from_pmc(INTERP, hash, val));
-            return;
-        }
-
-        b = parrot_hash_get_bucket(INTERP, (Hash *)SELF.get_pointer(), keystr);
-        if (b)
-            box = hash_value_to_pmc(INTERP, hash, b->value);
-
-        /* autovivify an Hash */
-        if (PMC_IS_NULL(box))
-            box = Parrot_pmc_new(INTERP, SELF.type());
+        key = key_next(INTERP, key);
 
-        VTABLE_set_number_keyed(INTERP, box, nextkey, value);
+        if (!key) {
+            parrot_hash_put(INTERP, hash, hash_key,
+                    hash_value_from_number(INTERP, hash, value));
+        }
+        else {
+            PMC * const next_hash = get_next_hash(INTERP, hash, hash_key);
+            VTABLE_set_number_keyed(INTERP, next_hash, key, value);
+        }
     }
 
 /*
@@ -834,7 +862,7 @@
 */
 
     VTABLE void set_number_keyed_str(STRING *key, FLOATVAL value) {
-        PMC * const val  = get_number_pmc(INTERP, value);
+        Hash * const hash = (Hash *)SELF.get_pointer();
 
         if (PObj_constant_TEST(SELF)
         && !PObj_constant_TEST((PObj *)key))
@@ -842,7 +870,8 @@
                 EXCEPTION_INVALID_OPERATION,
                 "Used non-constant STRING key in constant hash.");
 
-        parrot_hash_put(INTERP, (Hash *)SELF.get_pointer(), key, val);
+        parrot_hash_put(INTERP, hash, hash_key_from_string(INTERP, hash, key),
+                hash_value_from_number(INTERP, hash, value));
     }
 
 /*
@@ -854,11 +883,8 @@
 */
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
-        Hash   * const hash    = (Hash *)SELF.get_pointer();
-        void   * const keystr  = hash_key_from_pmc(INTERP, hash, key);
-        PMC    * const nextkey = key_next(INTERP, key);
-        PMC    *box;
-        HashBucket *b;
+        Hash * const hash     = (Hash *)SELF.get_pointer();
+        void * const hash_key = hash_key_from_pmc(INTERP, hash, key);
 
         if (PObj_constant_TEST(SELF)) {
             if (!PObj_constant_TEST((PObj *)key))
@@ -872,23 +898,15 @@
                     "Used non-constant PMC value in constant hash.");
         }
 
-        if (!nextkey) {
-            parrot_hash_put(INTERP, hash, keystr, value);
-            return;
-        }
+        key = key_next(INTERP, key);
 
-        b = parrot_hash_get_bucket(INTERP, hash, keystr);
-        if (b)
-            box = hash_value_to_pmc(INTERP, hash, b->value);
+        if (!key) {
+            parrot_hash_put(INTERP, hash, hash_key, value);
+        }
         else {
-            /* autovivify an Hash */
-            box = Parrot_pmc_new(INTERP, SELF.type());
-            parrot_hash_put(INTERP, hash, keystr,
-                    hash_value_from_pmc(INTERP, hash, box));
+            PMC * const next_hash = get_next_hash(INTERP, hash, hash_key);
+            VTABLE_set_pmc_keyed(INTERP, next_hash, key, value);
         }
-
-
-        VTABLE_set_pmc_keyed(INTERP, box, nextkey, value);
     }
 
 /*
@@ -960,7 +978,12 @@
         if (!key)
             return 1;
 
-        return VTABLE_exists_keyed(INTERP, hash_value_to_pmc(INTERP, h, b->value), key);
+        if (h->entry_type != enum_type_PMC)
+            Parrot_ex_throw_from_c_args(INTERP, NULL,
+                EXCEPTION_INVALID_OPERATION,
+                "Hash entry type must be PMC for multipart keys.");
+
+        return VTABLE_exists_keyed(INTERP, (PMC *)b->value, key);
     }
 
 /*
@@ -1006,9 +1029,13 @@
 
         if (!key)
             return VTABLE_defined(INTERP, hash_value_to_pmc(INTERP, h, b->value));
-        else
-            return VTABLE_defined_keyed(INTERP,
-                    hash_value_to_pmc(INTERP, h, b->value), key);
+
+        if (h->entry_type != enum_type_PMC)
+            Parrot_ex_throw_from_c_args(INTERP, NULL,
+                EXCEPTION_INVALID_OPERATION,
+                "Hash entry type must be PMC for multipart keys.");
+
+        return VTABLE_defined_keyed(INTERP, (PMC *)b->value, key);
     }
 
 /*
@@ -1045,10 +1072,17 @@
 
         key = key_next(INTERP, key);
 
-        if (!key)
+        if (!key) {
             parrot_hash_delete(INTERP, h, sx);
-        else
-            VTABLE_delete_keyed(INTERP, (PMC *)b->value, key);
+            return;
+        }
+
+        if (h->entry_type != enum_type_PMC)
+            Parrot_ex_throw_from_c_args(INTERP, NULL,
+                EXCEPTION_INVALID_OPERATION,
+                "Hash entry type must be PMC for multipart keys.");
+
+        VTABLE_delete_keyed(INTERP, (PMC *)b->value, key);
     }
 
 /*


More information about the parrot-commits mailing list