- ; for now we can only call closures
-(define (codegen-call closure args si env)
- (when (not (eq? (ast-type closure) 'closure))
- (error #f (format "~a is not a closure" closure)))
- (let* ((captured (caddr closure))
- (label (cadr closure))
- (argument-start (length captured)))
-
- ; first move the captured variables into param registers
+ ; a closure on the heap looks like:
+ ; 0 8 16 24
+ ; addr var1.... var2.... var3....
+
+(define (codegen-closure label captured si env)
+ (let* ((heap-offsets (map (lambda (i) (+ 8 (* 8 i)))
+ (range 0 (length captured))))) ; 4, 12, 20, etc.
+
+ (emit "## creating closure")
+
+ (emit "movq heap_start@GOTPCREL(%rip), %rbx")
+
+ (emit "movq (%rbx), %rax") ; %rax = heap addr of closure
+
+
+ ; point heap_start to next space
+ (emit "addq $~a, (%rbx)" (+ 8 (* 8 (length captured))))
+
+ (emit "## storing address to lambda")
+ ; store the address to the lambda code
+ (emit "movq ~a@GOTPCREL(%rip), %rbx" label)
+ (emit "movq %rbx, 0(%rax)")
+
+ (emit "## storing captives")
+ ; store the captured vars