aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/apply.s119
-rw-r--r--include/macros.s14
2 files changed, 118 insertions, 15 deletions
diff --git a/include/apply.s b/include/apply.s
index 2b88dd0..0a0457d 100644
--- a/include/apply.s
+++ b/include/apply.s
@@ -1,6 +1,8 @@
.include "include/data.s"
+#TODO apply1 seems obsolete by generic apply
+
# | fun | arg | -> cont
.thunkcode apply1
thunkto %rsi, $apply1_fini, $3, 030(%rbp), %rbp, %rsi
@@ -15,15 +17,15 @@
# 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
+ lea (%rdx, %r11, 010), %rbx # address behind the last arg
cmp %rdx, %rbx
- jle apply1_fini_cont
+ jbe 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
+ ja apply1_fini_copy # if not, continue
apply1_fini_cont:
add $1, %r11
pushq %r11 # new number of args of fun/thunk
@@ -35,7 +37,7 @@ apply1_fini_cont:
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
+ ja 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.
@@ -55,4 +57,111 @@ apply1_fini_feed:
mov %rsp, %rsi # return the new FUN
enter 040(%rbp) # jump to the continuation
-# TODO generalize to N args
+# | fun | arg[1] | arg[2] | ... | arg[args-1] | -> cont
+.thunkcode apply
+ thunkto %rsi, $apply_fini, $2, %rbp, %rsi
+ enter 020(%rbp)
+
+# fun -> | ret (with args) | cont |
+.thunkcode apply_fini
+ mov (%rsi), %r9 # infotable for the original function
+ mov 020(%rbp), %r10 # the original thunk
+ mov 020(%rsi), %r11 # amount of args applied in the closure
+ mov -010(%r9), %r12 # amount of args required to make a thunk
+ mov 010(%r10), %r13 # amount of args in the original thunk
+ sub $1, %r13 # amount of args we want to apply (the 1st one is the FUN)
+
+ mov %r11, %r14
+ add %r13, %r14
+ cmp %r12, %r14 # do we have enough arguments?
+ ja apply_fini_o
+
+apply_fini_pt:
+ # not enough args or exactly enough args.
+ # Basically make a function or a thunk that is almost the same.
+
+ # first move thunk params
+ mov %r13, %rcx
+ cmp $0, %rcx
+ jz apply_fini_pt_thunk_skip
+ lea 030(%r10, %r13, 010), %rdx
+ apply_fini_pt_thunk_copy:
+ sub $010, %rdx
+ pushq (%rdx)
+ loop apply_fini_pt_thunk_copy
+ apply_fini_pt_thunk_skip:
+
+ # now move the fun params
+ mov %r11, %rcx
+ cmp $0, %rcx
+ jz apply_fini_pt_fun_skip
+ lea 030(%rsi, %r11, 010), %rdx
+ apply_fini_pt_fun_copy:
+ sub $010, %rdx
+ pushq (%rdx)
+ loop apply_fini_pt_fun_copy
+ apply_fini_pt_fun_skip:
+
+ # make a thunk
+ thunk 010(%rsi), %r14
+ cmp %r12, %r14 # are we precisely at the right amount of arguments for a thunk?
+ je apply_fini_pt_thunk # if not wrap a closure
+ apply_fini_pt_closure:
+ thunkto %rsi, %r9
+
+ # replace the original thunk with an indirect
+ mov %rsi, 010(%r10)
+ movq $IND_code, (%r10)
+ # return the closure (%rsi) to the original continuation
+ enter 030(%rbp)
+
+ apply_fini_pt_thunk:
+ # it is a thunk, point to it and start evaluating it
+ mov %rsp, 010(%r10)
+ movq $IND_code, (%r10)
+ # tell the thunk to evaluate into the original continuation
+ mov 030(%rbp), %rsi
+ enter %rsp
+
+apply_fini_o: #TODO needs to be tested
+ # too many args, we need to split off a bit
+ # first move just the right amount of args off the thunk
+ mov %r12, %rcx
+ sub %r11, %rcx
+ lea 030(%r10, %rcx, 010), %rdx
+ apply_fini_o_tc_copy:
+ sub $010, %rdx
+ pushq (%rdx)
+ loop apply_fini_o_tc_copy
+
+ # move all args from the closure
+ mov %r11, %rcx
+ lea 030(%rsi, %r11, 010), %rdx
+ apply_fini_o_fun_copy:
+ sub $010, %rdx
+ pushq (%rdx)
+ loop apply_fini_o_fun_copy
+
+ # make the thunk for the application that can be evaluated later
+ thunkto %r15, 010(%rsi), %r14
+
+ # now make a thunk with the rest of the stuff
+ mov %r14, %rcx
+ sub %r12, %rcx
+ mov %rcx, %r14 #backup leftover count for later
+ lea 030(%r10, %r13, 010), %rdx
+ apply_fini_o_tt_copy:
+ sub $010, %rdx
+ pushq (%rdx)
+ loop apply_fini_o_tt_copy
+
+ # finish the leftovers thunk
+ add $1, %r14 # (1 fun to apply to + args)
+ thunk $apply,%r14,%r15
+
+ # replace the original thunk with an indirect
+ mov %rsp, 010(%r10)
+ movq $IND_code, (%r10)
+ # evaluate to the original continuation
+ mov 030(%rbp), %rsi
+ enter %rsp
diff --git a/include/macros.s b/include/macros.s
index c52f6b0..051f147 100644
--- a/include/macros.s
+++ b/include/macros.s
@@ -39,21 +39,15 @@ _macros_s_file:
\name:
.endm
-.macro thunkargs arg,args:vararg
+.macro thunk arg,args:vararg
.ifnb \arg
- thunkargs \args
+ thunk \args
pushq \arg
.endif
.endm
-.macro thunk code:req,n:req,args:vararg
- thunkargs \args
- pushq \n
- pushq \code
-.endm
-
-.macro thunkto reg:req,code:req,n:req,args:vararg
- thunk \code,\n,\args
+.macro thunkto reg:req,args:vararg
+ thunk \args
mov %rsp, \reg
.endm