Skip to content

Commit fefd12c

Browse files
committed
Loot with no tail calls
1 parent 855f95b commit fefd12c

28 files changed

+35
-40
lines changed

langs/loot-new/example.rkt

Lines changed: 0 additions & 6 deletions
This file was deleted.
File renamed without changes.
Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,18 @@
4747
(match l
4848
[(Lam '() xs e) (error "Lambdas must be labelled before code gen (contact your compiler writer)")]
4949
[(Lam f xs e)
50-
(let* ((free (fvs e))
50+
(let* ((free (remq* xs (fvs e)))
5151
; leave space for RIP
5252
(env (parity (cons #f (cons #f (reverse (append xs free)))))))
5353
(seq (Label (symbol->label f))
54+
(%% "Compiling the body of the function")
55+
(%% (~a "free vars: " free))
56+
(%% (~a "args: " xs))
57+
(%% (~a "env: " env))
5458
; we need the #args on the frame, not the length of the entire
5559
; env (which may have padding)
56-
(compile-tail-e e env (length (append xs free)))
60+
; Ignore tail calls for now
61+
(compile-e e env)
5762
(Ret)))]))
5863

5964
(define (parity c)
@@ -108,7 +113,9 @@
108113

109114
; Save the environment
110115
(%% "Begin saving the env")
116+
(%% (~a "free vars: " ys))
111117
(Mov r8 (length ys))
118+
112119
(Mov (Offset rbx 8) r8)
113120
(Mov r9 rbx)
114121
(Add r9 16)
@@ -137,19 +144,6 @@
137144
; far away from r9 the next item should be
138145
(copy-env-to-heap fvs c (+ 8 i)))]))
139146

140-
;; Id CEnv -> Asm
141-
(define (compile-fun f)
142-
; Load the address of the label into rax
143-
(seq (Lea rax (symbol->label f))
144-
; Copy the value onto the heap
145-
(Mov (Offset rbx 0) rax)
146-
; Copy the heap address into rax
147-
(Mov rax rbx)
148-
; Tag the value as a proc
149-
(Or rax type-proc)
150-
; Bump the heap pointer
151-
(Add rbx 8)))
152-
153147
;; Op0 CEnv -> Asm
154148
(define (compile-prim0 p c)
155149
(match p
@@ -257,14 +251,12 @@
257251
(Or rax type-cons)
258252
(Add rbx 16))])))
259253

260-
261-
262254
;; Id [Listof Expr] CEnv -> Asm
263-
;; Here's why this code is so gross: you have to align the stack for the call
264-
;; but you have to do it *before* evaluating the arguments es, because you need
265-
;; es's values to be just above 'rsp when the call is made. But if you push
266-
;; a frame in order to align the call, you've got to compile es in a static
267-
;; environment that accounts for that frame, hence:
255+
;; Here's (part of) why this code is so gross: you have to align the stack for
256+
;; the call but you have to do it *before* evaluating the arguments es,
257+
;; because you need es's values to be just above 'rsp when the call is made.
258+
;; But if you push a frame in order to align the call, you've got to compile es
259+
;; in a static environment that accounts for that frame, hence:
268260
(define (compile-call f es c)
269261
(let* ((cnt (length es))
270262
(aligned (even? (+ cnt (length c))))
@@ -275,7 +267,7 @@
275267
(c++ (cons #f c+)))
276268
(seq
277269

278-
(%% (~a "Begin compile-call: aligned = " aligned " function: " f))
270+
(%% "Begin compile-call")
279271
; Adjust the stack for alignment, if necessary
280272
(if aligned
281273
(seq)
@@ -286,8 +278,7 @@
286278
(compile-e f c+)
287279
(%% "Push function on stack")
288280
(Push rax)
289-
290-
(%% (~a "Begin compile-es: es = " es))
281+
291282
; Generate the code for the arguments
292283
; all results will be put on the stack (compile-es does this)
293284
(compile-es es c++)
@@ -299,7 +290,7 @@
299290
(Mov rax (Offset rsp (* 8 cnt)))
300291
(assert-proc rax)
301292
(Xor rax type-proc)
302-
293+
303294
(%% "Get closure env")
304295
(copy-closure-env-to-stack)
305296
(%% "finish closure env")
@@ -326,17 +317,19 @@
326317
(define (compile-tail-call e0 es c)
327318
(let ((cnt (length es)))
328319
(seq
320+
(%% (~a "Begin compile-tail-call: function = " e0))
329321
; Generate the code for the thing being called
330322
; and push the result on the stack
331323
(compile-e e0 c)
324+
(%% "Push function on stack")
332325
(Push rax)
333326

334327
; Generate the code for the arguments
335328
; all results will be put on the stack (compile-es does this)
336329
(compile-es es (cons #f c))
337330

338331
; Reuse the stack frame (as it's a tail call)
339-
(move-args cnt (+ cnt (add1 (in-frame c))))
332+
(move-args cnt (+ cnt (+ 2 (in-frame c))))
340333

341334
; Get the function being called off the stack
342335
; Ensure it's a proc and remove the tag
@@ -347,7 +340,7 @@
347340

348341
; Bump stack pointer (this is where the tail-call
349342
; savings kick in)
350-
(Add rsp (* 8 (+ cnt (add1 (in-frame c)))))
343+
(Add rsp (* 8 (+ cnt (+ 2 (in-frame c)))))
351344

352345
(copy-closure-env-to-stack)
353346

@@ -359,6 +352,7 @@
359352
(let ((copy-loop (symbol->label (gensym 'copy_closure)))
360353
(copy-done (symbol->label (gensym 'copy_done))))
361354
(seq
355+
362356
(Mov r8 (Offset rax 8)) ; length
363357
(Mov r9 rax)
364358
(Add r9 16) ; start of env

langs/loot/example.rkt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#lang racket
2+
(begin (define (f x) (if (zero? x) 0 (f (sub1 x))))
3+
(f 1))

0 commit comments

Comments
 (0)