Skip to content

Commit

Permalink
get rid of WORDS table, have symbols carry reference to global value …
Browse files Browse the repository at this point in the history
…instead
  • Loading branch information
devyn committed Aug 16, 2023
1 parent 4d3ba93 commit 15280ed
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 124 deletions.
26 changes: 12 additions & 14 deletions stage1/memory.s
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,18 @@ drop_object:
sd s2, 16(sp) # s2 = object type
mv s1, a0
lwu s2, LISP_OBJECT_TYPE(s1)
# check type
li t0, LISP_OBJECT_TYPE_CONS
beq s2, t0, .Ldrop_object_cons
li t0, LISP_OBJECT_TYPE_STRING
beq s2, t0, .Ldrop_object_string
li t0, LISP_OBJECT_TYPE_PROCEDURE
beq s2, t0, .Ldrop_object_procedure
li t0, LISP_OBJECT_TYPE_SYMBOL
beq s2, t0, .Ldrop_object_symbol
beqz s2, .Ldrop_object_zero # most likely double free
j .Ldrop_object_end # unknown or no special handling needed
.Ldrop_object_cons:
# check for CONS
li t0, LISP_OBJECT_TYPE_CONS
bne s2, t0, .Ldrop_object_string
# release head
ld a0, LISP_CONS_HEAD(s1)
call release_object
Expand All @@ -275,30 +282,21 @@ drop_object:
call release_object
j .Ldrop_object_end
.Ldrop_object_string:
# check for STRING
li t0, LISP_OBJECT_TYPE_STRING
bne s2, t0, .Ldrop_object_procedure
# release the buffer x capacity
ld a0, LISP_STRING_BUF(s1)
ld a1, LISP_STRING_CAP(s1)
call deallocate
j .Ldrop_object_end
.Ldrop_object_procedure:
# check for PROCEDURE
li t0, LISP_OBJECT_TYPE_PROCEDURE
bne s2, t0, .Ldrop_object_end
# release data
ld a0, LISP_PROCEDURE_DATA(s1)
call release_object
j .Ldrop_object_end
.Ldrop_object_symbol:
# check for SYMBOL
li t0, LISP_OBJECT_TYPE_SYMBOL
bne s2, t0, .Ldrop_object_end
# symbols should never be released
mv a0, s1
call acquire_object
j 1f
j .Ldrop_object_ret
.Ldrop_object_zero:
# print z address and return without deallocating
li a0, 'z'
Expand All @@ -313,7 +311,7 @@ drop_object:
mv a0, s1
li a1, LISP_OBJECT_SIZE
call deallocate
1:
.Ldrop_object_ret:
ld ra, 0(sp)
ld s1, 8(sp)
ld s2, 16(sp)
Expand Down
2 changes: 1 addition & 1 deletion stage1/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct lisp_cons {
struct lisp_symbol {
char *buf;
unsigned long len; // cap = len for symbols (they must be allocated with exact size)
char hash; // for hashtables
struct lisp_object *global_value; // for lookup in global context
};

struct lisp_string {
Expand Down
2 changes: 1 addition & 1 deletion stage1/object.h.s
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

.set LISP_SYMBOL_BUF, 8
.set LISP_SYMBOL_LEN, 16
.set LISP_SYMBOL_HASH, 24
.set LISP_SYMBOL_GLOBAL_VALUE, 24

.set LISP_CONS_HEAD, 8
.set LISP_CONS_TAIL, 16
Expand Down
6 changes: 1 addition & 5 deletions stage1/symbol.s
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,8 @@ symbol_intern:
mv a1, s1
mv a2, s4
call mem_copy
# get symbol hash
mv a0, s4
mv a1, s2
call symbol_hash
# create a new object for the symbol
andi a3, a0, 0xff # LISP_SYMBOL_HASH
mv a3, zero # LISP_SYMBOL_GLOBAL_VALUE
mv a2, s2 # LISP_SYMBOL_LEN
mv a1, s4 # LISP_SYMBOL_BUF
li a0, LISP_OBJECT_TYPE_SYMBOL
Expand Down
128 changes: 32 additions & 96 deletions stage1/words.s
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,6 @@

.bss

.set WORDS_HASH_BITS, 8
.set WORDS_LEN, (1 << WORDS_HASH_BITS)

# global definitions hashtable
#
# see symbol.s, this table is organized in the same way, but the list entries are different
#
# each list is a list of associated pairs to their values
#
# for example:
#
# ((add . <0x10000>) (sub . <0x10100>))
.global WORDS
WORDS: .skip WORDS_LEN * 8

.section .rodata

# The initial words list is a packed efficient format consisting of variable-length records of:
Expand Down Expand Up @@ -278,12 +263,6 @@ INITIAL_WORDS:
.ascii "unbox-integer$"
.balign 8

.quad WORDS
.byte 6
.byte LISP_OBJECT_TYPE_INTEGER
.ascii "words$"
.balign 8

.quad shutdown
.byte 9
.byte LISP_OBJECT_TYPE_INTEGER
Expand All @@ -303,11 +282,6 @@ words_init:
sd ra, 0x00(sp)
sd s1, 0x08(sp)
sd s2, 0x10(sp)
# zero the words table
la a0, WORDS
li a1, WORDS_LEN
mv a2, zero
call mem_set_d
# unpack the initial words table
la s1, INITIAL_WORDS
1:
Expand Down Expand Up @@ -421,7 +395,7 @@ lookup:
addi sp, sp, 0x30
ret

# Find the associated value of a symbol key in either the local words list, or global WORDS
# Find the associated value of a symbol key in either the local words list, or global value
#
# arguments:
# a0 = symbol address
Expand All @@ -441,21 +415,15 @@ lookup_var:
mv a0, a1
mv a1, s1
call lookup
bnez a0, .Llookup_var_ret_local
# if not found, check global WORDS
mv a0, s1
call get_words_ptr
ld a0, (a0) # deref value of WORDS ptr to get head of list
call acquire_object # get our own reference
mv a1, s1
ld ra, 0x00(sp)
ld s1, 0x08(sp)
addi sp, sp, 0x10
j lookup
.Llookup_var_ret_local:
# we found it locally, clean up extra symbol ref
bnez a0, .Llookup_var_ret
# if not found, return global value of the symbol
ld a0, LISP_SYMBOL_GLOBAL_VALUE(s1)
call acquire_object
mv a1, a0
.Llookup_var_ret:
# clean up the extra symbol ref
mv t0, a1
mv a0, s1
mv a0, s1 # symbol
mv s1, t0 # s1 now = found return a1
call release_object
li a0, 1
Expand All @@ -465,33 +433,6 @@ lookup_var:
addi sp, sp, 0x10
ret

# Find the pointer in the WORDS table for the given symbol address in a0
.global get_words_ptr
get_words_ptr:
addi sp, sp, -0x08
sd ra, 0x00(sp)
beqz a0, .Lget_words_ptr_error # nil => error
mv t1, a0
lwu t2, LISP_OBJECT_TYPE(t1)
li t3, LISP_OBJECT_TYPE_SYMBOL
bne t2, t3, .Lget_words_ptr_error # not symbol => error
lb a0, LISP_SYMBOL_HASH(t1)
# mask the hash to number of bits
andi a0, a0, (1 << WORDS_HASH_BITS) - 1
# times 8 (double word)
slli a0, a0, 3
j .Lget_words_ptr_ret
.Lget_words_ptr_error:
# on error just return &WORDS[0]
mv a0, zero
.Lget_words_ptr_ret:
# add WORDS offset
la t1, WORDS
add a0, a0, t1
ld ra, 0x00(sp)
addi sp, sp, 0x08
ret

# Define a new word
#
# a0 = symbol address
Expand All @@ -502,34 +443,29 @@ get_words_ptr:
# a0 = 0 (ok), -1 (error)
.global define
define:
addi sp, sp, -0x18
# check early for unacceptable arguments
beqz a0, .Ldefine_err # can't define nil
lwu t0, LISP_OBJECT_TYPE(a0)
li t1, LISP_OBJECT_TYPE_SYMBOL
bne t0, t1, .Ldefine_err # can't define other than a symbol as key
# setup stack so we can call stuff
addi sp, sp, -0x10
sd ra, 0x00(sp)
sd s1, 0x08(sp) # symbol / words ptr
sd s2, 0x10(sp) # pair
mv s1, a0
mv s2, zero
# create a new pair for (symbol . value)
call cons
beqz a0, .Ldefine_error # error
mv s2, a0
# find the ptr into WORDS and then prepend to that list
mv a0, s1 # the symbol
call get_words_ptr
mv s1, a0 # save it to s1
# create a new cons for the prepend
mv a0, s2 # pair
ld a1, (s1) # WORDS[N]
call cons
beqz a0, .Ldefine_error
mv s2, zero # used
sd a0, (s1) # WORDS[N] = new
mv a0, zero # return ok
j .Ldefine_ret
.Ldefine_error:
li a0, -1
.Ldefine_ret:
sd a0, 0x08(sp) # symbol
# swap the current global value of the symbol
ld t0, LISP_SYMBOL_GLOBAL_VALUE(a0)
sd a1, LISP_SYMBOL_GLOBAL_VALUE(a0)
# release the old value
mv a0, t0
call release_object
# release the symbol
ld a0, 0x08(sp)
call release_object
# return
li a0, 0
ld ra, 0x00(sp)
ld s1, 0x08(sp)
ld s2, 0x10(sp)
addi sp, sp, 0x18
addi sp, sp, 0x10
ret
.Ldefine_err:
li a0, -1
ret
19 changes: 12 additions & 7 deletions stage2/22-words-util.lsp
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
(define get-words (fn (index)
(let1 addr (peek.d (+ words$ (<< index 3)))
(seq
(call-native acquire-object$ 0 addr)
(deref addr))))))

;(map (fn (index) (length (get-words index))) (range 0 255))
(define global-value-of (fn (symbol)
(if (ref-eq? (type-of symbol) (quote symbol))
(let
(
(symbol-addr (ref symbol))
(global-value-addr (peek.d (+ symbol-addr 24)))
)
(seq
(call-native acquire-object$ 0 global-value-addr)
(call-native release-object$ 0 symbol-addr)
(deref global-value-addr)))
(error (quote not-a-symbol:) symbol))))

0 comments on commit 15280ed

Please sign in to comment.