Skip to content

Commit 257d829

Browse files
committed
Checking lvar during pass2 inline local (Fixes #286)
1 parent 25fb391 commit 257d829

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

boot/lib/pass2.scm

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
(penv (pass2/collect-inlinables iform)))
2929
(pass2/rec iform (acons 'library library penv) #t)))
3030

31+
(define (expand-lvars penv lvars)
32+
(define (pred p) (and (pair? p) (eq? (car p) 'lvars)))
33+
(let ((old (cond ((memp pred penv) => cdar)
34+
(else '()))))
35+
(acons 'lvars `(,@lvars ,@old) (remp pred penv))))
36+
3137
;; dispatch table is defined after all all method are defined.
3238
(define (pass2/rec iform penv tail?)
3339
((vector-ref *pass2-dispatch-table* (iform-tag iform))
@@ -298,7 +304,7 @@
298304

299305
(receive (lvars inits) (process-inits ($let-lvars iform) ($let-inits iform))
300306
(ifor-each2 (lambda (lv in) (lvar-initval-set! lv in)) lvars inits)
301-
(let ((obody (pass2/rec ($let-body iform) penv tail?)))
307+
(let ((obody (pass2/rec ($let-body iform) (expand-lvars penv lvars) tail?)))
302308
(ifor-each2 pass2/optimize-closure lvars inits)
303309
(pass2/shrink-let-frame iform lvars obody))))
304310

@@ -410,16 +416,17 @@
410416
(let loop ((env env))
411417
(cond ((null? env) #t)
412418
((eq? (car env) lambda-node) #t)
413-
((eq? ($lambda-flag (car env)) 'dissolved)
419+
((and (vector? (car env))
420+
($lambda? (car env))
421+
(eq? ($lambda-flag (car env)) 'dissolved))
414422
(loop (cdr env))) ;; skip dissolved (inlined) lamdas
415423
(else #f))))
416424
(let loop ((call&envs call&envs)
417425
(local '())
418426
(rec '())
419427
(trec '()))
420428
(smatch call&envs
421-
(()
422-
(values local rec trec))
429+
(() (values local rec trec))
423430
(((call . env) . more)
424431
(case ($call-flag call)
425432
((tail-rec)
@@ -497,12 +504,16 @@
497504

498505
(define-p2-backtracible (pass2/$LAMBDA iform penv tail?)
499506
($lambda-body-set! iform (pass2/rec ($lambda-body iform)
500-
(cons iform penv) #t))
507+
(expand-lvars (cons iform penv)
508+
($lambda-lvars iform))
509+
#t))
501510
iform)
502511

503512
(define-p2-backtracible (pass2/$RECEIVE iform penv tail?)
504513
($receive-expr-set! iform (pass2/rec ($receive-expr iform) penv #f))
505-
($receive-body-set! iform (pass2/rec ($receive-body iform) penv tail?))
514+
($receive-body-set! iform (pass2/rec ($receive-body iform)
515+
(expand-lvars penv ($receive-lvars iform))
516+
tail?))
506517
iform)
507518

508519
;; $LABEL' body should already be processed by pass2.
@@ -554,16 +565,15 @@
554565
($call-proc-set! iform (pass2/rec proc penv #f))
555566
(cond
556567
((vm-noinline-locals?)
557-
($call-args-set! iform (imap (lambda (arg)
558-
(pass2/rec arg penv #f)) args))
568+
($call-args-set! iform
569+
(imap (lambda (arg) (pass2/rec arg penv #f)) args))
559570
iform)
560571
(($lambda? proc) ;; ((lambda (...) ...) arg ...)
561572
;; ((lambda (var ...) body) arg ...)
562573
;; -> (let ((var arg) (... ...)) body)
563574
(pass2/rec (expand-inlined-procedure ($*-src iform) proc args)
564575
penv tail?))
565-
((and ($lref? proc)
566-
(pass2/head-lref proc penv tail?))
576+
((and ($lref? proc) (pass2/head-lref proc penv tail?))
567577
=> (lambda (result)
568578
(cond
569579
((vector? result)
@@ -650,7 +660,8 @@
650660
(define (pass2/head-lref iform penv tail?)
651661
(let* ((lvar ($lref-lvar iform))
652662
(initval (lvar-initval lvar)))
653-
(and (zero? (lvar-set-count lvar))
663+
(and (pass2/known-lvar lvar penv)
664+
(zero? (lvar-set-count lvar))
654665
(vector? initval)
655666
(has-tag? initval $LAMBDA)
656667
;; (let ((lref (lambda ...))) body)
@@ -664,6 +675,9 @@
664675
initval)
665676
(else 'local)))))
666677

678+
(define (pass2/known-lvar lvar penv)
679+
(memq lvar (cond ((assq 'lvars penv) => cdr) (else '()))))
680+
667681
(define (pass2/self-recursing? node penv) (memq node penv))
668682

669683
(define-p2-backtracible (pass2/$ASM iform penv tail?)

test/tests/sagittarius.scm

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,6 +2442,18 @@
24422442
(test-equal "version = (sagittarius-version)" "ok"
24432443
(test-cond-expand-version (version (= (sagittarius-version))) "ok"))
24442444

2445+
(let ()
2446+
(define expr
2447+
'(define (double-y)
2448+
(let ((plus-y (lambda (x) (+ x y))))
2449+
;;(set! plus-y (lambda (x) (+ x y)))
2450+
(let-syntax ((macro (lambda (x)
2451+
(syntax-case x ()
2452+
((_ a) #`(+ a #,(plus-y 0)))))))
2453+
(macro y)))))
2454+
(test-error "meta 1 reference on local variable"
2455+
(eval expr (environment '(rnrs)))))
2456+
24452457
;; compiler/macro expander
24462458
(let ()
24472459
(define-syntax foo

0 commit comments

Comments
 (0)