Well, actually two bugs.

 The first is an off-by-one error in key.c than can cause parrot
 to segfault if hash % NUM_BUCKETS happens to be zero.

 The other is a bug in the PerlHash init() code that causes new PerlHash
 PMCs to start with the wrong size.

 Both fixed below; also tests to prevent them recurring.

 Simon

--- key.c.old   Wed Jan  9 20:00:01 2002
+++ key.c       Thu Jan 10 17:41:01 2002
@@ -327,7 +327,7 @@
         if(bucket != NULL) {
           hash = hash % NUM_BUCKETS;
           /* Resize the hash here rather than set an initial size. */
-          if(hash > key->size) {
+          if(hash >= key->size) {
             key_set_size(interpreter,key,hash+1);
           }
           if(key->keys[hash].type != enum_key_undef) {

--- perlhash.pmc.old    Thu Jan 10 15:40:08 2002
+++ perlhash.pmc        Thu Jan 10 17:40:32 2002
@@ -24,7 +24,7 @@
 
     void init () {
        SELF->cache.struct_val = key_new(INTERP);
-       key_set_size(INTERP,SELF->cache.struct_val,1);
+       key_set_size(INTERP,SELF->cache.struct_val,0);
     }
 
     void clone (PMC* dest) { 

--- pmc_perlhash.t.old  Thu Jan 10 15:41:47 2002
+++ pmc_perlhash.t      Thu Jan 10 17:56:55 2002
@@ -1,6 +1,6 @@
 #! perl
 
-use Parrot::Test tests => 5;
+use Parrot::Test tests => 7;
 
 output_is(<<'CODE', <<OUTPUT, "simple set / get");
        new P0, PerlHash
@@ -23,6 +23,28 @@
 2
 OUTPUT
 
+output_is(<<'CODE', <<OUTPUT, "more than one PerlHash");
+       new P0, PerlHash
+       set S0, "key"
+       set P0, 1, S0
+               
+        new P1, PerlHash
+        set S1, "another_key"
+        set P1, 2, S1 
+
+       set I0, P0, S0
+       set I1, P1, S1
+
+       print I0
+       print "\n"
+       print I1
+       print "\n"
+        end
+CODE
+1
+2
+OUTPUT
+
 output_is(<<'CODE', <<OUTPUT, "hash keys with nulls in them");
        new P0, PerlHash
        set S0, "parp\0me"
@@ -112,5 +134,23 @@
 2
 2
 OUTPUT
+
+
+# NB Next test depends on "key2" hashing to zero, which it does with
+# the current algorithm; if the algorithm changes, change the test!
+
+output_is(<<'CODE', <<OUTPUT, "key that hashes to zero");
+        new P0, PerlHash
+        set S0, "key2"
+        set P0, 1, S0
+        set I0, P0, S0
+       print I0
+       print "\n"      
+       end
+CODE
+1
+OUTPUT
+
+
 
 1;


Reply via email to