diff options
| author | Mirek Kratochvil <exa.exa@gmail.com> | 2023-08-15 00:20:22 +0200 |
|---|---|---|
| committer | Mirek Kratochvil <exa.exa@gmail.com> | 2023-08-15 00:20:22 +0200 |
| commit | dab08fcbc01a3f8daa683ffeae4e8cc18df08acb (patch) | |
| tree | 313b41d2b14195804b0ef774b376d8209b79b5f9 /include/apply.s | |
| parent | 6be5a28bb90b391a5842a8ce3dfc7c154100ab68 (diff) | |
| download | uskel-dab08fcbc01a3f8daa683ffeae4e8cc18df08acb.tar.gz uskel-dab08fcbc01a3f8daa683ffeae4e8cc18df08acb.tar.bz2 | |
generic applyN
Diffstat (limited to 'include/apply.s')
| -rw-r--r-- | include/apply.s | 119 |
1 files changed, 114 insertions, 5 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 |
