+ ; now that we have everything we need on the stack,
+ ; move them into the param registers
+
+ (emit "## moving args into place")
+ (for-each
+ (lambda (i) (emit "movq ~a(%rbp), ~a"
+ (- si (* wordsize i))
+ (param-register i)))
+ (range 1 (length args)))
+
+ ; todo: can this be made more efficient
+ (emit "movq ~a(%rbp), %rax" si) ; load back pointer to closure
+
+ (emit "## moving captives into place")
+
+ ; move captives into first argument
+ (emit "movq %rax, %rbx")
+ (emit "addq $8, %rbx")
+ (emit "movq %rbx, ~a" (param-register 0))
+
+ (emit "## performing call")
+
+ (emit "addq $~a, %rsp" si) ; adjust the stack pointer to account all the stuff we put in the env
+ (emit "callq *(%rax)") ; call closure function
+ (emit "subq $~a, %rsp" si))
+
+ ; LAMBDAS:
+ ; 1st param: pointer to captured args
+ ; 2nd param: 1st arg
+ ; 3rd param: 2nd arg, etc.