[svn:parrot] r45023 - in branches/pcc_hackathon_6Mar10: src/pmc t/pmc

bacek at svn.parrot.org bacek at svn.parrot.org
Thu Mar 18 20:12:59 UTC 2010


Author: bacek
Date: Thu Mar 18 20:12:58 2010
New Revision: 45023
URL: https://trac.parrot.org/parrot/changeset/45023

Log:
Merge branch 'pcc_mergecells_local' into pcc_returns

Modified:
   branches/pcc_hackathon_6Mar10/src/pmc/callcontext.pmc
   branches/pcc_hackathon_6Mar10/t/pmc/callcontext.t

Modified: branches/pcc_hackathon_6Mar10/src/pmc/callcontext.pmc
==============================================================================
--- branches/pcc_hackathon_6Mar10/src/pmc/callcontext.pmc	Thu Mar 18 20:01:58 2010	(r45022)
+++ branches/pcc_hackathon_6Mar10/src/pmc/callcontext.pmc	Thu Mar 18 20:12:58 2010	(r45023)
@@ -27,161 +27,75 @@
         INTVAL   i;
         FLOATVAL n;
     } u;
-    struct Pcc_cell *next;
+    INTVAL type;
 } Pcc_cell;
 
 /* mask off lower two bits (1 + 2 = 3) for pointer tags */
-#define TAG_BITS 3
-#define UNTAG_CELL(c) INTVAL2PTR(Pcc_cell *, (PTR2INTVAL(c)) & ~TAG_BITS)
+#define NOCELL     0
+#define INTCELL    1
+#define FLOATCELL  2
+#define STRINGCELL 3
+#define PMCCELL    4
 
-#define CELL_INT(c)     UNTAG_CELL(c)->u.i
-#define CELL_FLOAT(c)   UNTAG_CELL(c)->u.n
-#define CELL_STRING(c)  UNTAG_CELL(c)->u.s
-#define CELL_PMC(c)     UNTAG_CELL(c)->u.p
+#define ALLOC_CELL(i) \
+    (Pcc_cell *)Parrot_gc_allocate_fixed_size_storage((i), sizeof (Pcc_cell))
 
-#define NEXT_CELL(c) UNTAG_CELL(c)->next
 #define FREE_CELL(i, c) \
-    Parrot_gc_free_fixed_size_storage((i), sizeof (Pcc_cell), (UNTAG_CELL(c)))
-
-#define CELL_TYPE_MASK(c) (PTR2INTVAL(c)) & 3
-#define INTCELL    0
-#define FLOATCELL  1
-#define STRINGCELL 2
-#define PMCCELL    3
+    Parrot_gc_free_fixed_size_storage((i), sizeof (Pcc_cell), c)
 
-#define ALLOC_CELL(i) \
-    (Pcc_cell *)Parrot_gc_allocate_fixed_size_storage((i), sizeof (Pcc_cell))
+#define CELL_TYPE_MASK(c) (c)->type
 
-#define INIT_CELL_INT(c)    INTVAL2PTR(Pcc_cell *, PTR2INTVAL(c) | INTCELL)
-#define INIT_CELL_FLOAT(c)  INTVAL2PTR(Pcc_cell *, PTR2INTVAL(c) | FLOATCELL)
-#define INIT_CELL_STRING(c) INTVAL2PTR(Pcc_cell *, PTR2INTVAL(c) | STRINGCELL)
-#define INIT_CELL_PMC(c)    INTVAL2PTR(Pcc_cell *, PTR2INTVAL(c) | PMCCELL)
-
-#define CREATE_INTVAL_CELL(i)   INIT_CELL_INT(ALLOC_CELL(i))
-
-#define CREATE_FLOATVAL_CELL(i) INIT_CELL_FLOAT(ALLOC_CELL(i))
-
-#define CREATE_STRING_CELL(i)   INIT_CELL_STRING(ALLOC_CELL(i))
-
-#define CREATE_PMC_CELL(i)      INIT_CELL_PMC(ALLOC_CELL(i))
-
-#define APPEND_CELL(i, obj, cell) \
-    do { \
-        INTVAL num_positionals; \
-        Pcc_cell *positionals; \
-        GETATTR_CallContext_num_positionals((i), (obj), num_positionals); \
-        GETATTR_CallContext_positionals((i), (obj), positionals); \
-        SETATTR_CallContext_num_positionals((i), (obj), num_positionals+1); \
-        NEXT_CELL(cell) = NULL; \
-        if (positionals) { \
-            while (NEXT_CELL(positionals)) { \
-                positionals = NEXT_CELL(positionals); \
-            } \
-            NEXT_CELL(positionals) = (cell); \
-        } \
-        else \
-            SETATTR_CallContext_positionals((i), (obj), (cell)); \
-    } while (0)
-
-#define PREPEND_CELL(i, obj, cell) \
-    do { \
-        INTVAL num_positionals; \
-        Pcc_cell *positionals; \
-        GETATTR_CallContext_num_positionals((i), (obj), num_positionals); \
-        GETATTR_CallContext_positionals((i), (obj), positionals); \
-        SETATTR_CallContext_num_positionals((i), (obj), num_positionals+1); \
-        NEXT_CELL(cell) = positionals; \
-        SETATTR_CallContext_positionals((i), (obj), (cell)); \
-    } while (0)
+#define CELL_INT(c)     (c)->u.i
+#define CELL_FLOAT(c)   (c)->u.n
+#define CELL_STRING(c)  (c)->u.s
+#define CELL_PMC(c)     (c)->u.p
 
 #define HLL_TYPE(i) Parrot_get_ctx_HLL_type(interp, (i))
 
-/* TODO: could use get_cell_at */
-static Pcc_cell *
-pop_cell(PARROT_INTERP, ARGIN(PMC *SELF))
+static void
+ensure_positionals_storage(PARROT_INTERP, ARGIN(PMC *self), INTVAL size)
 {
-    INTVAL num_positionals;
-    Pcc_cell *cell;
-    Pcc_cell *prev = NULL;
-
-    GETATTR_CallContext_positionals(interp, SELF, cell);
-
-    /* no cells */
-    if (!cell)
-        return NULL;
-
-    GETATTR_CallContext_num_positionals(interp, SELF, num_positionals);
-    SETATTR_CallContext_num_positionals(interp, SELF, num_positionals-1);
-
-    /* one cell */
-    if (!NEXT_CELL(cell)) {
-        SETATTR_CallContext_positionals(interp, SELF, NULL);
-        return cell;
-    }
-
-    while (cell) {
-        if (!NEXT_CELL(cell)) {
-            NEXT_CELL(prev) = NULL;
-            return cell;
-        }
+    INTVAL num_positionals, allocated_positionals;
+    struct Pcc_cell  *array;
+    struct Pcc_cell  *new_array;
+
+    GETATTR_CallContext_allocated_positionals(interp, self, allocated_positionals);
+    if (size <= allocated_positionals)
+        return;
+
+    if (size < 8)
+        size = 8;
+
+    GETATTR_CallContext_positionals(interp, self, array);
+    if (size > 8)
+        new_array = (struct Pcc_cell*)Parrot_gc_allocate_memory_chunk(interp,
+                size * sizeof (Pcc_cell));
+    else
+        new_array = (struct Pcc_cell*)Parrot_gc_allocate_fixed_size_storage(interp,
+                size * sizeof (Pcc_cell));
 
-        prev = cell;
-        cell = NEXT_CELL(cell);
+    if (array) {
+        memset(new_array, size * sizeof (Pcc_cell), 0);
+        GETATTR_CallContext_num_positionals(interp, self, num_positionals);
+        memcpy(new_array, array, num_positionals * sizeof (Pcc_cell));
+        if (num_positionals > 8)
+            Parrot_gc_free_memory_chunk(interp, array);
+        else
+            Parrot_gc_free_fixed_size_storage(interp, allocated_positionals * sizeof (Pcc_cell),
+                    array);
     }
 
-    /* should abort here */
-    SETATTR_CallContext_num_positionals(interp, SELF, num_positionals+1);
-    return NULL;
-}
-
-static Pcc_cell *
-shift_cell(PARROT_INTERP, ARGIN(PMC *SELF))
-{
-    INTVAL num_positionals;
-    Pcc_cell *cell;
-
-    GETATTR_CallContext_positionals(interp, SELF, cell);
-
-    /* no cells */
-    if (!cell)
-        return NULL;
-
-    GETATTR_CallContext_num_positionals(interp, SELF, num_positionals);
-    SETATTR_CallContext_num_positionals(interp, SELF, num_positionals-1);
-
-    /* one cell */
-    if (!NEXT_CELL(cell))
-        SETATTR_CallContext_positionals(interp, SELF, NULL);
-    else
-        SETATTR_CallContext_positionals(interp, SELF, NEXT_CELL(cell));
-
-    return cell;
+    SETATTR_CallContext_allocated_positionals(interp, self, size);
+    SETATTR_CallContext_positionals(interp, self, new_array);
 }
 
-static Pcc_cell *
-get_cell_at(PARROT_INTERP, ARGIN(PMC *SELF), INTVAL key)
+static Pcc_cell*
+get_cell_at(PARROT_INTERP, ARGIN(PMC *self), INTVAL key)
 {
-    INTVAL    i, num_positionals;
-    Pcc_cell *cell;
-
-    GETATTR_CallContext_num_positionals(interp, SELF, num_positionals);
-
-    if (key > num_positionals)
-        return NULL;
-
-    GETATTR_CallContext_positionals(interp, SELF, cell);
-
-    while (key) {
-        /* XXX: shouldn't happen */
-        if (!NEXT_CELL(cell))
-            return NULL;
-
-        cell = NEXT_CELL(cell);
-        key--;
-    }
-
-    return cell;
-
+    Pcc_cell *cells;
+    ensure_positionals_storage(interp, self, key + 1);
+    GETATTR_CallContext_positionals(interp, self, cells);
+    return &cells[key];
 }
 
 static INTVAL
@@ -299,26 +213,36 @@
 }
 
 static void
-mark_positionals(PARROT_INTERP, ARGIN(Pcc_cell *c))
+mark_cell(PARROT_INTERP, ARGIN(Pcc_cell *c))
 {
-    while (c) {
-        switch (CELL_TYPE_MASK(c)) {
-          case STRINGCELL:
+    switch (CELL_TYPE_MASK(c)) {
+        case STRINGCELL:
             if (CELL_STRING(c))
                 Parrot_gc_mark_STRING_alive(interp, CELL_STRING(c));
             break;
-          case PMCCELL:
+        case PMCCELL:
             if (!PMC_IS_NULL(CELL_PMC(c)))
                 Parrot_gc_mark_PMC_alive(interp, CELL_PMC(c));
             break;
-          case INTCELL:
-          case FLOATCELL:
-          default:
+        case INTCELL:
+        case FLOATCELL:
+        default:
             break;
-        }
-
-        c = NEXT_CELL(c);
     }
+
+}
+
+static void
+mark_positionals(PARROT_INTERP, ARGIN(PMC *self))
+{
+    INTVAL size, i;
+    struct Pcc_cell *cells;
+
+    GETATTR_CallContext_num_positionals(interp, self, size);
+    GETATTR_CallContext_positionals(interp, self, cells);
+
+    for (i=0; i<size; ++i)
+        mark_cell(interp, &cells[i]);
 }
 
 /* don't look now, but here goes encapsulation.... */
@@ -333,7 +257,7 @@
 
         while (b) {
             Parrot_gc_mark_STRING_alive(interp, (STRING *)b->key);
-            mark_positionals(interp, (Pcc_cell *)b->value);
+            mark_cell(interp, (Pcc_cell *)b->value);
             b = b->next;
         }
 
@@ -411,13 +335,15 @@
     ATTR size_t pred_offset;
 
     /* Storage for arguments */
-    ATTR struct Pcc_cell *positionals; /* linked list of positionals */
+    ATTR struct Pcc_cell *positionals; /* array of positionals */
+    ATTR INTVAL  num_positionals;      /* count of used positionals */
+    ATTR INTVAL  allocated_positionals;/* count of allocated positionals */
+
     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 */
 
 /*
 
@@ -473,8 +399,7 @@
         Parrot_gc_mark_PMC_alive(INTERP, arg_flags);
         Parrot_gc_mark_PMC_alive(INTERP, return_flags);
 
-        if (num_positionals)
-            mark_positionals(INTERP, positionals);
+        mark_positionals(INTERP, SELF);
 
         if (hash)
             mark_hash(INTERP, hash);
@@ -541,8 +466,7 @@
 
 */
     VTABLE void morph(PMC *type) {
-        INTVAL  num_positionals;
-        Hash   *hash;
+        Hash     *hash;
 
         if (!PMC_data(SELF))
             return;
@@ -552,23 +476,10 @@
         SET_ATTR_return_flags(INTERP, SELF, PMCNULL);
         SET_ATTR_type_tuple(INTERP, SELF, PMCNULL);
 
-        GET_ATTR_hash(INTERP, SELF, hash);
-        GET_ATTR_num_positionals(INTERP, SELF, num_positionals);
-
-        if (num_positionals) {
-            Pcc_cell *c;
-
-            GET_ATTR_positionals(INTERP, SELF, c);
-
-            while (c) {
-                Pcc_cell *to_free = c;
-                c = NEXT_CELL(c);
-                FREE_CELL(INTERP, to_free);
-            }
-            SET_ATTR_num_positionals(INTERP, SELF, 0);
-            SET_ATTR_positionals(interp, SELF, NULL);
-        }
+        /* Don't free positionals. Just reuse them */
+        SET_ATTR_num_positionals(INTERP, SELF, 0);
 
+        GET_ATTR_hash(INTERP, SELF, hash);
 
         if (hash) {
             UINTVAL i;
@@ -588,25 +499,24 @@
     }
 
     VTABLE void destroy() {
-        INTVAL    num_positionals, returns_resize_threshold;
+        INTVAL    allocated_positionals;
         Hash     *hash;
 
         if (!PMC_data(SELF))
             return;
 
         GET_ATTR_hash(INTERP, SELF, hash);
-        GET_ATTR_num_positionals(INTERP, SELF, num_positionals);
+        GET_ATTR_allocated_positionals(INTERP, SELF, allocated_positionals);
 
-        if (num_positionals) {
+        if (allocated_positionals) {
             Pcc_cell *c;
 
             GET_ATTR_positionals(INTERP, SELF, c);
-
-            while (c) {
-                Pcc_cell *to_free = c;
-                c = NEXT_CELL(c);
-                FREE_CELL(INTERP, to_free);
-            }
+            if (allocated_positionals > 8)
+                Parrot_gc_free_memory_chunk(INTERP, c);
+            else
+                Parrot_gc_free_fixed_size_storage(INTERP, allocated_positionals * sizeof (Pcc_cell),
+                        c);
         }
 
         if (hash) {
@@ -652,7 +562,7 @@
 */
 
     VTABLE STRING *get_string() {
-        INTVAL    num_positionals;
+        INTVAL    num_positionals, i;
         STRING   *res;
         Pcc_cell *c;
 
@@ -666,8 +576,8 @@
 
         res = Parrot_str_new(INTERP, NULL, num_positionals);
 
-        while (c) {
-            switch (CELL_TYPE_MASK(c)) {
+        for (i=0; i<num_positionals; ++i) {
+            switch (c[i].type) {
               case INTCELL:
                 res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, "I"));
                 break;
@@ -684,7 +594,6 @@
                 PARROT_FAILURE("Impossible flag");
                 break;
             }
-            c = NEXT_CELL(c);
         }
         /* TODO Add named args to signature */
         /* After fixind build_MMD_type_tuple to use raw arguments instead of signature */
@@ -735,17 +644,17 @@
             type_tuple = Parrot_pmc_new_init_int(interp,
                 enum_class_FixedIntegerArray, num_positionals);
 
-            while (c) {
+            for (i=0; i<num_positionals; ++i) {
                 INTVAL type;
 
-                switch (CELL_TYPE_MASK(c)) {
+                switch (c[i].type) {
                     case INTCELL:    type = enum_type_INTVAL;   break;
                     case FLOATCELL:  type = enum_type_FLOATVAL; break;
                     case STRINGCELL: type = enum_type_STRING;   break;
                     case PMCCELL:
-                        type = PMC_IS_NULL(CELL_PMC(c))
+                        type = PMC_IS_NULL(c[i].u.p)
                              ? enum_type_PMC
-                             : VTABLE_type(interp, CELL_PMC(c));
+                             : VTABLE_type(interp, c[i].u.p);
                         break;
                     default:
                         Parrot_ex_throw_from_c_args(interp, NULL,
@@ -754,8 +663,6 @@
                 }
 
                 VTABLE_set_integer_keyed_int(interp, type_tuple, i, type);
-                i++;
-                c = NEXT_CELL(c);
             }
 
             SET_ATTR_type_tuple(INTERP, SELF, type_tuple);
@@ -931,255 +838,169 @@
     }
 
     VTABLE void push_integer(INTVAL value) {
-        Pcc_cell *cell = CREATE_INTVAL_CELL(INTERP);
-        APPEND_CELL(INTERP, SELF, cell);
-        CELL_INT(cell) = value;
-    }
+        INTVAL    num_pos;
+        Pcc_cell *cells;
 
-    VTABLE void push_float(FLOATVAL value) {
-        Pcc_cell *cell = CREATE_FLOATVAL_CELL(INTERP);
-        APPEND_CELL(INTERP, SELF, cell);
-        CELL_FLOAT(cell) = value;
-    }
+        GET_ATTR_num_positionals(INTERP, SELF, num_pos);
+        ensure_positionals_storage(INTERP, SELF, num_pos + 1);
 
-    VTABLE void push_string(STRING *value) {
-        Pcc_cell *cell = CREATE_STRING_CELL(INTERP);
-        APPEND_CELL(INTERP, SELF, cell);
-        CELL_STRING(cell) = value;
+        GET_ATTR_positionals(INTERP, SELF, cells);
+        cells[num_pos].u.i      = value;
+        cells[num_pos].type     = INTCELL;
+        SET_ATTR_num_positionals(INTERP, SELF, num_pos + 1);
     }
 
-    VTABLE void push_pmc(PMC *value) {
-        Pcc_cell *cell = CREATE_PMC_CELL(INTERP);
-        APPEND_CELL(INTERP, SELF, cell);
-        CELL_PMC(cell) = value;
-    }
+    VTABLE void push_float(FLOATVAL value) {
+        INTVAL    num_pos;
+        Pcc_cell *cells;
 
-    VTABLE INTVAL pop_integer() {
-        Pcc_cell *cell = pop_cell(INTERP, SELF);
-
-        if (cell) {
-            INTVAL result = autobox_intval(INTERP, cell);
-            FREE_CELL(INTERP, cell);
-            return result;
-        }
+        GET_ATTR_num_positionals(INTERP, SELF, num_pos);
+        ensure_positionals_storage(INTERP, SELF, num_pos + 1);
 
-        return 0;
+        GET_ATTR_positionals(INTERP, SELF, cells);
+        cells[num_pos].u.n      = value;
+        cells[num_pos].type     = FLOATCELL;
+        SET_ATTR_num_positionals(INTERP, SELF, num_pos + 1);
     }
 
-    VTABLE FLOATVAL pop_float() {
-        Pcc_cell *cell = pop_cell(INTERP, SELF);
+    VTABLE void push_string(STRING *value) {
+        INTVAL    num_pos;
+        Pcc_cell *cells;
 
-        if (cell) {
-            FLOATVAL result = autobox_floatval(INTERP, cell);
-            FREE_CELL(INTERP, cell);
-            return result;
-        }
+        GET_ATTR_num_positionals(INTERP, SELF, num_pos);
+        ensure_positionals_storage(INTERP, SELF, num_pos + 1);
 
-        return 0.0;
+        GET_ATTR_positionals(INTERP, SELF, cells);
+        cells[num_pos].u.s      = value;
+        cells[num_pos].type     = STRINGCELL;
+        SET_ATTR_num_positionals(INTERP, SELF, num_pos + 1);
     }
 
-    VTABLE PMC * pop_pmc() {
-        Pcc_cell *cell = pop_cell(INTERP, SELF);
-
-        if (cell) {
-            PMC *result = autobox_pmc(INTERP, cell);
-            FREE_CELL(INTERP, cell);
-            return result;
-        }
-
-        return PMCNULL;
-    }
+    VTABLE void push_pmc(PMC *value) {
+        INTVAL    num_pos;
+        Pcc_cell *cells;
 
-    VTABLE STRING * pop_string() {
-        Pcc_cell *cell = pop_cell(INTERP, SELF);
+        GET_ATTR_num_positionals(INTERP, SELF, num_pos);
+        ensure_positionals_storage(INTERP, SELF, num_pos + 1);
 
-        if (cell) {
-            STRING *result = autobox_string(INTERP, cell);
-            FREE_CELL(INTERP, cell);
-            return result;
-        }
+        GET_ATTR_positionals(INTERP, SELF, cells);
+        cells[num_pos].u.p      = value;
+        cells[num_pos].type     = PMCCELL;
+        SET_ATTR_num_positionals(INTERP, SELF, num_pos + 1);
+    }
+
+    /*
+        TODO It's very naive implementation. But we do unshift _once_ only.
+        So, for speed sake, allocate _one_ Cell upfront. Or store it independent.
+    */
 
-        return NULL;
+    VTABLE void unshift_pmc(PMC *value) {
+        INTVAL    size = STATICSELF.elements();
+        Pcc_cell *cells;
+        INTVAL    i;
+
+        ensure_positionals_storage(INTERP, SELF, size + 1);
+        GET_ATTR_positionals(INTERP, SELF, cells);
+
+        for (i = size; i; --i)
+            cells[i] = cells[i - 1];
+
+        cells[0].u.p    = value;
+        cells[0].type   = PMCCELL;
+        SET_ATTR_num_positionals(INTERP, SELF, size + 1);
     }
 
+
     VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
-        Pcc_cell *cell = get_cell_at(INTERP, SELF, key);
+        INTVAL    num_pos;
+        Pcc_cell *cells;
 
-        if (!cell)
+        GET_ATTR_num_positionals(INTERP, SELF, num_pos);
+        if (key>=num_pos || key < 0)
             return 0;
 
-        return autobox_intval(INTERP, cell);
+        GET_ATTR_positionals(INTERP, SELF, cells);
+        return autobox_intval(INTERP, &cells[key]);
     }
 
     VTABLE FLOATVAL get_number_keyed_int(INTVAL key) {
-        Pcc_cell *cell = get_cell_at(INTERP, SELF, key);
+        INTVAL    num_pos;
+        Pcc_cell *cells;
 
-        if (!cell)
+        GET_ATTR_num_positionals(INTERP, SELF, num_pos);
+        if (key>=num_pos || key < 0)
             return 0.0;
 
-        return autobox_floatval(INTERP, cell);
+        GET_ATTR_positionals(INTERP, SELF, cells);
+        return autobox_floatval(INTERP, &cells[key]);
     }
 
     VTABLE STRING * get_string_keyed_int(INTVAL key) {
-        Pcc_cell *cell = get_cell_at(INTERP, SELF, key);
+        INTVAL    num_pos;
+        Pcc_cell *cells;
 
-        if (!cell)
+        GET_ATTR_num_positionals(INTERP, SELF, num_pos);
+        if (key>=num_pos || key < 0)
             return NULL;
 
-        return autobox_string(INTERP, cell);
+        GET_ATTR_positionals(INTERP, SELF, cells);
+        return autobox_string(INTERP, &cells[key]);
     }
 
     VTABLE PMC * get_pmc_keyed_int(INTVAL key) {
-        Pcc_cell *cell = get_cell_at(INTERP, SELF, key);
+        INTVAL    num_pos;
+        Pcc_cell *cells;
 
-        if (!cell)
+        GET_ATTR_num_positionals(INTERP, SELF, num_pos);
+        if (key>=num_pos || key < 0)
             return PMCNULL;
 
-        return autobox_pmc(INTERP, cell);
-    }
-
-    VTABLE void unshift_integer(INTVAL value) {
-        Pcc_cell *cell = CREATE_INTVAL_CELL(INTERP);
-        PREPEND_CELL(INTERP, SELF, cell);
-        CELL_INT(cell) = value;
-    }
-
-    VTABLE void unshift_float(FLOATVAL value) {
-        Pcc_cell *cell = CREATE_FLOATVAL_CELL(INTERP);
-        PREPEND_CELL(INTERP, SELF, cell);
-        CELL_FLOAT(cell) = value;
-    }
-
-    VTABLE void unshift_string(STRING *value) {
-        Pcc_cell *cell = CREATE_STRING_CELL(INTERP);
-        PREPEND_CELL(INTERP, SELF, cell);
-        CELL_STRING(cell) = value;
-    }
-
-    VTABLE void unshift_pmc(PMC *value) {
-        Pcc_cell *cell = CREATE_PMC_CELL(INTERP);
-        PREPEND_CELL(INTERP, SELF, cell);
-        CELL_PMC(cell) = value;
-    }
-
-    VTABLE INTVAL shift_integer() {
-        Pcc_cell *cell = shift_cell(INTERP, SELF);
-
-        if (cell) {
-            INTVAL result = autobox_intval(INTERP, cell);
-            FREE_CELL(INTERP, cell);
-            return result;
-        }
-
-        return 0;
-    }
-
-    VTABLE FLOATVAL shift_float() {
-        Pcc_cell *cell = shift_cell(INTERP, SELF);
-
-        if (cell) {
-            FLOATVAL result = autobox_floatval(INTERP, cell);
-            FREE_CELL(INTERP, cell);
-            return result;
-        }
-
-        return 0.0;
-    }
-
-    VTABLE STRING * shift_string() {
-        Pcc_cell *cell = shift_cell(INTERP, SELF);
-
-        if (cell) {
-            STRING *result = autobox_string(INTERP, cell);
-            FREE_CELL(INTERP, cell);
-            return result;
-        }
-
-        return NULL;
-    }
-
-    VTABLE PMC * shift_pmc() {
-        Pcc_cell *cell = shift_cell(INTERP, SELF);
-
-        if (cell) {
-            PMC *result = autobox_pmc(INTERP, cell);
-            FREE_CELL(INTERP, cell);
-            return result;
-        }
-
-        return PMCNULL;
+        GET_ATTR_positionals(INTERP, SELF, cells);
+        return autobox_pmc(INTERP, &cells[key]);
     }
 
     VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
+        INTVAL    pos;
         Pcc_cell *cell = get_cell_at(INTERP, SELF, key);
 
-        if (!cell) {
-            INTVAL num_positionals;
-
-            GET_ATTR_num_positionals(INTERP, SELF, num_positionals);
-
-            if (key == num_positionals)
-                VTABLE_push_integer(INTERP, SELF, value);
-
-            /* XXX: else throw exception? */
-            return;
-        }
-
-        CELL_INT(cell) = value;
+        cell->u.i   = value;
+        cell->type  = INTCELL;
+        GET_ATTR_num_positionals(INTERP, SELF, pos);
+        if (pos <= key)
+            SET_ATTR_num_positionals(INTERP, SELF, key + 1);
     }
 
     VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
+        INTVAL    pos;
         Pcc_cell *cell = get_cell_at(INTERP, SELF, key);
 
-        if (!cell) {
-            INTVAL num_positionals;
-
-            GET_ATTR_num_positionals(INTERP, SELF, num_positionals);
-
-            if (key == num_positionals)
-                VTABLE_push_float(INTERP, SELF, value);
-
-            /* XXX: else throw exception? */
-            return;
-        }
-
-        CELL_FLOAT(cell) = value;
+        cell->u.n   = value;
+        cell->type  = FLOATCELL;
+        GET_ATTR_num_positionals(INTERP, SELF, pos);
+        if (pos <= key)
+            SET_ATTR_num_positionals(INTERP, SELF, key + 1);
     }
 
     VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
+        INTVAL    pos;
         Pcc_cell *cell = get_cell_at(INTERP, SELF, key);
 
-        if (!cell) {
-            INTVAL num_positionals;
-
-            GET_ATTR_num_positionals(INTERP, SELF, num_positionals);
-
-            if (key == num_positionals)
-                VTABLE_push_string(INTERP, SELF, value);
-
-            /* XXX: else throw exception? */
-            return;
-        }
-
-        CELL_STRING(cell) = value;
+        cell->u.s   = value;
+        cell->type  = STRINGCELL;
+        GET_ATTR_num_positionals(INTERP, SELF, pos);
+        if (pos <= key)
+            SET_ATTR_num_positionals(INTERP, SELF, key + 1);
     }
 
     VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
+        INTVAL    pos;
         Pcc_cell *cell = get_cell_at(INTERP, SELF, key);
 
-        if (!cell) {
-            INTVAL num_positionals;
-
-            GET_ATTR_num_positionals(INTERP, SELF, num_positionals);
-
-            if (key == num_positionals)
-                VTABLE_push_pmc(INTERP, SELF, value);
-
-            /* XXX: else throw exception? */
-            return;
-        }
-
-        CELL_PMC(cell) = value;
+        cell->u.p   = value;
+        cell->type  = PMCCELL;
+        GET_ATTR_num_positionals(INTERP, SELF, pos);
+        if (pos <= key)
+            SET_ATTR_num_positionals(INTERP, SELF, key + 1);
     }
 
     VTABLE void set_integer_keyed_str(STRING *key, INTVAL value) {
@@ -1187,12 +1008,12 @@
         Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(INTERP, hash, (void *)key);
 
         if (!cell) {
-            cell = CREATE_INTVAL_CELL(INTERP);
+            cell = ALLOC_CELL(INTERP);
             parrot_hash_put(INTERP, hash, (void *)key, (void *)cell);
-            NEXT_CELL(cell) = NULL;
         }
 
-        CELL_INT(cell) = value;
+        cell->u.i       = value;
+        cell->type      = INTCELL;
     }
 
     VTABLE void set_number_keyed_str(STRING *key, FLOATVAL value) {
@@ -1200,12 +1021,12 @@
         Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(INTERP, hash, (void *)key);
 
         if (!cell) {
-            cell = CREATE_FLOATVAL_CELL(INTERP);
+            cell = ALLOC_CELL(INTERP);
             parrot_hash_put(INTERP, hash, (void *)key, (void *)cell);
-            NEXT_CELL(cell) = NULL;
         }
 
-        CELL_FLOAT(cell) = value;
+        cell->u.n       = value;
+        cell->type      = FLOATCELL;
     }
 
     VTABLE void set_string_keyed_str(STRING *key, STRING *value) {
@@ -1213,12 +1034,12 @@
         Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(INTERP, hash, (void *)key);
 
         if (!cell) {
-            cell = CREATE_STRING_CELL(INTERP);
+            cell = ALLOC_CELL(INTERP);
             parrot_hash_put(INTERP, hash, (void *)key, (void *)cell);
-            NEXT_CELL(cell) = NULL;
         }
 
-        CELL_STRING(cell) = value;
+        cell->u.s       = value;
+        cell->type      = STRINGCELL;
     }
 
     VTABLE void set_pmc_keyed_str(STRING *key, PMC *value) {
@@ -1226,12 +1047,12 @@
         Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(INTERP, hash, (void *)key);
 
         if (!cell) {
-            cell = CREATE_PMC_CELL(INTERP);
+            cell = ALLOC_CELL(INTERP);
             parrot_hash_put(INTERP, hash, (void *)key, (void *)cell);
-            NEXT_CELL(cell) = NULL;
         }
 
-        CELL_PMC(cell) = value;
+        cell->u.p       = value;
+        cell->type      = PMCCELL;
     }
 
     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
@@ -1240,12 +1061,12 @@
         Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(INTERP, hash, k);
 
         if (!cell) {
-            cell = CREATE_INTVAL_CELL(INTERP);
+            cell = ALLOC_CELL(INTERP);
             parrot_hash_put(INTERP, hash, k, (void *)cell);
-            NEXT_CELL(cell) = NULL;
         }
 
-        CELL_INT(cell) = value;
+        cell->u.i       = value;
+        cell->type      = INTCELL;
     }
 
     VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
@@ -1254,12 +1075,12 @@
         Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(INTERP, hash, k);
 
         if (!cell) {
-            cell = CREATE_FLOATVAL_CELL(INTERP);
+            cell = ALLOC_CELL(INTERP);
             parrot_hash_put(INTERP, hash, k, (void *)cell);
-            NEXT_CELL(cell) = NULL;
         }
 
-        CELL_FLOAT(cell) = value;
+        cell->u.n       = value;
+        cell->type      = FLOATCELL;
     }
 
     VTABLE void set_string_keyed(PMC *key, STRING *value) {
@@ -1268,12 +1089,12 @@
         Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(INTERP, hash, k);
 
         if (!cell) {
-            cell = CREATE_STRING_CELL(INTERP);
+            cell = ALLOC_CELL(INTERP);
             parrot_hash_put(INTERP, hash, k, (void *)cell);
-            NEXT_CELL(cell) = NULL;
         }
 
-        CELL_STRING(cell) = value;
+        cell->u.s       = value;
+        cell->type      = STRINGCELL;
     }
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
@@ -1282,12 +1103,12 @@
         Pcc_cell *cell = (Pcc_cell *)parrot_hash_get(INTERP, hash, k);
 
         if (!cell) {
-            cell = CREATE_PMC_CELL(INTERP);
+            cell = ALLOC_CELL(INTERP);
             parrot_hash_put(INTERP, hash, k, (void *)cell);
-            NEXT_CELL(cell) = NULL;
         }
 
-        CELL_PMC(cell) = value;
+        cell->u.p       = value;
+        cell->type      = PMCCELL;
     }
 
     VTABLE INTVAL get_integer_keyed_str(STRING *key) {
@@ -1446,56 +1267,25 @@
 
 */
     VTABLE PMC *clone() {
-        Pcc_cell    *cell;
         STRING      *short_sig;
         PMC         *type_tuple, *arg_flags, *return_flags;
-        PMC * const dest = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
-
-        GET_ATTR_positionals(INTERP, SELF, cell);
-
-        /* Copy all positional cells (thanks to APPEND_CELL, this also
-         * sets num_positionals). */
-        for (; cell; cell = NEXT_CELL(cell)) {
-            Pcc_cell *cloned_cell;
-
-            switch (CELL_TYPE_MASK(cell)) {
-              case INTCELL:
-                cloned_cell = CREATE_INTVAL_CELL(INTERP);
-                CELL_INT(cloned_cell) = CELL_INT(cell);
-                break;
-              case FLOATCELL:
-                cloned_cell = CREATE_FLOATVAL_CELL(INTERP);
-                CELL_FLOAT(cloned_cell) = CELL_FLOAT(cell);
-                break;
-              case STRINGCELL:
-                cloned_cell = CREATE_STRING_CELL(INTERP);
-                CELL_STRING(cloned_cell) = CELL_STRING(cell);
-                break;
-              case PMCCELL:
-                cloned_cell = CREATE_PMC_CELL(INTERP);
-                CELL_PMC(cloned_cell) = CELL_PMC(cell);
-                break;
-              default:
-                break;
-            }
-            APPEND_CELL(INTERP, dest, cloned_cell);
-        }
-
+        PMC * const  dest = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
+        INTVAL       num;
+        Pcc_cell    *our_cells, *dest_cells;
+
+        GET_ATTR_num_positionals(INTERP, SELF, num);
+        /* Copy positionals */
+        ensure_positionals_storage(INTERP, dest, num);
+        GET_ATTR_positionals(INTERP, SELF, our_cells);
+        GET_ATTR_positionals(INTERP, dest, dest_cells);
+        memcpy(dest_cells, our_cells, num * sizeof (Pcc_cell));
+        SET_ATTR_num_positionals(INTERP, dest, num);
 
         GET_ATTR_type_tuple(INTERP, SELF, type_tuple);
         GET_ATTR_short_sig(INTERP, SELF, short_sig);
         GET_ATTR_arg_flags(INTERP, SELF, arg_flags);
         GET_ATTR_return_flags(INTERP, SELF, return_flags);
 
-        /* FIXME
-        PMC *results;
-
-        GET_ATTR_results(INTERP, SELF, results);
-
-        if (!PMC_IS_NULL(results))
-            SET_ATTR_results(INTERP, dest, VTABLE_clone(INTERP, results));
-        */
-
         if (!PMC_IS_NULL(type_tuple))
             SET_ATTR_type_tuple(INTERP, dest, VTABLE_clone(INTERP, type_tuple));
 
@@ -1514,7 +1304,6 @@
         return dest;
     }
 
-
 /*
 
 =item C<PMC *backtrace>

Modified: branches/pcc_hackathon_6Mar10/t/pmc/callcontext.t
==============================================================================
--- branches/pcc_hackathon_6Mar10/t/pmc/callcontext.t	Thu Mar 18 20:01:58 2010	(r45022)
+++ branches/pcc_hackathon_6Mar10/t/pmc/callcontext.t	Thu Mar 18 20:12:58 2010	(r45023)
@@ -19,12 +19,10 @@
 .sub 'main' :main
     .include 'test_more.pir'
 
-    plan(66)
+    plan(37)
 
     test_instantiate()
     test_get_set_attrs()
-    test_push_pop_indexed_access()
-    test_shift_unshift_indexed_access()
     test_indexed_access()
     test_indexed_boxing()
     test_keyed_access()
@@ -54,85 +52,6 @@
     is($P5,'cheese', 'got arg_flags attribute')
 .end
 
-.sub 'test_push_pop_indexed_access'
-    $P0 = new [ 'CallContext' ]
-    $P1 = new [ 'Integer' ]
-    $P1 = 100
-
-    push $P0, $P1
-    $I0 = elements $P0
-    is( $I0, 1, 'elements after push' )
-
-    $P2 = $P0[0]
-    is( $P2, 100, 'push_pmc/get_pmc_keyed_int pair' )
-    $P2 = pop $P0
-    is( $P2, 100, 'push_pmc/pop_pmc pair' )
-
-    $I0 = elements $P0
-    is( $I0, 0, 'elements after pop' )
-
-    push $P0, 200
-    $I0 = $P0[0]
-    is( $I0, 200, 'push_integer/get_integer_keyed_int pair' )
-    $I0 = pop $P0
-    is( $I0, 200, 'push_integer/pop_integer pair' )
-
-    push $P0, 3.03
-    $N0 = $P0[0]
-    is( $N0, 3.03, 'push_number/get_number_keyed_int pair' )
-    $N0 = pop $P0
-    is( $N0, 3.03, 'push_number/pop_number pair' )
-
-    push $P0, 'hello'
-    $S0 = $P0[0]
-    is( $S0, 'hello', 'push_string/get_string_keyed_int pair' )
-    $S0 = pop $P0
-    is( $S0, 'hello', 'push_string/pop_string pair' )
-
-    $I0 = elements $P0
-    is( $I0, 0, 'elements after push/pop' )
-.end
-
-.sub 'test_shift_unshift_indexed_access'
-    $P0 = new [ 'CallContext' ]
-    $P1 = new [ 'Integer' ]
-    $P1 = 100
-
-    unshift $P0, $P1
-
-    $I0 = elements $P0
-    is( $I0, 1, 'elements after unshift' )
-
-    $P2 = $P0[0]
-    is( $P2, 100, 'unshift_pmc/get_pmc_keyed_int pair' )
-    $P2 = shift $P0
-    is( $P2, 100, 'unshift_pmc/shift_pmc pair' )
-
-    $I0 = elements $P0
-    is( $I0, 0, 'elements after unshift/shift' )
-
-    unshift $P0, 200
-    $I0 = $P0[0]
-    is( $I0, 200, 'unshift_integer/get_integer_keyed_int pair' )
-    $I0 = shift $P0
-    is( $I0, 200, 'unshift_integer/shift_integer pair' )
-
-    unshift $P0, 3.03
-    $N0 = $P0[0]
-    is( $N0, 3.03, 'unshift_number/get_number_keyed_int pair' )
-    $N0 = shift $P0
-    is( $N0, 3.03, 'unshift_number/shift_number pair' )
-
-    unshift $P0, 'hello'
-    $S0 = $P0[0]
-    is( $S0, 'hello', 'unshift_string/get_string_keyed_int pair' )
-    $S0 = shift $P0
-    is( $S0, 'hello', 'unshift_string/shift_string pair' )
-
-    $I0 = elements $P0
-    is( $I0, 0, 'elements after unshift/shift' )
-.end
-
 .sub 'test_indexed_access'
     $P0    = new [ 'CallContext' ]
     $P0[0] = 100
@@ -170,26 +89,6 @@
     $P1    = $P0[3]
     is( $P1, 3.33, 'set_pmc_keyed_int/get_pmc_keyed_int pair' )
 
-    $I1 = shift $P0
-    is( $I1, 100, 'set_integer_keyed_int/shift_integer pair' )
-
-    $N1 = $P0[0]
-    is( $N1, 1.11, 'shift_* should remove elements from array' )
-
-    $N1 = shift $P0
-    is( $N1, 1.11, 'set_number_keyed_int/shift_number pair' )
-
-    $S1 = $P0[0]
-    is( $S1, '2.22', 'shift_* should remove elements from array' )
-
-    $S1 = shift $P0
-    is( $S1, '2.22', 'set_string_keyed_int/shift_string pair' )
-
-    $P1 = $P0[0]
-    is( $P1, 3.33, 'shift_* should remove elements from array' )
-
-    $P1 = shift $P0
-    is( $P1, 3.33, 'set_pmc_keyed_int/shift_pmc pair' )
 .end
 
 .sub 'test_indexed_boxing'


More information about the parrot-commits mailing list