diff options
Diffstat (limited to 'include/apply.s')
| -rw-r--r-- | include/apply.s | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/include/apply.s b/include/apply.s new file mode 100644 index 0000000..124e434 --- /dev/null +++ b/include/apply.s @@ -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 |
