hashtables bootstrap correctly

cvs
Slava Pestov 2005-01-28 01:06:10 +00:00
parent 0dfb0cf01e
commit 67af634d00
26 changed files with 225 additions and 79 deletions

View File

@ -24,7 +24,8 @@ OBJS = native/arithmetic.o native/array.o native/bignum.o \
native/unix/read.o \ native/unix/read.o \
native/unix/write.o \ native/unix/write.o \
native/unix/ffi.o \ native/unix/ffi.o \
native/debug.o native/debug.o \
native/hashtable.o
default: default:
@echo "Run 'make' with one of the following parameters:" @echo "Run 'make' with one of the following parameters:"

View File

@ -29,6 +29,7 @@ IN: kernel-internals
USE: generic USE: generic
USE: math-internals USE: math-internals
USE: kernel USE: kernel
USE: lists
! An array is a range of memory storing pointers to other ! An array is a range of memory storing pointers to other
! objects. Arrays are not used directly, and their access words ! objects. Arrays are not used directly, and their access words
@ -42,7 +43,7 @@ USE: kernel
BUILTIN: array 8 BUILTIN: array 8
: array-capacity ( array -- n ) 1 integer-slot ; inline : array-capacity ( array -- n ) 1 slot ; inline
: vector-array ( vec -- array ) 2 slot ; inline : vector-array ( vec -- array ) 2 slot ; inline
: set-vector-array ( array vec -- ) 2 set-slot ; inline : set-vector-array ( array vec -- ) 2 set-slot ; inline
@ -51,3 +52,14 @@ BUILTIN: array 8
: set-array-nth ( obj n array -- ) : set-array-nth ( obj n array -- )
swap 2 fixnum+ set-slot ; inline swap 2 fixnum+ set-slot ; inline
: (array>list) ( n i array -- list )
pick pick fixnum<= [
3drop [ ]
] [
2dup array-nth >r >r 1 fixnum+ r> (array>list) r>
swap cons
] ifte ;
: array>list ( n array -- list )
0 swap (array>list) ;

View File

@ -41,6 +41,7 @@
IN: image IN: image
USE: errors USE: errors
USE: generic USE: generic
USE: kernel-internals
USE: hashtables USE: hashtables
USE: kernel USE: kernel
USE: lists USE: lists
@ -86,9 +87,9 @@ SYMBOL: boot-quot
: cons-tag BIN: 010 ; inline : cons-tag BIN: 010 ; inline
: object-tag BIN: 011 ; inline : object-tag BIN: 011 ; inline
: f-type 6 ; inline
: t-type 7 ; inline : t-type 7 ; inline
: array-type 8 ; inline : array-type 8 ; inline
: hashtable-type 10 ; inline
: vector-type 11 ; inline : vector-type 11 ; inline
: string-type 12 ; inline : string-type 12 ; inline
: word-type 17 ; inline : word-type 17 ; inline
@ -142,6 +143,8 @@ GENERIC: ' ( obj -- ptr )
( Fixnums ) ( Fixnums )
: emit-fixnum ( n -- ) fixnum-tag immediate emit ;
M: fixnum ' ( n -- tagged ) fixnum-tag immediate ; M: fixnum ' ( n -- tagged ) fixnum-tag immediate ;
( Bignums ) ( Bignums )
@ -154,7 +157,7 @@ M: bignum ' ( bignum -- tagged )
[[ 0 [ 1 0 ] ]] [[ 0 [ 1 0 ] ]]
[[ -1 [ 2 1 1 ] ]] [[ -1 [ 2 1 1 ] ]]
[[ 1 [ 2 0 1 ] ]] [[ 1 [ 2 0 1 ] ]]
] assoc [ emit ] each align-here r> ; ] assoc unswons emit-fixnum [ emit ] each align-here r> ;
( Special objects ) ( Special objects )
@ -175,7 +178,7 @@ M: f ' ( obj -- ptr )
: -1, -1 >bignum ' drop ; : -1, -1 >bignum ' drop ;
( Beginning of the image ) ( Beginning of the image )
! The image proper begins with the header, then T, ! The image begins with the header, then T,
! and the bignums 0, 1, and -1. ! and the bignums 0, 1, and -1.
: begin ( -- ) header t, 0, 1, -1, ; : begin ( -- ) header t, 0, 1, -1, ;
@ -249,7 +252,7 @@ M: cons ' ( c -- tagged )
object-tag here-as swap object-tag here-as swap
string-type >header emit string-type >header emit
dup str-length emit dup str-length emit
dup hashcode fixnum-tag immediate emit dup hashcode emit-fixnum
pack-string pack-string
align-here ; align-here ;
@ -266,7 +269,7 @@ M: string ' ( string -- pointer )
[ ' ] map [ ' ] map
object-tag here-as >r object-tag here-as >r
array-type >header emit array-type >header emit
dup length emit dup length emit-fixnum
( elements -- ) [ emit ] each ( elements -- ) [ emit ] each
align-here r> ; align-here r> ;
@ -274,7 +277,7 @@ M: string ' ( string -- pointer )
dup vector>list emit-array swap vector-length dup vector>list emit-array swap vector-length
object-tag here-as >r object-tag here-as >r
vector-type >header emit vector-type >header emit
emit ( length ) emit-fixnum ( length )
emit ( array ptr ) emit ( array ptr )
align-here r> ; align-here r> ;
@ -284,24 +287,30 @@ M: vector ' ( vector -- pointer )
: rehash ( hashtable -- ) : rehash ( hashtable -- )
! Now make a rehashing boot quotation ! Now make a rehashing boot quotation
dup hash>alist [ dup hash>alist [
>r dup vector-length [ over hash-clear
[ f swap pick set-vector-nth ] keep
] repeat r>
[ unswons rot set-hash ] each-with [ unswons rot set-hash ] each-with
] cons cons ] cons cons
boot-quot [ append ] change ; boot-quot [ append ] change ;
: emit-hashtable ( hash -- pointer )
dup buckets>list emit-array swap hash-size
object-tag here-as >r
hashtable-type >header emit
emit-fixnum ( length )
emit ( array ptr )
align-here r> ;
M: hashtable ' ( hashtable -- pointer ) M: hashtable ' ( hashtable -- pointer )
#! Only hashtables are pooled, not vectors! #! Only hashtables are pooled, not vectors!
dup pooled-object [ dup pooled-object [
[ dup emit-vector [ pool-object ] keep ] keep rehash [ dup emit-hashtable [ pool-object ] keep ] keep rehash
] ?unless ; ] ?unless ;
( End of the image ) ( End of the image )
: vocabularies, ( vocabularies -- ) : vocabularies, ( vocabularies -- )
[ [
cdr dup vector? [ cdr dup hashtable? [
[ [
cdr dup word? [ word, ] [ drop ] ifte cdr dup word? [ word, ] [ drop ] ifte
] hash-each ] hash-each

View File

@ -218,11 +218,14 @@ vocabularies get [
[[ "vectors" ">vector" ]] [[ "vectors" ">vector" ]]
[[ "strings" ">string" ]] [[ "strings" ">string" ]]
[[ "words" ">word" ]] [[ "words" ">word" ]]
[[ "hashtables" ">hashtable" ]]
[[ "kernel-internals" "slot" ]] [[ "kernel-internals" "slot" ]]
[[ "kernel-internals" "set-slot" ]] [[ "kernel-internals" "set-slot" ]]
[[ "kernel-internals" "integer-slot" ]] [[ "kernel-internals" "integer-slot" ]]
[[ "kernel-internals" "set-integer-slot" ]] [[ "kernel-internals" "set-integer-slot" ]]
[[ "kernel-internals" "grow-array" ]] [[ "kernel-internals" "grow-array" ]]
[[ "hashtables" "<hashtable>" ]]
[[ "kernel-internals" "<array>" ]]
] [ ] [
unswons create swap 1 + [ f define ] keep unswons create swap 1 + [ f define ] keep
] each drop ] each drop

View File

@ -39,7 +39,7 @@ USE: vectors
! Traits metaclass for user-defined classes based on hashtables ! Traits metaclass for user-defined classes based on hashtables
: traits ( object -- symbol ) : traits ( object -- symbol )
dup vector? [ \ traits swap hash ] [ drop f ] ifte ; dup hashtable? [ \ traits swap hash ] [ drop f ] ifte ;
! Hashtable slot holding an optional delegate. Any undefined ! Hashtable slot holding an optional delegate. Any undefined
! methods are called on the delegate. The object can also ! methods are called on the delegate. The object can also
@ -58,7 +58,7 @@ SYMBOL: delegate
] ifte ; ] ifte ;
: add-traits-dispatch ( word vtable -- ) : add-traits-dispatch ( word vtable -- )
>r unit [ car traits-dispatch call ] cons \ vector r> >r unit [ car traits-dispatch call ] cons \ hashtable r>
set-vtable ; set-vtable ;
\ traits [ \ traits [

View File

@ -25,37 +25,45 @@
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: kernel-internals IN: hashtables
USE: generic USE: generic
USE: kernel USE: kernel
USE: lists USE: lists
USE: math USE: math
USE: vectors USE: vectors
: hash-array vector-array ; inline BUILTIN: hashtable 10
: bucket-count >vector hash-array array-capacity ; inline
! A hashtable is implemented as an array of buckets. The
! array index is determined using a hash function, and the
! buckets are associative lists which are searched
! linearly.
IN: kernel-internals
: hash-array 2 slot ; inline
: hash-bucket ( n hash -- alist ) : hash-bucket ( n hash -- alist )
swap >fixnum swap >vector hash-array array-nth ; inline swap >fixnum swap >hashtable hash-array array-nth ; inline
: set-hash-bucket ( obj n hash -- ) : set-hash-bucket ( obj n hash -- )
>r >fixnum r> hash-array set-array-nth ; inline swap >fixnum swap >hashtable hash-array set-array-nth ;
inline
: hash-size+ ( hash -- )
>hashtable dup 1 slot 1 + swap 1 set-slot ; inline
: hash-size- ( hash -- )
>hashtable dup 1 slot 1 - swap 1 set-slot ; inline
IN: hashtables IN: hashtables
! Note that the length of a hashtable vector must not change : hash-size ( hash -- n )
! for the lifetime of the hashtable, otherwise problems will #! Number of elements in the hashtable.
! occur. Do not use vector words with hashtables. >hashtable 1 slot ;
PREDICATE: vector hashtable ( obj -- ? ) : bucket-count ( hash -- n )
[ assoc? ] vector-all? ; >hashtable hash-array array-capacity ; inline
: <hashtable> ( buckets -- )
#! A hashtable is implemented as an array of buckets. The
#! array index is determined using a hash function, and the
#! buckets are associative lists which are searched
#! linearly. The number of buckets must be a power of two.
empty-vector ;
: (hashcode) ( key table -- index ) : (hashcode) ( key table -- index )
#! Compute the index of the bucket for a key. #! Compute the index of the bucket for a key.
@ -74,6 +82,8 @@ PREDICATE: vector hashtable ( obj -- ? )
: set-hash* ( key table quot -- ) : set-hash* ( key table quot -- )
#! Apply the quotation to yield a new association list. #! Apply the quotation to yield a new association list.
#! If the association list already contains the key,
#! decrement the hash size, since it will get removed.
>r >r
2dup (hashcode) 2dup (hashcode)
r> pick >r r> pick >r
@ -86,27 +96,46 @@ PREDICATE: vector hashtable ( obj -- ? )
#! Store the value in the hashtable. Either replaces an #! Store the value in the hashtable. Either replaces an
#! existing value in the appropriate bucket, or adds a new #! existing value in the appropriate bucket, or adds a new
#! key/value pair. #! key/value pair.
dup hash-size+
[ set-assoc ] set-hash* ; [ set-assoc ] set-hash* ;
: remove-hash ( key table -- ) : remove-hash ( key table -- )
#! Remove a value from a hashtable. #! Remove a value from a hashtable.
[ remove-assoc ] set-hash* ; [ remove-assoc ] set-hash* ;
: hash-each ( hash code -- ) : hash-clear ( hash -- )
#! Apply the code to each key/value pair of the hashtable. #! Remove all entries from a hashtable.
swap [ swap dup >r each r> ] vector-each drop ; inline dup bucket-count [
[ f swap pick set-hash-bucket ] keep
] repeat drop ;
: buckets>list ( hash -- list )
#! Push a list of key/value pairs in a hashtable.
dup bucket-count swap hash-array array>list ;
: (hash>alist) ( alist n hash -- alist )
2dup bucket-count >= [
2drop
] [
[ hash-bucket [ swons ] each ] 2keep
>r 1 + r> (hash>alist)
] ifte ;
: hash>alist ( hash -- alist )
#! Push a list of key/value pairs in a hashtable.
[ ] 0 rot (hash>alist) ;
: alist>hash ( alist -- hash )
dup length <hashtable> swap [ unswons pick set-hash ] each ;
: hash-keys ( hash -- list ) : hash-keys ( hash -- list )
#! Push a list of keys in a hashtable. #! Push a list of keys in a hashtable.
[ ] swap [ car swons ] hash-each ; hash>alist [ car ] map ;
: hash-values ( hash -- alist ) : hash-values ( hash -- alist )
#! Push a list of values in a hashtable. #! Push a list of values in a hashtable.
[ ] swap [ cdr swons ] hash-each ; hash>alist [ cdr ] map ;
: hash>alist ( hash -- list ) : hash-each ( hash code -- )
#! Push a list of key/value pairs in a hashtable. #! Apply the code to each key/value pair of the hashtable.
[ ] swap [ swons ] hash-each ; >r hash>alist r> each ; inline
: alist>hash ( alist -- hash )
37 <hashtable> swap [ unswons pick set-hash ] each ;

View File

@ -61,7 +61,7 @@ USE: math
: >n ( namespace -- n:namespace ) : >n ( namespace -- n:namespace )
#! Push a namespace on the namespace stack. #! Push a namespace on the namespace stack.
>vector namestack cons set-namestack ; inline >hashtable namestack cons set-namestack ; inline
: n> ( n:namespace -- namespace ) : n> ( n:namespace -- namespace )
#! Pop the top of the namespace stack. #! Pop the top of the namespace stack.

View File

@ -26,6 +26,7 @@
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: alien IN: alien
USE: hashtables
DEFER: alien DEFER: alien
DEFER: dll DEFER: dll
@ -215,12 +216,15 @@ USE: words
[ >cons [ [ object ] [ cons ] ] ] [ >cons [ [ object ] [ cons ] ] ]
[ >vector [ [ object ] [ vector ] ] ] [ >vector [ [ object ] [ vector ] ] ]
[ >string [ [ object ] [ string ] ] ] [ >string [ [ object ] [ string ] ] ]
[ >word [ [ word ] [ word ] ] ] [ >word [ [ object ] [ word ] ] ]
[ >hashtable [ [ object ] [ hashtable ] ] ]
[ slot [ [ object fixnum ] [ object ] ] ] [ slot [ [ object fixnum ] [ object ] ] ]
[ set-slot [ [ object object fixnum ] [ ] ] ] [ set-slot [ [ object object fixnum ] [ ] ] ]
[ integer-slot [ [ object fixnum ] [ integer ] ] ] [ integer-slot [ [ object fixnum ] [ integer ] ] ]
[ set-integer-slot [ [ integer object fixnum ] [ ] ] ] [ set-integer-slot [ [ integer object fixnum ] [ ] ] ]
[ grow-array [ [ integer array ] [ object ] ] ] [ grow-array [ [ integer array ] [ object ] ] ]
[ <hashtable> [ [ number ] [ hashtable ] ] ]
[ <array> [ [ number ] [ array ] ] ]
] [ ] [
2unlist dup string? [ 2unlist dup string? [
"stack-effect" set-word-property "stack-effect" set-word-property

View File

@ -58,3 +58,17 @@ f 100000000000000000000000000 "testhash" get set-hash
"visual basic" "testhash" get remove-hash "visual basic" "testhash" get remove-hash
"visual basic" "testhash" get hash* "visual basic" "testhash" get hash*
] unit-test ] unit-test
[ 4 ] [
"hey"
{{ [[ "hey" 4 ]] [[ "whey" 5 ]] }} 2dup (hashcode)
>r buckets>list r> [ cdr ] times car assoc
] unit-test
! Testing the hash element counting
<namespace> "counting" set
"key" "value" "counting" get set-hash
[ 1 ] [ "counting" get hash-size ] unit-test
"key" "value" "counting" get set-hash
[ 1 ] [ "counting" get hash-size ] unit-test

View File

@ -78,7 +78,7 @@ unit-test
[ "funky" ] [ "funny-stack" get vector-pop ] unit-test [ "funky" ] [ "funny-stack" get vector-pop ] unit-test
[ t ] [ [ t ] [
10 <vector> dup vector-array array-capacity { 1 2 3 4 } dup vector-array array-capacity
>r vector-clone vector-array array-capacity r> >r vector-clone vector-array array-capacity r>
= =
] unit-test ] unit-test

View File

@ -36,11 +36,11 @@ USE: math-internals
BUILTIN: vector 11 BUILTIN: vector 11
: vector-length ( vec -- len ) >vector 1 integer-slot ; inline : vector-length ( vec -- len ) >vector 1 slot ; inline
IN: kernel-internals IN: kernel-internals
: (set-vector-length) ( len vec -- ) 1 set-integer-slot ; inline : (set-vector-length) ( len vec -- ) 1 set-slot ; inline
: assert-positive ( fx -- ) : assert-positive ( fx -- )
0 fixnum< 0 fixnum<
@ -107,15 +107,8 @@ IN: vectors
: >pop> ( stack -- stack ) : >pop> ( stack -- stack )
dup vector-pop drop ; dup vector-pop drop ;
: (vector>list) ( i vec -- list ) : vector>list ( vec -- list )
2dup vector-length >= [ dup vector-length swap vector-array array>list ;
2drop [ ]
] [
2dup vector-nth >r >r 1 + r> (vector>list) r> swons
] ifte ;
: vector>list ( str -- list )
0 swap (vector>list) ;
: vector-each ( vector quotation -- ) : vector-each ( vector quotation -- )
#! Execute the quotation with each element of the vector #! Execute the quotation with each element of the vector

View File

@ -5,7 +5,7 @@ F_ARRAY* allot_array(CELL type, CELL capacity)
{ {
F_ARRAY* array; F_ARRAY* array;
array = allot_object(type,sizeof(F_ARRAY) + capacity * CELLS); array = allot_object(type,sizeof(F_ARRAY) + capacity * CELLS);
array->capacity = capacity; array->capacity = tag_fixnum(capacity);
return array; return array;
} }
@ -22,20 +22,30 @@ F_ARRAY* array(CELL capacity, CELL fill)
return array; return array;
} }
void primitive_array(void)
{
F_FIXNUM capacity = to_fixnum(dpop());
if(capacity < 0)
general_error(ERROR_NEGATIVE_ARRAY_SIZE,tag_fixnum(capacity));
maybe_garbage_collection();
dpush(tag_object(array(capacity,F)));
}
F_ARRAY* grow_array(F_ARRAY* array, CELL capacity, CELL fill) F_ARRAY* grow_array(F_ARRAY* array, CELL capacity, CELL fill)
{ {
/* later on, do an optimization: if end of array is here, just grow */ /* later on, do an optimization: if end of array is here, just grow */
int i; int i;
F_ARRAY* new_array; F_ARRAY* new_array;
CELL curr_cap = untag_fixnum_fast(array->capacity);
if(array->capacity >= capacity) if(curr_cap >= capacity)
return array; return array;
new_array = allot_array(untag_header(array->header),capacity); new_array = allot_array(untag_header(array->header),capacity);
memcpy(new_array + 1,array + 1,array->capacity * CELLS); memcpy(new_array + 1,array + 1,array->capacity * CELLS);
for(i = array->capacity; i < capacity; i++) for(i = curr_cap; i < capacity; i++)
put(AREF(new_array,i),fill); put(AREF(new_array,i),fill);
return new_array; return new_array;
@ -43,8 +53,11 @@ F_ARRAY* grow_array(F_ARRAY* array, CELL capacity, CELL fill)
void primitive_grow_array(void) void primitive_grow_array(void)
{ {
F_ARRAY* array = untag_array(dpop()); F_ARRAY* array;
CELL capacity = to_fixnum(dpop()); CELL capacity;
maybe_garbage_collection();
array = untag_array(dpop());
capacity = to_fixnum(dpop());
dpush(tag_object(grow_array(array,capacity,F))); dpush(tag_object(grow_array(array,capacity,F)));
} }
@ -58,13 +71,15 @@ F_ARRAY* shrink_array(F_ARRAY* array, CELL capacity)
void fixup_array(F_ARRAY* array) void fixup_array(F_ARRAY* array)
{ {
int i = 0; int i = 0;
for(i = 0; i < array->capacity; i++) CELL capacity = untag_fixnum_fast(array->capacity);
for(i = 0; i < capacity; i++)
data_fixup((void*)AREF(array,i)); data_fixup((void*)AREF(array,i));
} }
void collect_array(F_ARRAY* array) void collect_array(F_ARRAY* array)
{ {
int i = 0; int i = 0;
for(i = 0; i < array->capacity; i++) CELL capacity = untag_fixnum_fast(array->capacity);
for(i = 0; i < capacity; i++)
copy_object((void*)AREF(array,i)); copy_object((void*)AREF(array,i));
} }

View File

@ -1,17 +1,18 @@
typedef struct { typedef struct {
CELL header; CELL header;
/* untagged */ /* tagged */
CELL capacity; CELL capacity;
} F_ARRAY; } F_ARRAY;
INLINE F_ARRAY* untag_array(CELL tagged) INLINE F_ARRAY* untag_array(CELL tagged)
{ {
/* type_check(ARRAY_TYPE,tagged); */ type_check(ARRAY_TYPE,tagged);
return (F_ARRAY*)UNTAG(tagged); /* FIXME */ return (F_ARRAY*)UNTAG(tagged);
} }
F_ARRAY* allot_array(CELL type, CELL capacity); F_ARRAY* allot_array(CELL type, CELL capacity);
F_ARRAY* array(CELL capacity, CELL fill); F_ARRAY* array(CELL capacity, CELL fill);
void primitive_array(void);
F_ARRAY* grow_array(F_ARRAY* array, CELL capacity, CELL fill); F_ARRAY* grow_array(F_ARRAY* array, CELL capacity, CELL fill);
void primitive_grow_array(void); void primitive_grow_array(void);
F_ARRAY* shrink_array(F_ARRAY* array, CELL capacity); F_ARRAY* shrink_array(F_ARRAY* array, CELL capacity);
@ -19,7 +20,7 @@ F_ARRAY* shrink_array(F_ARRAY* array, CELL capacity);
#define AREF(array,index) ((CELL)(array) + sizeof(F_ARRAY) + (index) * CELLS) #define AREF(array,index) ((CELL)(array) + sizeof(F_ARRAY) + (index) * CELLS)
#define ASIZE(pointer) align8(sizeof(F_ARRAY) + \ #define ASIZE(pointer) align8(sizeof(F_ARRAY) + \
((F_ARRAY*)(pointer))->capacity * CELLS) untag_fixnum_fast(((F_ARRAY*)(pointer))->capacity) * CELLS)
void fixup_array(F_ARRAY* array); void fixup_array(F_ARRAY* array);
void collect_array(F_ARRAY* array); void collect_array(F_ARRAY* array);

View File

@ -135,6 +135,7 @@ typedef unsigned char BYTE;
#include "image.h" #include "image.h"
#include "primitives.h" #include "primitives.h"
#include "vector.h" #include "vector.h"
#include "hashtable.h"
#include "stack.h" #include "stack.h"
#include "compiler.h" #include "compiler.h"
#include "relocate.h" #include "relocate.h"

View File

@ -71,6 +71,9 @@ INLINE void collect_object(CELL scan)
case ARRAY_TYPE: case ARRAY_TYPE:
collect_array((F_ARRAY*)scan); collect_array((F_ARRAY*)scan);
break; break;
case HASHTABLE_TYPE:
collect_hashtable((F_HASHTABLE*)scan);
break;
case VECTOR_TYPE: case VECTOR_TYPE:
collect_vector((F_VECTOR*)scan); collect_vector((F_VECTOR*)scan);
break; break;

View File

@ -27,6 +27,9 @@ INLINE void copy_object(CELL* handle)
if(tag == FIXNUM_TYPE) if(tag == FIXNUM_TYPE)
return; return;
if(headerp(pointer))
critical_error("Asked to copy header",pointer);
header = get(UNTAG(pointer)); header = get(UNTAG(pointer));
if(TAG(header) == GC_COLLECTED) if(TAG(header) == GC_COLLECTED)
newpointer = UNTAG(header); newpointer = UNTAG(header);

33
native/hashtable.c Normal file
View File

@ -0,0 +1,33 @@
#include "factor.h"
F_HASHTABLE* hashtable(F_FIXNUM capacity)
{
F_HASHTABLE* hash;
if(capacity < 0)
general_error(ERROR_NEGATIVE_ARRAY_SIZE,tag_fixnum(capacity));
hash = allot_object(HASHTABLE_TYPE,sizeof(F_VECTOR));
hash->count = tag_fixnum(0);
hash->array = tag_object(array(capacity,F));
return hash;
}
void primitive_hashtable(void)
{
maybe_garbage_collection();
drepl(tag_object(hashtable(to_fixnum(dpeek()))));
}
void primitive_to_hashtable(void)
{
type_check(HASHTABLE_TYPE,dpeek());
}
void fixup_hashtable(F_HASHTABLE* hashtable)
{
data_fixup(&hashtable->array);
}
void collect_hashtable(F_HASHTABLE* hashtable)
{
copy_object(&hashtable->array);
}

15
native/hashtable.h Normal file
View File

@ -0,0 +1,15 @@
typedef struct {
/* always tag_header(HASHTABLE_TYPE) */
CELL header;
/* tagged */
CELL count;
/* tagged */
CELL array;
} F_HASHTABLE;
F_HASHTABLE* hashtable(F_FIXNUM capacity);
void primitive_hashtable(void);
void primitive_to_hashtable(void);
void fixup_hashtable(F_HASHTABLE* hashtable);
void collect_hashtable(F_HASHTABLE* hashtable);

View File

@ -168,11 +168,14 @@ void* primitives[] = {
primitive_to_vector, primitive_to_vector,
primitive_to_string, primitive_to_string,
primitive_to_word, primitive_to_word,
primitive_to_hashtable,
primitive_slot, primitive_slot,
primitive_set_slot, primitive_set_slot,
primitive_integer_slot, primitive_integer_slot,
primitive_set_integer_slot, primitive_set_integer_slot,
primitive_grow_array primitive_grow_array,
primitive_hashtable,
primitive_array
}; };
CELL primitive_to_xt(CELL primitive) CELL primitive_to_xt(CELL primitive)

View File

@ -10,6 +10,9 @@ void relocate_object(CELL relocating)
case ARRAY_TYPE: case ARRAY_TYPE:
fixup_array((F_ARRAY*)relocating); fixup_array((F_ARRAY*)relocating);
break; break;
case HASHTABLE_TYPE:
fixup_hashtable((F_HASHTABLE*)relocating);
break;
case VECTOR_TYPE: case VECTOR_TYPE:
fixup_vector((F_VECTOR*)relocating); fixup_vector((F_VECTOR*)relocating);
break; break;

View File

@ -83,7 +83,7 @@ typedef long bignum_length_type;
#define BIGNUM_START_PTR(bignum) \ #define BIGNUM_START_PTR(bignum) \
((BIGNUM_TO_POINTER (bignum)) + 1) ((BIGNUM_TO_POINTER (bignum)) + 1)
#define BIGNUM_LENGTH(bignum) ((bignum)->capacity - 1) #define BIGNUM_LENGTH(bignum) (untag_fixnum_fast((bignum)->capacity) - 1)
#define BIGNUM_NEGATIVE_P(bignum) (get(AREF(bignum,0)) != 0) #define BIGNUM_NEGATIVE_P(bignum) (get(AREF(bignum,0)) != 0)
#define BIGNUM_SET_NEGATIVE_P(bignum,neg) put(AREF(bignum,0),neg) #define BIGNUM_SET_NEGATIVE_P(bignum,neg) put(AREF(bignum,0),neg)

View File

@ -81,7 +81,7 @@ F_VECTOR* stack_to_vector(CELL bottom, CELL top)
F_VECTOR* v = vector(depth); F_VECTOR* v = vector(depth);
F_ARRAY* a = untag_array(v->array); F_ARRAY* a = untag_array(v->array);
memcpy(a + 1,(void*)bottom,depth * CELLS); memcpy(a + 1,(void*)bottom,depth * CELLS);
v->top = depth; v->top = tag_fixnum(depth);
return v; return v;
} }
@ -101,7 +101,7 @@ void primitive_callstack(void)
CELL vector_to_stack(F_VECTOR* vector, CELL bottom) CELL vector_to_stack(F_VECTOR* vector, CELL bottom)
{ {
CELL start = bottom; CELL start = bottom;
CELL len = vector->top * CELLS; CELL len = untag_fixnum_fast(vector->top) * CELLS;
memcpy((void*)start,untag_array(vector->array) + 1,len); memcpy((void*)start,untag_array(vector->array) + 1,len);
return start + len - CELLS; return start + len - CELLS;
} }

View File

@ -55,6 +55,9 @@ CELL untagged_object_size(CELL pointer)
case BIGNUM_TYPE: case BIGNUM_TYPE:
size = ASIZE(pointer); size = ASIZE(pointer);
break; break;
case HASHTABLE_TYPE:
size = sizeof(F_HASHTABLE);
break;
case VECTOR_TYPE: case VECTOR_TYPE:
size = sizeof(F_VECTOR); size = sizeof(F_VECTOR);
break; break;

View File

@ -27,6 +27,7 @@ CELL T;
#define F_TYPE 9 #define F_TYPE 9
#define F RETAG(0,OBJECT_TYPE) #define F RETAG(0,OBJECT_TYPE)
#define HASHTABLE_TYPE 10
#define VECTOR_TYPE 11 #define VECTOR_TYPE 11
#define STRING_TYPE 12 #define STRING_TYPE 12
#define SBUF_TYPE 13 #define SBUF_TYPE 13

View File

@ -6,7 +6,7 @@ F_VECTOR* vector(F_FIXNUM capacity)
if(capacity < 0) if(capacity < 0)
general_error(ERROR_NEGATIVE_ARRAY_SIZE,tag_fixnum(capacity)); general_error(ERROR_NEGATIVE_ARRAY_SIZE,tag_fixnum(capacity));
vector = allot_object(VECTOR_TYPE,sizeof(F_VECTOR)); vector = allot_object(VECTOR_TYPE,sizeof(F_VECTOR));
vector->top = 0; vector->top = tag_fixnum(0);
vector->array = tag_object(array(capacity,F)); vector->array = tag_object(array(capacity,F));
return vector; return vector;
} }

View File

@ -1,7 +1,7 @@
typedef struct { typedef struct {
/* always tag_header(VECTOR_TYPE) */ /* always tag_header(VECTOR_TYPE) */
CELL header; CELL header;
/* untagged */ /* tagged */
CELL top; CELL top;
/* tagged */ /* tagged */
CELL array; CELL array;