hash-sets,hashtables: make it so the array backing the hash is non-empty

Commit 70c7f9e029 made it so the code
assumes the array is not empty. But it can be empty if the hashtable is
created using "hashtable new" and then it can crash because it reads
uninitialized memory. Setting the initial of the array slot to
a valid hash-array should fix that.
char-rename
Björn Lindqvist 2016-10-05 19:09:55 +02:00
parent 78d9065db0
commit 6f10f06c27
3 changed files with 29 additions and 5 deletions

View File

@ -10,7 +10,10 @@ IN: hash-sets
TUPLE: hash-set
{ count array-capacity }
{ deleted array-capacity }
{ array array } ;
{ array array initial: {
T{ tombstone } T{ tombstone } T{ tombstone } T{ tombstone }
}
} ;
<PRIVATE

View File

@ -1,5 +1,11 @@
USING: accessors assocs continuations fry hashtables kernel make
math namespaces sequences tools.test ;
USING: accessors arrays assocs continuations fry hashtables
hashtables.private kernel make math memory namespaces sequences
tools.test ;
! hash@
{ 18 } [
77 20 f <array> hash@
] unit-test
{ H{ } } [ { } [ dup ] H{ } map>assoc ] unit-test
@ -182,5 +188,14 @@ H{ } "x" set
{ 1 } [ 2 "h" get at ] unit-test
! Previously this could break as hashtable new created a backing an
! empty backing array and the code assumed its length was > 0.
{ f f } [
compact-gc 77 hashtable new [ clone ] change-array at*
] unit-test
! Random test case
{ "A" } [ 100 iota [ dup ] H{ } map>assoc 32 over delete-at "A" 32 pick set-at 32 of ] unit-test
{ "A" } [
100 iota [ dup ] H{ } map>assoc 32 over
delete-at "A" 32 pick set-at 32 of
] unit-test

View File

@ -4,10 +4,16 @@ USING: accessors arrays assocs kernel kernel.private math
math.private sequences sequences.private slots.private vectors ;
IN: hashtables
! Required because the hashtable definition references tombstone.
<PRIVATE PRIVATE>
TUPLE: hashtable
{ count array-capacity }
{ deleted array-capacity }
{ array array } ;
{ array array initial: {
T{ tombstone } T{ tombstone } T{ tombstone } T{ tombstone }
}
} ;
<PRIVATE