(if (eq? context 'tail)
(emit-code #f (make-glil-call 'return 1)))))
+ ;; After lexical binding forms in non-tail context, call this
+ ;; function to clear stack slots, allowing their previous values to
+ ;; be collected.
+ (define (clear-stack-slots context syms)
+ (case context
+ ((push drop)
+ (for-each (lambda (v)
+ (and=>
+ ;; Can be #f if the var is labels-allocated.
+ (hashq-ref allocation v)
+ (lambda (h)
+ (pmatch (hashq-ref h self)
+ ((#t _ . ,n)
+ (emit-code #f (make-glil-void))
+ (emit-code #f (make-glil-lexical #t #f 'set n)))
+ (,loc (error "bad let var allocation" x loc))))))
+ syms))))
+
(record-case x
((<void>)
(case context
(,loc (error "bad let var allocation" x loc))))
(reverse gensyms))
(comp-tail body)
+ (clear-stack-slots context gensyms)
(emit-code #f (make-glil-unbind)))
((<letrec> src in-order? names gensyms vals body)
(,loc (error "bad letrec var allocation" x loc))))
(reverse gensyms))))
(comp-tail body)
+ (clear-stack-slots context gensyms)
(emit-code #f (make-glil-unbind)))
((<fix> src names gensyms vals body)
(comp-tail body)
(if new-RA
(emit-label new-RA))
+ (clear-stack-slots context gensyms)
(emit-code #f (make-glil-unbind))))
((<let-values> src exp body)
(,loc (error "bad let-values var allocation" x loc))))
(reverse gensyms))
(comp-tail body)
+ (clear-stack-slots context gensyms)
(emit-code #f (make-glil-unbind))))))
;; much trickier than i thought this would be, at first, due to the need
;;;; License along with this library; if not, write to the Free Software
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-(use-modules (ice-9 documentation)
- (test-suite lib))
+(define-module (test-suite tests gc)
+ #:use-module (ice-9 documentation)
+ #:use-module (test-suite lib)
+ #:use-module ((system base compile) #:select (compile)))
;;;
(add-hook! after-gc-hook thunk)
(gc)
(remove-hook! after-gc-hook thunk)
- foo)))
+ foo))
-
-(with-test-prefix "gc"
(pass-if "Unused modules are removed"
(let* ((guard (make-guardian))
(total 1000))
(stack-cleanup 20)
(gc)
- (gc) ;; twice: have to kill the weak vectors.
- (gc) ;; thrice: because the test doesn't succeed with only
- ;; one gc round. not sure why.
+ (gc) ;; twice: have to kill the weak vectors.
+ (gc) ;; thrice: because the test doesn't succeed with only
+ ;; one gc round. not sure why.
(= (let lp ((i 0))
(if (guard)
(lp (1+ i))
i))
- total))))
+ total)))
+
+ (pass-if "Lexical vars are collectable"
+ (procedure?
+ (compile
+ '(begin
+ (define guardian (make-guardian))
+ (let ((f (lambda () (display "test\n"))))
+ (guardian f))
+ (gc)(gc)(gc)
+ (guardian))))))