This commit is contained in:
Mirek Kratochvil 2023-08-11 22:30:22 +02:00
parent 74cad99337
commit 5184299c7d
6 changed files with 159 additions and 16 deletions

47
apply.s Normal file
View file

@ -0,0 +1,47 @@
.include "include/uskel.s"
.include "include/apply.s"
.include "include/intops.s"
.include "include/io.s"
.include "include/main_exit.s"
main:
# make an integer
pushq $1
pushq $INT_code
mov %rsp, %r11
# make a closure for adding stuff
pushq $0
pushq $plus
pushq $FUN2_code
mov %rsp, %r12
# apply first argument
push %r11
push %r12
pushq $2
pushq $apply1
mov %rsp, %r12
# apply second argument (the p.a. function part is still in r12)
push %r11
push %r12
pushq $2
pushq $apply1
mov %rsp, %r12
# print the result
push %r12
pushq $1
pushq $print
mov %rsp, %r12
# make the continuation for main (exit)
push %rsi
pushq $1
pushq $main_exit
mov %rsp, %rsi
enter %r12

65
include/apply.s Normal file
View file

@ -0,0 +1,65 @@
.include "include/data.s"
# | fun | arg | -> cont
.thunkcode apply1
# push a thunk for eval
push %rsi # cont
push %rbp # ret (self)
pushq 030(%rbp) # arg
pushq $3
pushq $apply1_fini
mov %rsp, %rsi # return to above thunk
enter 020(%rbp) # evaluate fun
# fun -> | arg | ret | cont |
.thunkcode apply1_fini
# we now know that fun points to a FUN with at least one arg missing.
# we're certainly going to copy a lot of args.
mov 020(%rsi), %r11 # amount of args applied now
# the copying code is shared so let's do that first:
pushq 020(%rbp) #push the new arg
lea 030(%rsi), %rdx # the end (first arg)
lea (%rdx, %r11, 8), %rbx # address behind the last arg
cmp %rdx, %rbx
jle apply1_fini_cont
apply1_fini_copy:
sub $010, %rbx # iterate down
pushq (%rbx) # push what we have
cmp %rdx, %rbx # check if we are at the end
jg apply1_fini_copy # if not, continue
apply1_fini_cont:
add $1, %r11
pushq %r11 # new number of args of fun/thunk
pushq 010(%rsi) # thunk code pointer
# copying of all args and their thunky header is now done, let's find
# out how we need to finish it.
mov (%rsi), %rdi # infotable for the original fun
mov -010(%rdi), %r12 # amount of args required to make the thunk
cmp %r11, %r12
jg apply1_fini_feed # not enough args, just make a bigger FUN
# if there was enough args, we simply have a thunk that we want to
# continue evaluating, so let's jump to it.
mov 030(%rbp), %rdi # load the original thunk
mov %rsp, 010(%rdi) # set indirect to the new thunk
movq $IND_code, 0(%rdi)
mov 040(%rbp), %rsi # set continuation to the original continuation
enter %rsp # evaluate the new thunk
apply1_fini_feed:
# if there were not enough args, we push the function info and return
pushq (%rsi) # copy the function infoptr
mov 030(%rbp), %rdi # load the original thunk
mov %rsp, 010(%rdi) # set the indirect to the new FUN
movq $IND_code, 0(%rdi)
mov %rsp, %rsi # return the new FUN
enter 040(%rbp) # jump to the continuation
# TODO generalize to N args

View file

@ -5,10 +5,18 @@ _data_s_file:
# Simple values and boxed machine integers
# | ptr | value |
CON_evacuate1:
retq
retq # TODO
CON_scavenge1:
add $0x10, %rsi
retq
# Format of the info tables:
# - code
# ----- code pointer
# - 8B helper information for eval/apply (generally this is 0, and only gets used for FUN/PAP)
# - 8B pointer to scavenge
# - 8B pointer to evacuate
INT_info_table:
cell CON_evacuate1
cell CON_scavenge1
@ -36,7 +44,7 @@ LIST_info_table:
LIST_code:
continue
# FUN/PAP combo objects
# FUN objects
# | ptr | thunkptr | args | arg[0] | arg[1] | ... | arg[args] |
FUN_evacuate:
retq #TODO
@ -47,29 +55,44 @@ FUN_scavenge:
add %rax, %rsi
retq
# Simple info for n-ary functions
# TODO continue to add as required
fun1_info_table:
# Info tables for FUN objects.
FUN0_info_table:
cell FUN_evacuate
cell FUN_scavenge
cell 0
FUN0_code:
continue
FUN1_info_table:
cell FUN_evacuate
cell FUN_scavenge
cell 1
fun1_code:
FUN1_code:
continue
fun2_info_table:
FUN2_info_table:
cell FUN_evacuate
cell FUN_scavenge
cell 2
fun2_code:
FUN2_code:
continue
fun3_info_table:
FUN3_info_table:
cell FUN_evacuate
cell FUN_scavenge
cell 3
fun3_code:
FUN3_code:
continue
FUN4_info_table:
cell FUN_evacuate
cell FUN_scavenge
cell 4
FUN4_code:
continue
# TODO: add more funN here as needed
# indirection (Q: how to recognize IND and THUNK on return?)
# | ptr | indptr |
IND_evacuate:
@ -97,3 +120,9 @@ THU_scavenge:
retq
.endif # _data_s_file
# evacuate and scavenge:
# - evacuate just copies the object
# - scavenge evacuates all children (to the new location IF they are in the old
# location), changes the pointer, and moves the scavenge pointer to the next
# object (because everything needs to be scavenged)

View file

@ -16,9 +16,8 @@ _macros_s_file:
.endm
.macro continue
mov %rsi, %rax
mov %rbp, %rsi
enter %rax
xchg %rsi, %rbp
enter_rbp
.endm
.macro thunkenv arg, dest

View file

@ -3,8 +3,11 @@ _main_exit_s_file:
# exitcode -> | cont (unused, should be 0) |
.thunkcode main_exit
mov 0x8(%rsi), %rdi # result to syscall exitcode
mov $0x3c, %rax # syscall 60
mov 010(%rsi), %rdi # result goes to syscall exitcode
mov $60, %rax # exit=60
syscall # exit %rdi
# TODO this is a "case" kind of thunk so it's quite likely that it really
# doesn't need the continuation.
.endif # _main_exit_s_file

View file

@ -10,7 +10,7 @@ _primops_s_file:
# push a thunk for finishing the plus
push %rsi # cont
push %rbp # ret (self)
pushq 030(%rbp)
pushq 030(%rbp) # arg2
pushq $3
pushq $\name\()_step1