|
28 | 28 | (penv (pass2/collect-inlinables iform))) |
29 | 29 | (pass2/rec iform (acons 'library library penv) #t))) |
30 | 30 |
|
| 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 | + |
31 | 37 | ;; dispatch table is defined after all all method are defined. |
32 | 38 | (define (pass2/rec iform penv tail?) |
33 | 39 | ((vector-ref *pass2-dispatch-table* (iform-tag iform)) |
|
298 | 304 |
|
299 | 305 | (receive (lvars inits) (process-inits ($let-lvars iform) ($let-inits iform)) |
300 | 306 | (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?))) |
302 | 308 | (ifor-each2 pass2/optimize-closure lvars inits) |
303 | 309 | (pass2/shrink-let-frame iform lvars obody)))) |
304 | 310 |
|
|
410 | 416 | (let loop ((env env)) |
411 | 417 | (cond ((null? env) #t) |
412 | 418 | ((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)) |
414 | 422 | (loop (cdr env))) ;; skip dissolved (inlined) lamdas |
415 | 423 | (else #f)))) |
416 | 424 | (let loop ((call&envs call&envs) |
417 | 425 | (local '()) |
418 | 426 | (rec '()) |
419 | 427 | (trec '())) |
420 | 428 | (smatch call&envs |
421 | | - (() |
422 | | - (values local rec trec)) |
| 429 | + (() (values local rec trec)) |
423 | 430 | (((call . env) . more) |
424 | 431 | (case ($call-flag call) |
425 | 432 | ((tail-rec) |
|
497 | 504 |
|
498 | 505 | (define-p2-backtracible (pass2/$LAMBDA iform penv tail?) |
499 | 506 | ($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)) |
501 | 510 | iform) |
502 | 511 |
|
503 | 512 | (define-p2-backtracible (pass2/$RECEIVE iform penv tail?) |
504 | 513 | ($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?)) |
506 | 517 | iform) |
507 | 518 |
|
508 | 519 | ;; $LABEL' body should already be processed by pass2. |
|
554 | 565 | ($call-proc-set! iform (pass2/rec proc penv #f)) |
555 | 566 | (cond |
556 | 567 | ((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)) |
559 | 570 | iform) |
560 | 571 | (($lambda? proc) ;; ((lambda (...) ...) arg ...) |
561 | 572 | ;; ((lambda (var ...) body) arg ...) |
562 | 573 | ;; -> (let ((var arg) (... ...)) body) |
563 | 574 | (pass2/rec (expand-inlined-procedure ($*-src iform) proc args) |
564 | 575 | penv tail?)) |
565 | | - ((and ($lref? proc) |
566 | | - (pass2/head-lref proc penv tail?)) |
| 576 | + ((and ($lref? proc) (pass2/head-lref proc penv tail?)) |
567 | 577 | => (lambda (result) |
568 | 578 | (cond |
569 | 579 | ((vector? result) |
|
650 | 660 | (define (pass2/head-lref iform penv tail?) |
651 | 661 | (let* ((lvar ($lref-lvar iform)) |
652 | 662 | (initval (lvar-initval lvar))) |
653 | | - (and (zero? (lvar-set-count lvar)) |
| 663 | + (and (pass2/known-lvar lvar penv) |
| 664 | + (zero? (lvar-set-count lvar)) |
654 | 665 | (vector? initval) |
655 | 666 | (has-tag? initval $LAMBDA) |
656 | 667 | ;; (let ((lref (lambda ...))) body) |
|
664 | 675 | initval) |
665 | 676 | (else 'local))))) |
666 | 677 |
|
| 678 | +(define (pass2/known-lvar lvar penv) |
| 679 | + (memq lvar (cond ((assq 'lvars penv) => cdr) (else '())))) |
| 680 | + |
667 | 681 | (define (pass2/self-recursing? node penv) (memq node penv)) |
668 | 682 |
|
669 | 683 | (define-p2-backtracible (pass2/$ASM iform penv tail?) |
|
0 commit comments