|
78 | 78 | [`(if ,e0 ,e1 ,e2) (compile-tail-if e0 e1 e2 c)] |
79 | 79 | [`(+ ,e0 ,e1) (compile-+ e0 e1 c)] |
80 | 80 | [`(let ((,x ,e0)) ,e1) (compile-tail-let x e0 e1 c)] |
81 | | - [`(letrec ,bs ,e0) (compile-tail-letrec (map first bs) (map second bs) e0 c)] |
| 81 | + [`(letrec ,bs ,e0) (compile-tail-letrec (map first bs) (map second bs) e0 c)] |
82 | 82 | [`(λ ,xs ',l ,e0) (compile-λ xs l (fvs e) c)] |
83 | 83 | [`(,e . ,es) (compile-tail-call e es c)])) |
84 | 84 |
|
|
109 | 109 | `(;; Save label address |
110 | 110 | (lea rax (offset ,f 0)) |
111 | 111 | (mov (offset rdi 0) rax) |
112 | | - |
| 112 | + |
113 | 113 | ;; Save the environment |
114 | 114 | (mov r8 ,(length ys)) |
115 | 115 | (mov (offset rdi 1) r8) |
116 | 116 | (mov r9 rdi) |
117 | 117 | (add r9 16) |
118 | 118 | ,@(copy-env-to-heap ys c 0) |
119 | | - |
| 119 | + |
120 | 120 | ;; Return a pointer to the closure |
121 | 121 | (mov rax rdi) |
122 | 122 | (or rax ,type-proc) |
|
153 | 153 | (mov rax (offset rsp ,i)) |
154 | 154 | ,@assert-proc |
155 | 155 | (xor rax ,type-proc) |
156 | | - (sub rsp ,stack-size) |
157 | | - ,@(copy-closure-env-to-stack (add1 (length es))) |
158 | | - (call (offset rax 0)) |
| 156 | + (sub rsp ,stack-size) |
| 157 | + |
| 158 | + (mov rcx rsp) ; start of stack in rcx |
| 159 | + (add rcx ,(- (* 8 (+ 2 (length es))))) |
| 160 | + ,@(copy-closure-env-to-stack) |
| 161 | + |
| 162 | + (call (offset rax 0)) |
159 | 163 | (add rsp ,stack-size)))) |
160 | 164 |
|
161 | 165 | ;; LExpr (Listof LExpr) CEnv -> Asm |
|
170 | 174 | ,@(move-args (length es) i) |
171 | 175 | ,@assert-proc |
172 | 176 | (xor rax ,type-proc) |
173 | | - ,@(copy-closure-env-to-stack (length es)) |
| 177 | + |
| 178 | + (mov rcx rsp) ; start of stack in rcx |
| 179 | + (add rcx ,(- (* 8 (+ 1 (length es))))) |
| 180 | + ,@(copy-closure-env-to-stack) |
| 181 | + |
| 182 | + ;,@(copy-closure-env-to-stack (length es)) |
174 | 183 | (jmp (offset rax 0))))) |
175 | 184 |
|
| 185 | +;; -> Asm |
| 186 | +;; Copy closure's (in rax) env to stack in rcx |
| 187 | +(define (copy-closure-env-to-stack) |
| 188 | + (let ((copy-loop (gensym 'copy_closure)) |
| 189 | + (copy-done (gensym 'copy_done))) |
| 190 | + `((mov r8 (offset rax 1)) ; length |
| 191 | + (mov r9 rax) |
| 192 | + (add r9 16) ; start of env |
| 193 | + ,copy-loop |
| 194 | + (cmp r8 0) |
| 195 | + (je ,copy-done) |
| 196 | + (mov rbx (offset r9 0)) |
| 197 | + (mov (offset rcx 0) rbx) |
| 198 | + (sub r8 1) |
| 199 | + (add r9 8) |
| 200 | + (sub rcx 8) |
| 201 | + (jmp ,copy-loop) |
| 202 | + ,copy-done))) |
| 203 | +#| |
176 | 204 | ;; Natural -> Asm |
177 | 205 | ;; Copy closure's (in rax) env to stack skipping n spots |
178 | 206 | (define (copy-closure-env-to-stack n) |
|
185 | 213 | (add rcx ,(- (* 8 (add1 n)))) |
186 | 214 | ,copy-loop |
187 | 215 | (cmp r8 0) |
188 | | - (je ,copy-done) |
189 | | - (mov rbx (offset r9 0)) |
| 216 | + (je ,copy-done) |
| 217 | + (mov rbx (offset r9 0)) |
190 | 218 | (mov (offset rcx 0) rbx) |
191 | 219 | (sub r8 1) |
192 | 220 | (add r9 8) |
193 | | - (sub rcx 8) |
| 221 | + (sub rcx 8) |
194 | 222 | (jmp ,copy-loop) |
195 | 223 | ,copy-done))) |
| 224 | +|# |
196 | 225 |
|
197 | 226 | ;; (Listof Variable) (Listof Lambda) Expr CEnv -> Asm |
198 | | -(define (compile-letrec fs ls e c) |
| 227 | +(define (compile-letrec fs ls e c) |
199 | 228 | (let ((c0 (compile-letrec-λs ls c)) |
200 | 229 | (c1 (compile-letrec-init fs ls (append (reverse fs) c))) |
201 | 230 | (c2 (compile-e e (append (reverse fs) c)))) |
|
0 commit comments