This patch obsoletes my previous two key-related patches. It's a large
patch that does a bunch of things, so I'd like somebody to give an
opinion before I commit it.

 - Changes KEY to contain a KEY_PAIR* instead of a KEY_PAIR**
 - Changes the MAKE_KEY macro to work within an expression
 - Changes the MAKE_KEY macro to not return NULL if the value is 0 or
   NULL. This is needed because an enum_int_val key, for example, will
   quite often have the value zero, but that shouldn't mean the whole
   aggregate. I think we'll have to add another macro or a flag for
   keys with those semantics. But this patch is trying to be the
   minimum necessary to get PerlArrays working again.
 - Adds various *_keyed ops to core.ops. This is an incomplete set,
   because I thought someone might be thinking about autogenerating
   some of them. This is enough to access command-line parameters
   and use PerlArrays of PerlInts.
 - Adds back in the copying of the command-line parameters to P0.
 - Makes the rx_*group* opcodes work again (they use PerlArrays)
 - Fixes the array_resize logic. It was totally inconsistent about
   whether its size parameter was a size or an index, and could seg
   fault as a result.
 - Makes array_resize zero out newly allocated memory. This is the only
   way to tell whether an array slot has been initialized yet.
 - Sets the PMC GC flags for PerlArrays.
 - Automatically creates PerlStrings/PerlInts/PerlNums when assigning
   strings, integers, or numbers to uninitialized PerlArray slots.

I'm sorry this patch isn't split up more, but the lines overlap a lot,
and I think the whole thing passes the "better than what's there now"
test.

-- 
WM ISO JOB. http://foxglove.dnsalias.org/~sfink/job.html
C, perl, networking, performance optimization, Java, XML.

Index: include/parrot/key.h
===================================================================
RCS file: /home/perlcvs/parrot/include/parrot/key.h,v
retrieving revision 1.9
diff -u -r1.9 key.h
--- include/parrot/key.h        4 Mar 2002 03:17:21 -0000       1.9
+++ include/parrot/key.h        29 Mar 2002 06:04:39 -0000
@@ -39,7 +39,7 @@
 
 struct _key {
     INTVAL size;
-    KEY_PAIR **keys;
+    KEY_PAIR *keys;
 };
 
 typedef struct _key KEY;
Index: core.ops
===================================================================
RCS file: /home/perlcvs/parrot/core.ops,v
retrieving revision 1.114
diff -u -r1.114 core.ops
--- core.ops    28 Mar 2002 08:02:02 -0000      1.114
+++ core.ops    29 Mar 2002 06:04:24 -0000
@@ -2,15 +2,16 @@
 ** core.ops
 */
 
-/* This convoluted mess avoids costly runtime creation of KEY
-and KEY_PAIR structures. */
-
-#define MAKE_KEY(k,k_p,v,c,t) if (v) {\
-        k_p.type = c;\
-        k_p.cache.t = v;\
-        k.size = 1;\
-        k.keys[0] = &k_p;\
-    }
+/* This (now even more) convoluted mess avoids costly runtime creation
+ * of KEY and KEY_PAIR structures, and can be used in an expression.
+ */
+
+#define MAKE_KEY(k,k_p,v,c,t) (\
+        k_p.type = c,\
+        k_p.cache.t = v,\
+        k.size = 1,\
+        k.keys = &k_p,\
+        &k)
 
 VERSION = PARROT_VERSION;
 
@@ -565,6 +566,22 @@
   goto NEXT();
 }
 
+inline op get_keyed(out INT, in PMC, in INT) {
+  KEY_PAIR key_p;
+  KEY key;
+  MAKE_KEY(key, key_p, $3, enum_key_int, int_val);
+  $1 = $2->vtable->get_integer_keyed(interpreter, $2, &key);
+  goto NEXT();
+}
+
+inline op get_keyed(out STR, in PMC, in INT) {
+  KEY_PAIR key_p;
+  KEY key;
+  MAKE_KEY(key, key_p, $3, enum_key_int, int_val);
+  $1 = $2->vtable->get_string_keyed(interpreter, $2, &key);
+  goto NEXT();
+}
+
 =item B<set_keyed>(out PMC, out PMC, in PMC, in PMC)
 
     $1[$2] = $3[$4];
@@ -580,6 +597,26 @@
 
     $1->vtable->set_pmc_keyed(interpreter, 
                     $1, $2 ? &src_key : NULL, $3, $4 ? &dest_key : NULL);
+    goto NEXT();
+}
+
+inline op set_keyed (out PMC, in INT, in INT)  {
+    KEY_PAIR key_p;
+    KEY key;
+
+    MAKE_KEY(key, key_p, $2, enum_key_int, int_val);
+
+    $1->vtable->set_integer_keyed(interpreter, $1, &key, $3);
+    goto NEXT();
+}
+
+inline op set_keyed (out PMC, in INT, in STR)  {
+    KEY_PAIR key_p;
+    KEY key;
+
+    MAKE_KEY(key, key_p, $2, enum_key_int, int_val);
+
+    $1->vtable->set_string_keyed(interpreter, $1, &key, $3);
     goto NEXT();
 }
 
Index: embed.c
===================================================================
RCS file: /home/perlcvs/parrot/embed.c,v
retrieving revision 1.18
diff -u -r1.18 embed.c
--- embed.c     9 Mar 2002 00:59:56 -0000       1.18
+++ embed.c     29 Mar 2002 19:35:26 -0000
@@ -165,6 +165,8 @@
 {
     INTVAL i;
     PMC *userargv;
+    KEY key;
+    KEY_PAIR key_p;
 
     if (interpreter->flags & PARROT_DEBUG_FLAG) {
         fprintf(stderr, "*** Parrot VM: Debugging enabled. ***\n");
@@ -195,20 +197,24 @@
     }
 
     userargv = pmc_new(interpreter, enum_class_PerlArray);
+    /* immediately anchor pmc to root set */
+    interpreter->pmc_reg.registers[0] = userargv;
+
+    key.size = 1;
+    key.keys = &key_p;
+    key_p.type = enum_key_int;
 
     for (i = 0; i < argc; i++) {
+        STRING* arg = string_make(interpreter, argv[i], strlen(argv[i]),
+                                  0, BUFFER_external_FLAG, 0);
+
         if (interpreter->flags & PARROT_DEBUG_FLAG) {
             fprintf(stderr, "\t" INTVAL_FMT ": %s\n", i, argv[i]);
         }
 
-        /* XXX: Delayed
-         * userargv->vtable->set_string_index(interpreter, userargv, 
-         * string_make(interpreter, argv[i], strlen(argv[i]), 0, 0, 0), i
-         * );
-         */
+        key_p.cache.int_val = i;
+        userargv->vtable->set_string_keyed(interpreter, userargv, &key, arg);
     }
-
-    interpreter->pmc_reg.registers[0] = userargv;
 
     runops(interpreter, interpreter->code, 0);
 
Index: key.c
===================================================================
RCS file: /home/perlcvs/parrot/key.c,v
retrieving revision 1.23
diff -u -r1.23 key.c
--- key.c       5 Mar 2002 04:26:10 -0000       1.23
+++ key.c       29 Mar 2002 06:04:25 -0000
@@ -29,7 +29,7 @@
     fprintf(stderr, " *** key %p\n", key);
     fprintf(stderr, " *** size " INTVAL_FMT "\n", key->size);
     for (i = 0; i < key->size; i++) {
-        INTVAL type = key->keys[i]->type;
+        INTVAL type = key->keys[i].type;
         if (type == enum_key_bucket) {
             fprintf(stderr, " *** Bucket " INTVAL_FMT " type " INTVAL_FMT "\n",
                     i, type);
@@ -199,9 +199,9 @@
                 (KEY_PAIR *)realloc(key->keys, sizeof(KEY_PAIR *) * size);
             if (pair != NULL) {
                 INTVAL i;
-                key->keys = (KEY_PAIR **)pair;
+                key->keys = pair;
                 for (i = key->size; i < size; i++) {
-                    key->keys[i]->type = enum_key_undef;
+                    key->keys[i].type = enum_key_undef;
                 }
             }
             else {
@@ -215,7 +215,7 @@
                 /* Memory leak in the making */
             }
             key->keys =
-                (KEY_PAIR **)realloc(key->keys, sizeof(KEY_PAIR *) * size);
+                (KEY_PAIR *)realloc(key->keys, sizeof(KEY_PAIR *) * size);
         }
         key->size = size;
     }
@@ -316,7 +316,7 @@
             hash = hash % NUM_BUCKETS;
             pair =
                 find_bucket(interpreter,
-                            (BUCKET *)key->keys[hash]->cache.struct_val, idx);
+                            (BUCKET *)key->keys[hash].cache.struct_val, idx);
             if (pair == NULL) {
                 internal_exception(KEY_NOT_FOUND,
                                    "*** key_element_value_s pair returning a null 
key\n");
@@ -384,14 +384,14 @@
                     if (hash >= key->size) {
                         key_set_size(interpreter, key, hash + 1);
                     }
-                    if (key->keys[hash]->type != enum_key_undef) {
-                        STRING *tmp = key->keys[hash]->cache.struct_val;
+                    if (key->keys[hash].type != enum_key_undef) {
+                        STRING *tmp = key->keys[hash].cache.struct_val;
                         bucket->next = (BUCKET *)tmp;
                     }
                     else {
                     }
-                    key->keys[hash]->cache.struct_val = (STRING *)bucket;
-                    key->keys[hash]->type = enum_key_bucket;
+                    key->keys[hash].cache.struct_val = (STRING *)bucket;
+                    key->keys[hash].type = enum_key_bucket;
                 }
                 else {
                     fprintf(stderr,
@@ -430,7 +430,7 @@
             /* Memory leak in the making */
             key->size--;
             key->keys =
-                (KEY_PAIR **)realloc(key->keys,
+                (KEY_PAIR *)realloc(key->keys,
                                      sizeof(KEY_PAIR *) * key->size);
         }
         else if (key->size == 0) {
Index: rx.ops
===================================================================
RCS file: /home/perlcvs/parrot/rx.ops,v
retrieving revision 1.16
diff -u -r1.16 rx.ops
--- rx.ops      15 Feb 2002 02:30:02 -0000      1.16
+++ rx.ops      29 Mar 2002 19:36:52 -0000
@@ -372,12 +372,13 @@
 =cut
 
 op rx_info_getgroup(in pmc, out int, out int, in int) {
+        KEY_PAIR key_p;
+        KEY key;
        RX_dUNPACK($1);
 
-    /* Delayed XXX
-       $2=rx->groupstart->vtable->get_integer_index(interpreter, rx->groupstart, $4);
-       $3=rx->groupend->vtable->get_integer_index(interpreter, rx->groupend, $4);
-    */
+        MAKE_KEY(key, key_p, $4, enum_key_int, int_val);
+       $2=rx->groupstart->vtable->get_integer_keyed(interpreter, rx->groupstart, 
+&key);
+       $3=rx->groupend->vtable->get_integer_keyed(interpreter, rx->groupend, &key);
        
        goto NEXT();
 }
@@ -635,11 +636,12 @@
 =cut
 
 op rx_startgroup(in pmc, in int) {
+        KEY_PAIR key_p;
+        KEY key;
        RX_dUNPACK($1);
        
-    /* XXX Delayed
-       rx->groupstart->vtable->set_integer_index(interpreter, rx->groupstart, 
rx->index, $2);
-    */
+        MAKE_KEY(key, key_p, $2, enum_key_int, int_val);
+       rx->groupstart->vtable->set_integer_keyed(interpreter, rx->groupstart, &key, 
+rx->index);
        
        goto NEXT();
 }
@@ -654,13 +656,14 @@
 =cut
 
 op rx_endgroup(in pmc, in int) {
-       RX_dUNPACK($1);
+    KEY_PAIR key_p;
+    KEY key;
+    RX_dUNPACK($1);
        
-    /* XXX Delayed
-       rx->groupend->vtable->set_integer_index(interpreter, rx->groupend, rx->index, 
$2);
-    */
+    MAKE_KEY(key, key_p, $2, enum_key_int, int_val);        
+    rx->groupend->vtable->set_integer_keyed(interpreter, rx->groupend, &key, 
+rx->index);
        
-       goto NEXT();
+    goto NEXT();
 }
 
 ########################################
Index: classes/array.pmc
===================================================================
RCS file: /home/perlcvs/parrot/classes/array.pmc,v
retrieving revision 1.18
diff -u -r1.18 array.pmc
--- classes/array.pmc   14 Mar 2002 14:46:23 -0000      1.18
+++ classes/array.pmc   29 Mar 2002 06:04:34 -0000
@@ -83,7 +83,7 @@
             return 0;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp2int(INTERP, *kp);
 
         if (ix > SELF->cache.int_val || ix < 0) {
@@ -107,7 +107,7 @@
             return 0;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp2int(INTERP, *kp);
 
         if (ix > SELF->cache.int_val || ix < 0) {
@@ -131,7 +131,7 @@
             return 0;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp2int(INTERP, *kp);
 
         if (ix > SELF->cache.int_val || ix < 0) {
@@ -184,7 +184,7 @@
             return;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp2int(INTERP, *kp);
 
         if (ix > SELF->cache.int_val || ix < 0) {
@@ -221,7 +221,7 @@
             return;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp2int(INTERP, *kp);
 
         if (ix > SELF->cache.int_val || ix < 0) {
@@ -256,7 +256,7 @@
             return;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp2int(INTERP, *kp);
 
         if (ix > SELF->cache.int_val || ix < 0) {
@@ -275,7 +275,7 @@
             src = src->vtable->get_pmc_keyed(INTERP, src, src_key);
         }
         if (dest_key) {
-            INTVAL ix = kp2int(INTERP, *((dest_key->keys)[0]));
+            INTVAL ix = kp2int(INTERP, dest_key->keys[0]);
             PMC* dest = ((PMC**)(((Buffer *)SELF->data)->bufstart))[ix];
             dest->vtable->set_pmc(INTERP, dest, src);
         } 
Index: classes/perlhash.pmc
===================================================================
RCS file: /home/perlcvs/parrot/classes/perlhash.pmc,v
retrieving revision 1.15
diff -u -r1.15 perlhash.pmc
--- classes/perlhash.pmc        10 Mar 2002 21:18:13 -0000      1.15
+++ classes/perlhash.pmc        29 Mar 2002 06:04:37 -0000
@@ -59,7 +59,7 @@
             return 0;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
         if (ix > SELF->cache.int_val) {
@@ -89,7 +89,7 @@
             return 0;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
         if (ix > SELF->cache.int_val) {
@@ -119,7 +119,7 @@
             return 0;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
         if (ix > SELF->cache.int_val) {
@@ -177,7 +177,7 @@
             return;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
         if (ix > SELF->cache.int_val) {
@@ -219,7 +219,7 @@
             return;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
         if (ix > SELF->cache.int_val) {
@@ -259,7 +259,7 @@
             return;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
         if (ix > SELF->cache.int_val) {
Index: classes/perlarray.pmc
===================================================================
RCS file: /home/perlcvs/parrot/classes/perlarray.pmc,v
retrieving revision 1.23
diff -u -r1.23 perlarray.pmc
--- classes/perlarray.pmc       14 Mar 2002 14:46:23 -0000      1.23
+++ classes/perlarray.pmc       29 Mar 2002 20:00:42 -0000
@@ -13,10 +13,13 @@
 #include "parrot/parrot.h"
 
 static void resize_array ( struct Parrot_Interp *interpreter, PMC* self, INTVAL size 
) {
-    size++;
-    if(self->data != NULL) {
+    int oldsize = self->cache.int_val;
+    Buffer* buffer = (Buffer *) self->data;
+    if(buffer != NULL) {
        if(size >= 0) {
-           ((Buffer *)self->data)->bufstart = mem_realloc(interpreter, 
self->data,self->cache.int_val*sizeof(PMC *),sizeof(PMC*)*size);
+           buffer->bufstart = mem_realloc(interpreter, buffer->bufstart, 
+oldsize*sizeof(PMC *), size*sizeof(PMC*));
+            if (size > oldsize)
+                memset(buffer->bufstart + oldsize * sizeof(PMC *), 0, (size - 
+oldsize) * sizeof(PMC *));
        }
        else {
             internal_exception(OUT_OF_BOUNDS,
@@ -24,9 +27,14 @@
        }
     }
     else {
-       self->data = new_buffer_header(interpreter);
-       ((Buffer *)self->data)->bufstart = Parrot_allocate(interpreter, 
sizeof(PMC*)*size);
+       buffer = (Buffer *) self->data = new_buffer_header(interpreter);
+        self->flags |= PMC_is_buffer_ptr_FLAG;
+        self->flags |= PMC_is_PMC_ptr_FLAG;
+       buffer->bufstart = Parrot_allocate(interpreter, sizeof(PMC*)*size);
+        memset(buffer->bufstart, 0, size * sizeof(PMC *));
     }
+
+    self->cache.int_val = size;
 }
 
 pmclass PerlArray {
@@ -40,8 +48,10 @@
     }
 
     void init (INTVAL size) {
-       SELF->data = mem_sys_allocate(sizeof(PMC*));
+        SELF->flags |= PMC_is_container_FLAG;
+       SELF->data = NULL;
        SELF->cache.int_val = 0;
+        resize_array(INTERP, SELF, 0);
     }
 
     void clone (PMC* dest) { 
@@ -55,11 +65,11 @@
     }
 
     INTVAL real_size () {
-       return 0; /* ->data is unused */
+       return 0; /* ->data is unused */ /* XXX Huh? */
     }
 
     void destroy () {
-       key_destroy(INTERP,SELF->data);
+       key_destroy(INTERP,SELF->data); /* XXX Huh? */
     }
 
     INTVAL get_integer () {
@@ -70,22 +80,25 @@
         KEY_PAIR* kp;
         INTVAL ix;
         PMC* value;
+        PMC** array;
 
         if (!key) {
             return 0;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
-        if (ix > SELF->cache.int_val) {
-           resize_array(interpreter, SELF,ix);
+        if (ix >= SELF->cache.int_val) {
+           resize_array(interpreter, SELF, ix+1);
         }
         if (ix < 0) {
             ix += SELF->cache.int_val;
         }
 
-        value = ((PMC**)(SELF->data))[ix];
+        array = ((Buffer *) SELF->data)->bufstart;
+        value = array[ix];
+        if (value == NULL) value = pmc_new(INTERP, enum_class_PerlUndef);
         return value->vtable->get_integer(INTERP, value);
     }
 
@@ -97,22 +110,25 @@
         KEY_PAIR* kp;
         INTVAL ix;
         PMC* value;
+        PMC** array;
 
         if (!key) {
             return 0;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
-        if (ix > SELF->cache.int_val) {
-           resize_array(interpreter, SELF,ix);
+        if (ix >= SELF->cache.int_val) {
+           resize_array(interpreter, SELF, ix+1);
         }
         if (ix < 0) {
             ix += SELF->cache.int_val;
         }
 
-        value = ((PMC**)(SELF->data))[ix];
+        array = ((Buffer *) SELF->data)->bufstart;
+        value = array[ix];
+        if (value == NULL) value = pmc_new(INTERP, enum_class_PerlUndef);
         return value->vtable->get_number(INTERP, value);
     }
 
@@ -124,22 +140,25 @@
         KEY_PAIR* kp;
         INTVAL ix;
         PMC* value;
+        PMC** array;
 
         if (!key) {
             return 0;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
-        if (ix > SELF->cache.int_val) {
-           resize_array(interpreter, SELF,ix);
+        if (ix >= SELF->cache.int_val) {
+           resize_array(interpreter, SELF, ix+1);
         }
         else if (ix < 0) {
             ix += SELF->cache.int_val;
         }
 
-        value = ((PMC**)(SELF->data))[ix];
+        array = ((Buffer *) SELF->data)->bufstart;
+        value = array[ix];
+        if (value == NULL) value = pmc_new(INTERP, enum_class_PerlUndef);
         return value->vtable->get_string(INTERP, value);
     }
 
@@ -162,11 +181,11 @@
 
     void set_integer (PMC* value) {
        INTVAL size = value->vtable->get_integer(INTERP,value);
-       resize_array(interpreter, SELF,size);
+       resize_array(interpreter, SELF, size);
     }
 
     void set_integer_native (INTVAL size) {
-       resize_array(interpreter, SELF,size);
+       resize_array(interpreter, SELF, size);
     }
 
     void set_integer_bigint (BIGINT value) {
@@ -174,39 +193,44 @@
 
     void set_integer_same (PMC * value) {
        INTVAL size = value->cache.int_val;
-       resize_array(interpreter, SELF,size);
+       resize_array(interpreter, SELF, size);
     }
 
     void set_integer_keyed (KEY * key, INTVAL value) {
         KEY_PAIR* kp;
         INTVAL ix;
         PMC* pmc2;
+        PMC** array;
 
         if (!key) {
             return;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
-        if (ix > SELF->cache.int_val) {
-           resize_array(interpreter, SELF,ix);
+        if (ix >= SELF->cache.int_val) {
+           resize_array(interpreter, SELF, ix+1);
         }
         else if (ix < 0) {
             ix += SELF->cache.int_val;
         }
 
-        pmc2 = ((PMC**)(SELF->data))[ix];
+        array = ((Buffer *) SELF->data)->bufstart;
+        pmc2 = array[ix];
+        if (pmc2 == NULL)
+            array[ix] = pmc2 = pmc_new(INTERP, enum_class_PerlInt);
+
         pmc2->vtable->set_integer_native(INTERP, pmc2, value);
     }
 
     void set_number (PMC * value) {
        INTVAL size = (INTVAL)value->cache.num_val;
-       resize_array(interpreter, SELF,size);
+       resize_array(interpreter, SELF, size+1);
     }
 
     void set_number_native (FLOATVAL size) {
-       resize_array(interpreter, SELF,(INTVAL)size);
+       resize_array(interpreter, SELF, (INTVAL)size);
     }
 
     void set_number_bigfloat (BIGFLOAT value) {
@@ -214,29 +238,34 @@
 
     void set_number_same (PMC * value) {
        INTVAL size = value->cache.int_val;
-       resize_array(interpreter, SELF,size);
+       resize_array(interpreter, SELF, size);
     }
 
     void set_number_keyed (KEY * key, FLOATVAL value) {
         KEY_PAIR* kp;
         INTVAL ix;
         PMC* pmc2;
+        PMC** array;
 
         if (!key) {
             return;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
-        if (ix > SELF->cache.int_val) {
-           resize_array(interpreter, SELF,ix);
+        if (ix >= SELF->cache.int_val) {
+           resize_array(interpreter, SELF, ix+1);
         }
         else if (ix < 0) {
             ix += SELF->cache.int_val;
         }
 
-        pmc2 = ((PMC**)(SELF->data))[ix];
+        array = ((Buffer *) SELF->data)->bufstart;
+        pmc2 = array[ix];
+        if (pmc2 == NULL)
+            array[ix] = pmc2 = pmc_new(INTERP, enum_class_PerlNum);
+
         pmc2->vtable->set_number_native(INTERP, pmc2, value);
     }
 
@@ -259,22 +288,27 @@
         KEY_PAIR* kp;
         INTVAL ix;
         PMC* pmc2;
+        PMC** array;
 
         if (!key) {
             return;
         }
 
-        kp = (key->keys)[0];
+        kp = &key->keys[0];
         ix = kp->cache.int_val;
 
-        if (ix > SELF->cache.int_val) {
-           resize_array(interpreter, SELF,ix);
+        if (ix >= SELF->cache.int_val) {
+           resize_array(interpreter, SELF, ix+1);
         }
         else if (ix < 0) {
             ix += SELF->cache.int_val;
         }
 
-        pmc2 = ((PMC**)(SELF->data))[ix];
+        array = ((Buffer *) SELF->data)->bufstart;
+        pmc2 = array[ix];
+        if (pmc2 == NULL)
+           array[ix] = pmc2 = pmc_new(INTERP, enum_class_PerlString);
+
         pmc2->vtable->set_string_native(INTERP, pmc2, value);
     }
 

Reply via email to