[svn:parrot] r41852 - in branches/pcc_optimize_sig: src/pmc t/pmc

chromatic at svn.parrot.org chromatic at svn.parrot.org
Wed Oct 14 08:37:51 UTC 2009


Author: chromatic
Date: Wed Oct 14 08:37:49 2009
New Revision: 41852
URL: https://trac.parrot.org/parrot/changeset/41852

Log:
[PMC] Gave CallSignature PMC its own hash component and removed its inheritance
from Capture PMC.
Added tests for keyed access.
Fixed mark() and destroy() vtable entries for named arguments.
Made 'named' attribute access of CallSignature return a FixedStringArray
of all named arguments.

Modified:
   branches/pcc_optimize_sig/src/pmc/callsignature.pmc
   branches/pcc_optimize_sig/t/pmc/callsignature.t

Modified: branches/pcc_optimize_sig/src/pmc/callsignature.pmc
==============================================================================
--- branches/pcc_optimize_sig/src/pmc/callsignature.pmc	Wed Oct 14 07:02:00 2009	(r41851)
+++ branches/pcc_optimize_sig/src/pmc/callsignature.pmc	Wed Oct 14 08:37:49 2009	(r41852)
@@ -30,14 +30,6 @@
     struct Pcc_cell *next;
 } Pcc_cell;
 
-#define CAPTURE_DATA_SIZE   2
-#define CAPTURE_array_CREATE(i, obj) \
-    if (!PARROT_CAPTURE(obj)->array) \
-        PARROT_CAPTURE(obj)->array = pmc_new((i), enum_class_ResizablePMCArray);
-#define CAPTURE_hash_CREATE(i, obj) \
-    if (!PARROT_CAPTURE(obj)->hash) \
-        PARROT_CAPTURE(obj)->hash = pmc_new((i), enum_class_Hash);
-
 /* mask off lower three bits for pointer tag */
 #define UNTAG_CELL(c) INTVAL2PTR(Pcc_cell *, (PTR2INTVAL(c)) & ~3)
 
@@ -55,17 +47,25 @@
 #define STRINGCELL 2
 #define PMCCELL    3
 
-#define CREATE_INTVAL_CELL \
-    INTVAL2PTR(Pcc_cell *, PTR2INTVAL(mem_allocate_zeroed_typed(Pcc_cell)) | INTCELL)
+#define SET_CELL_INT(c) \
+        INTVAL2PTR(Pcc_cell *, PTR2INTVAL(UNTAG_CELL(c)) | INTCELL)
+
+#define SET_CELL_FLOAT(c) \
+        INTVAL2PTR(Pcc_cell *, PTR2INTVAL(UNTAG_CELL(c)) | FLOATCELL)
+
+#define SET_CELL_STRING(c) \
+        INTVAL2PTR(Pcc_cell *, PTR2INTVAL(UNTAG_CELL(c)) | STRINGCELL)
+
+#define SET_CELL_PMC(c) \
+        INTVAL2PTR(Pcc_cell *, PTR2INTVAL(UNTAG_CELL(c)) | PMCCELL)
+
+#define CREATE_INTVAL_CELL   SET_CELL_INT(mem_allocate_zeroed_typed(Pcc_cell))
 
-#define CREATE_FLOATVAL_CELL \
-    INTVAL2PTR(Pcc_cell *, (PTR2INTVAL(mem_allocate_zeroed_typed(Pcc_cell)) | FLOATCELL))
+#define CREATE_FLOATVAL_CELL SET_CELL_FLOAT(mem_allocate_zeroed_typed(Pcc_cell))
 
-#define CREATE_STRING_CELL \
-    INTVAL2PTR(Pcc_cell *, PTR2INTVAL(mem_allocate_zeroed_typed(Pcc_cell)) | STRINGCELL)
+#define CREATE_STRING_CELL   SET_CELL_STRING(mem_allocate_zeroed_typed(Pcc_cell))
 
-#define CREATE_PMC_CELL \
-    INTVAL2PTR(Pcc_cell *, PTR2INTVAL(mem_allocate_zeroed_typed(Pcc_cell)) | PMCCELL)
+#define CREATE_PMC_CELL      SET_CELL_PMC(mem_allocate_zeroed_typed(Pcc_cell))
 
 #define APPEND_CELL(SELF, cell) \
     do { \
@@ -238,7 +238,7 @@
 static PMC *
 autobox_pmc(PARROT_INTERP, Pcc_cell *cell)
 {
-    PMC *result;
+    PMC *result = PMCNULL;
 
     /* TODO: respect HLL types? */
     switch (CELL_TYPE_MASK(cell)) {
@@ -264,13 +264,93 @@
     return result;
 }
 
-pmclass CallSignature extends Capture auto_attrs provides array provides hash {
+static Hash *
+get_hash(PARROT_INTERP, ARGIN(PMC *SELF))
+{
+    Parrot_CallSignature_attributes * const attrs = PARROT_CALLSIGNATURE(SELF);
+
+    if (!attrs->hash)
+        attrs->hash = parrot_new_hash(interp);
+
+    return attrs->hash;
+}
+
+static void
+mark_positionals(PARROT_INTERP, ARGIN(Pcc_cell *c))
+{
+    while (c) {
+        switch (CELL_TYPE_MASK(c)) {
+            case STRINGCELL:
+                if (CELL_STRING(c))
+                    Parrot_gc_mark_STRING_alive(interp, CELL_STRING(c));
+                break;
+            case PMCCELL:
+                if (!PMC_IS_NULL(CELL_PMC(c)))
+                    Parrot_gc_mark_PMC_alive(interp, CELL_PMC(c));
+                break;
+            case INTCELL:
+            case FLOATCELL:
+            default:
+                break;
+        }
+
+        c = NEXT_CELL(c);
+    }
+}
+
+/* don't look now, but here goes encapsulation.... */
+static void
+mark_hash(PARROT_INTERP, ARGIN(Hash *h))
+{
+    UINTVAL entries = h->entries;
+    INTVAL  i;
+
+    for (i = h->mask; i >= 0; --i) {
+        HashBucket *b = h->bi[i];
+
+        while (b) {
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)b->key);
+            mark_positionals(interp, (Pcc_cell *)b->value);
+        }
+
+        b = b->next;
+    }
+}
+
+static PMC *
+get_named_names(PARROT_INTERP, ARGIN(PMC *SELF))
+{
+    Parrot_CallSignature_attributes * const attrs = PARROT_CALLSIGNATURE(SELF);
+    PMC *result = PMCNULL;
+
+    /* yes, this *looks* risky, but it's a Parrot STRING hash internally */
+    if (attrs->hash && attrs->hash->entries) {
+        UINTVAL i, j = 0;
+        result  = pmc_new(interp, enum_class_FixedStringArray);
+        VTABLE_set_integer_native(interp, result, attrs->hash->entries);
+
+        for (i = 0; i <= attrs->hash->mask; i++) {
+            HashBucket *b = attrs->hash->bi[i];
+
+            while (b) {
+                VTABLE_set_string_keyed_int(interp, result,
+                    j++, (STRING *)b->key);
+                b = b->next;
+            }
+        }
+    }
+
+    return result;
+}
+
+pmclass CallSignature auto_attrs provides array provides hash {
     ATTR struct Pcc_cell *positionals; /* linked list of positionals */
     ATTR PMC    *results;              /* Storage for return arguments */
     ATTR PMC    *type_tuple;           /* Cached argument types for MDD */
     ATTR STRING *short_sig;            /* Simple string sig args & returns */
     ATTR PMC    *arg_flags;            /* Integer array of argument flags */
     ATTR PMC    *return_flags;         /* Integer array of return flags */
+    ATTR Hash   *hash;                 /* Hash of named arguments */
     ATTR INTVAL  num_positionals;      /* count of positionals */
 
 /*
@@ -461,7 +541,7 @@
             GET_ATTR_return_flags(interp, SELF, value);
         }
         else if (Parrot_str_equal(INTERP, key, CONST_STRING(INTERP, "named"))) {
-            GET_ATTR_hash(interp, SELF, value);
+            value = get_named_names(INTERP, SELF);
         }
         else {
             /* If unknown attribute name, throw an exception. */
@@ -491,29 +571,12 @@
         Parrot_gc_mark_STRING_alive(interp, attrs->short_sig);
         Parrot_gc_mark_PMC_alive(interp, attrs->arg_flags);
         Parrot_gc_mark_PMC_alive(interp, attrs->return_flags);
-        SUPER();
 
-        if (attrs->num_positionals) {
-            Pcc_cell *c = attrs->positionals;
-            while (c) {
-                switch (CELL_TYPE_MASK(c)) {
-                    case STRINGCELL:
-                        if (CELL_STRING(c))
-                            Parrot_gc_mark_STRING_alive(interp, CELL_STRING(c));
-                        break;
-                    case PMCCELL:
-                        if (!PMC_IS_NULL(CELL_PMC(c)))
-                            Parrot_gc_mark_PMC_alive(interp, CELL_PMC(c));
-                        break;
-                    case INTCELL:
-                    case FLOATCELL:
-                    default:
-                        break;
-                }
+        if (attrs->num_positionals)
+            mark_positionals(interp, attrs->positionals);
 
-                c = NEXT_CELL(c);
-            }
-        }
+        if (attrs->hash)
+            mark_hash(interp, attrs->hash);
     }
 
     VTABLE void destroy() {
@@ -530,6 +593,21 @@
                 FREE_CELL(to_free);
             }
         }
+
+        if (attrs->hash) {
+            UINTVAL i;
+
+            for (i = 0; i <= attrs->hash->mask; i++) {
+                HashBucket *b = attrs->hash->bi[i];
+
+                while (b) {
+                    FREE_CELL((Pcc_cell *)b->value);
+                    b = b->next;
+                }
+            }
+
+            parrot_hash_destroy(interp, attrs->hash);
+        }
     }
 
     VTABLE INTVAL elements () {
@@ -785,6 +863,178 @@
         CELL_PMC(cell) = value;
     }
 
+    VTABLE void set_integer_keyed_str(STRING *key, INTVAL value) {
+        Hash     *hash = get_hash(interp, SELF);
+        Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, (void *)key);
+
+        if (!cell) {
+            cell = CREATE_INTVAL_CELL;
+            parrot_hash_put(interp, hash, (void *)key, (void *)cell);
+        }
+        else
+            SET_CELL_INT(cell);
+
+        CELL_INT(cell) = value;
+    }
+
+    VTABLE void set_number_keyed_str(STRING *key, FLOATVAL value) {
+        Hash     *hash = get_hash(interp, SELF);
+        Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, (void *)key);
+
+        if (!cell) {
+            cell = CREATE_FLOATVAL_CELL;
+            parrot_hash_put(interp, hash, (void *)key, (void *)cell);
+        }
+        else
+            SET_CELL_FLOAT(cell);
+
+        CELL_FLOAT(cell) = value;
+    }
+
+    VTABLE void set_string_keyed_str(STRING *key, STRING *value) {
+        Hash     *hash = get_hash(interp, SELF);
+        Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, (void *)key);
+
+        if (!cell) {
+            cell = CREATE_STRING_CELL;
+            parrot_hash_put(interp, hash, (void *)key, (void *)cell);
+        }
+        else
+            SET_CELL_STRING(cell);
+
+        CELL_STRING(cell) = value;
+    }
+
+    VTABLE void set_pmc_keyed_str(STRING *key, PMC *value) {
+        Hash     *hash = get_hash(interp, SELF);
+        Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, (void *)key);
+
+        if (!cell) {
+            cell = CREATE_PMC_CELL;
+            parrot_hash_put(interp, hash, (void *)key, (void *)cell);
+        }
+        else
+            SET_CELL_PMC(cell);
+
+        CELL_PMC(cell) = value;
+    }
+
+    VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
+        Hash     *hash = get_hash(interp, SELF);
+        void     *k    = hash_key_from_pmc(interp, hash, key);
+        Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, k);
+
+        if (!cell) {
+            cell = CREATE_INTVAL_CELL;
+            parrot_hash_put(interp, hash, k, (void *)cell);
+        }
+        else
+            SET_CELL_INT(cell);
+
+        CELL_INT(cell) = value;
+    }
+
+    VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
+        Hash     *hash = get_hash(interp, SELF);
+        void     *k    = hash_key_from_pmc(interp, hash, key);
+        Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, k);
+
+        if (!cell) {
+            cell = CREATE_FLOATVAL_CELL;
+            parrot_hash_put(interp, hash, k, (void *)cell);
+        }
+        else
+            SET_CELL_FLOAT(cell);
+
+        CELL_FLOAT(cell) = value;
+    }
+
+    VTABLE void set_string_keyed(PMC *key, STRING *value) {
+        Hash     *hash = get_hash(interp, SELF);
+        void     *k    = hash_key_from_pmc(interp, hash, key);
+        Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, k);
+
+        if (!cell) {
+            cell = CREATE_STRING_CELL;
+            parrot_hash_put(interp, hash, k, (void *)cell);
+        }
+        else
+            SET_CELL_STRING(cell);
+
+        CELL_STRING(cell) = value;
+    }
+
+    VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
+        Hash     *hash = get_hash(interp, SELF);
+        void     *k    = hash_key_from_pmc(interp, hash, key);
+        Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, k);
+
+        if (!cell) {
+            cell = CREATE_PMC_CELL;
+            parrot_hash_put(interp, hash, k, (void *)cell);
+        }
+        else
+            SET_CELL_PMC(cell);
+
+        CELL_PMC(cell) = value;
+    }
+
+    VTABLE INTVAL get_integer_keyed(PMC *key) {
+        Hash *hash = get_hash(interp, SELF);
+
+        if (hash) {
+            void     *k    = hash_key_from_pmc(interp, hash, key);
+            Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, k);
+
+            if (cell)
+                return autobox_intval(interp, cell);
+        }
+
+        return 0;
+    }
+
+    VTABLE FLOATVAL get_number_keyed(PMC *key) {
+        Hash *hash = get_hash(interp, SELF);
+
+        if (hash) {
+            void     *k    = hash_key_from_pmc(interp, hash, key);
+            Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, k);
+
+            if (cell)
+                return autobox_floatval(interp, cell);
+        }
+
+        return 0.0;
+    }
+
+    VTABLE STRING * get_string_keyed(PMC *key) {
+        Hash *hash = get_hash(interp, SELF);
+
+        if (hash) {
+            void     *k    = hash_key_from_pmc(interp, hash, key);
+            Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, k);
+
+            if (cell)
+                return autobox_string(interp, cell);
+        }
+
+        return NULL;
+    }
+
+    VTABLE PMC * get_pmc_keyed(PMC *key) {
+        Hash *hash = get_hash(interp, SELF);
+
+        if (hash) {
+            void     *k    = hash_key_from_pmc(interp, hash, key);
+            Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(interp, hash, k);
+
+            if (cell)
+                return autobox_pmc(interp, cell);
+        }
+
+        return PMCNULL;
+    }
+
 /*
 
 =back

Modified: branches/pcc_optimize_sig/t/pmc/callsignature.t
==============================================================================
--- branches/pcc_optimize_sig/t/pmc/callsignature.t	Wed Oct 14 07:02:00 2009	(r41851)
+++ branches/pcc_optimize_sig/t/pmc/callsignature.t	Wed Oct 14 08:37:49 2009	(r41852)
@@ -19,7 +19,7 @@
 .sub 'main' :main
     .include 'test_more.pir'
 
-    plan(56)
+    plan(61)
 
     test_instantiate()
     test_get_set_attrs()
@@ -27,6 +27,7 @@
     test_shift_unshift_indexed_access()
     test_indexed_access()
     test_indexed_boxing()
+    test_keyed_access()
 .end
 
 .sub 'test_instantiate'
@@ -236,6 +237,34 @@
     is( $P1, 2.22, 'indexed string converted to PMC on get_pmc_keyed_int' )
 .end
 
+.sub 'test_keyed_access'
+    $P0        = new [ 'CallSignature' ]
+
+    $P0['foo'] = 100
+    $P0['bar'] = 1.11
+    $P0['baz'] = '2.22'
+    $P1        = new [ 'Float' ]
+    $P1        = 3.33
+
+    $P0['qux'] = $P1
+
+    $I0 = $P0['foo']
+    is( $I0, 100, 'set/get_intval_keyed_str' )
+
+    $N0 = $P0['bar']
+    is( $N0, 1.11, 'set/get_number_keyed_str' )
+
+    $S0 = $P0['baz']
+    is( $S0, '2.22', 'set/get_string_keyed_str' )
+
+    $P2 = $P0['qux']
+    is( $P2, 3.33, 'set/get_pmc_keyed_str' )
+
+    $P1 = getattribute $P0, 'named'
+    $I0 = elements $P1
+    is( $I0, 4, 'elements after set_*_keyed' )
+.end
+
 # Local Variables:
 #   mode: pir
 #   fill-column: 100


More information about the parrot-commits mailing list