@@ -4338,7 +4338,7 @@ f(x) = yt(x)
43384338 (car s)
43394339 (loop (cdr s))))))
43404340 `(pop_exception ,restore-token))))
4341- (define (emit-return x)
4341+ (define (emit-return tail x)
43424342 (define (emit- x)
43434343 (let* ((tmp (if ((if (null? catch-token-stack) valid-ir-return? simple-atom?) x)
43444344 #f
@@ -4347,8 +4347,12 @@ f(x) = yt(x)
43474347 (begin (emit `(= ,tmp ,x)) tmp)
43484348 x)))
43494349 (define (actually-return x)
4350- (let* ((x (if rett
4351- (compile (convert-for-type-decl (emit- x) rett #t lam) '() #t #f)
4350+ (let* ((x (begin0 (emit- x)
4351+ ;; if we are adding an implicit return then mark it as having no location
4352+ (if (not (eq? tail 'explicit))
4353+ (emit '(line #f)))))
4354+ (x (if rett
4355+ (compile (convert-for-type-decl x rett #t lam) '() #t #f)
43524356 x))
43534357 (x (emit- x)))
43544358 (let ((pexc (pop-exc-expr catch-token-stack '())))
@@ -4487,7 +4491,7 @@ f(x) = yt(x)
44874491 (eq? (car e) 'globalref))
44884492 (underscore-symbol? (cadr e)))))
44894493 (error (string "all-underscore identifier used as rvalue" (format-loc current-loc))))
4490- (cond (tail (emit-return e1))
4494+ (cond (tail (emit-return tail e1))
44914495 (value e1)
44924496 ((symbol? e1) (emit e1) #f) ;; keep symbols for undefined-var checking
44934497 ((and (pair? e1) (eq? (car e1) 'outerref)) (emit e1) #f) ;; keep globals for undefined-var checking
@@ -4533,7 +4537,7 @@ f(x) = yt(x)
45334537 (else
45344538 (compile-args (cdr e) break-labels))))
45354539 (callex (cons (car e) args)))
4536- (cond (tail (emit-return callex))
4540+ (cond (tail (emit-return tail callex))
45374541 (value callex)
45384542 (else (emit callex)))))
45394543 ((=)
@@ -4550,7 +4554,7 @@ f(x) = yt(x)
45504554 (if (not (eq? rr rhs))
45514555 (emit `(= ,rr ,rhs)))
45524556 (emit `(= ,lhs ,rr))
4553- (if tail (emit-return rr))
4557+ (if tail (emit-return tail rr))
45544558 rr)
45554559 (emit-assignment lhs rhs))))))
45564560 ((block)
@@ -4603,7 +4607,7 @@ f(x) = yt(x)
46034607 (if file-diff (set! filename last-fname))
46044608 v)))
46054609 ((return)
4606- (compile (cadr e) break-labels #t #t )
4610+ (compile (cadr e) break-labels #t 'explicit )
46074611 #f)
46084612 ((unnecessary)
46094613 ;; `unnecessary` marks expressions generated by lowering that
@@ -4618,7 +4622,8 @@ f(x) = yt(x)
46184622 (let ((v1 (compile (caddr e) break-labels value tail)))
46194623 (if val (emit-assignment val v1))
46204624 (if (and (not tail) (or (length> e 3) val))
4621- (emit end-jump))
4625+ (begin (emit `(line #f))
4626+ (emit end-jump)))
46224627 (let ((elselabel (make&mark-label)))
46234628 (for-each (lambda (test)
46244629 (set-car! (cddr test) elselabel))
@@ -4630,7 +4635,7 @@ f(x) = yt(x)
46304635 (if (not tail)
46314636 (set-car! (cdr end-jump) (make&mark-label))
46324637 (if (length= e 3)
4633- (emit-return v2)))
4638+ (emit-return tail v2)))
46344639 val))))
46354640 ((_while)
46364641 (let* ((endl (make-label))
@@ -4672,7 +4677,7 @@ f(x) = yt(x)
46724677 (emit `(label ,m))
46734678 (put! label-map (cadr e) (make&mark-label)))
46744679 (if tail
4675- (emit-return '(null))
4680+ (emit-return tail '(null))
46764681 (if value (error "misplaced label")))))
46774682 ((symbolicgoto)
46784683 (let* ((m (get label-map (cadr e) #f))
@@ -4712,7 +4717,7 @@ f(x) = yt(x)
47124717 (begin (if els
47134718 (begin (if (and (not val) v1) (emit v1))
47144719 (emit '(leave 1)))
4715- (if v1 (emit-return v1)))
4720+ (if v1 (emit-return tail v1)))
47164721 (if (not finally) (set! endl #f)))
47174722 (begin (emit '(leave 1))
47184723 (emit `(goto ,(or els endl)))))
@@ -4744,7 +4749,7 @@ f(x) = yt(x)
47444749 (emit `(= ,tmp (call (core ===) ,finally ,(caar actions))))
47454750 (emit `(gotoifnot ,tmp ,skip))))
47464751 (let ((ac (cdar actions)))
4747- (cond ((eq? (car ac) 'return) (emit-return (cadr ac)))
4752+ (cond ((eq? (car ac) 'return) (emit-return tail (cadr ac)))
47484753 ((eq? (car ac) 'break) (emit-break (cadr ac)))
47494754 (else ;; assumed to be a rethrow
47504755 (emit ac))))
@@ -4783,8 +4788,8 @@ f(x) = yt(x)
47834788 (set! global-const-error current-loc))
47844789 (emit e))))
47854790 ((atomic) (error "misplaced atomic declaration"))
4786- ((isdefined) (if tail (emit-return e) e))
4787- ((boundscheck) (if tail (emit-return e) e))
4791+ ((isdefined) (if tail (emit-return tail e) e))
4792+ ((boundscheck) (if tail (emit-return tail e) e))
47884793
47894794 ((method)
47904795 (if (not (null? (cadr lam)))
@@ -4805,20 +4810,20 @@ f(x) = yt(x)
48054810 l))))
48064811 (emit `(method ,(or (cadr e) '(false)) ,sig ,lam))
48074812 (if value (compile '(null) break-labels value tail)))
4808- (cond (tail (emit-return e))
4813+ (cond (tail (emit-return tail e))
48094814 (value e)
48104815 (else (emit e)))))
48114816 ((lambda)
48124817 (let ((temp (linearize e)))
4813- (cond (tail (emit-return temp))
4818+ (cond (tail (emit-return tail temp))
48144819 (value temp)
48154820 (else (emit temp)))))
48164821
48174822 ;; top level expressions
48184823 ((thunk module)
48194824 (check-top-level e)
48204825 (emit e)
4821- (if tail (emit-return '(null)))
4826+ (if tail (emit-return tail '(null)))
48224827 '(null))
48234828 ((toplevel-only)
48244829 (check-top-level (cdr e))
@@ -4828,7 +4833,7 @@ f(x) = yt(x)
48284833 (check-top-level e)
48294834 (let ((val (make-ssavalue)))
48304835 (emit `(= ,val ,e))
4831- (if tail (emit-return val))
4836+ (if tail (emit-return tail val))
48324837 val))
48334838
48344839 ;; other top level expressions
@@ -4837,7 +4842,7 @@ f(x) = yt(x)
48374842 (emit e)
48384843 (let ((have-ret? (and (pair? code) (pair? (car code)) (eq? (caar code) 'return))))
48394844 (if (and tail (not have-ret?))
4840- (emit-return '(null))))
4845+ (emit-return tail '(null))))
48414846 '(null))
48424847
48434848 ((gc_preserve_begin)
@@ -4861,7 +4866,7 @@ f(x) = yt(x)
48614866 (else
48624867 (emit e)))
48634868 (if (and tail (not have-ret?))
4864- (emit-return '(null)))
4869+ (emit-return tail '(null)))
48654870 '(null)))
48664871
48674872 ;; unsupported assignment operators
@@ -4979,6 +4984,7 @@ f(x) = yt(x)
49794984 (labltable (table))
49804985 (ssavtable (table))
49814986 (current-loc 0)
4987+ (nowhere #f)
49824988 (current-file file)
49834989 (current-line line)
49844990 (locstack '())
@@ -4991,25 +4997,32 @@ f(x) = yt(x)
49914997 (set! current-loc 1)))
49924998 (set! code (cons e code))
49934999 (set! i (+ i 1))
4994- (set! locs (cons current-loc locs)))
5000+ (set! locs (cons (if nowhere 0 current-loc) locs))
5001+ (set! nowhere #f))
49955002 (let loop ((stmts (cdr body)))
49965003 (if (pair? stmts)
49975004 (let ((e (car stmts)))
49985005 (cond ((atom? e) (emit e))
49995006 ((eq? (car e) 'line)
5000- (if (and (= current-line 0) (length= e 2) (pair? linetable))
5001- ;; (line n) after push_loc just updates the line for the new file
5002- (begin (set-lineno! (car linetable) (cadr e))
5003- (set! current-line (cadr e)))
5004- (begin
5005- (set! current-line (cadr e))
5006- (if (pair? (cddr e))
5007- (set! current-file (caddr e)))
5008- (set! linetable (cons (if (null? locstack)
5009- (make-lineinfo name current-file current-line)
5010- (make-lineinfo name current-file current-line (caar locstack)))
5011- linetable))
5012- (set! current-loc (- (length linetable) 1)))))
5007+ (cond ((and (length= e 2) (not (cadr e)))
5008+ ;; (line #f) marks that we are entering a generated statement
5009+ ;; that should not be counted as belonging to the previous marked location,
5010+ ;; for example `return` after a not-executed `if` arm in tail position.
5011+ (set! nowhere #t))
5012+ ((and (= current-line 0) (length= e 2) (pair? linetable))
5013+ ;; (line n) after push_loc just updates the line for the new file
5014+ (begin (set-lineno! (car linetable) (cadr e))
5015+ (set! current-line (cadr e))))
5016+ (else
5017+ (begin
5018+ (set! current-line (cadr e))
5019+ (if (pair? (cddr e))
5020+ (set! current-file (caddr e)))
5021+ (set! linetable (cons (if (null? locstack)
5022+ (make-lineinfo name current-file current-line)
5023+ (make-lineinfo name current-file current-line (caar locstack)))
5024+ linetable))
5025+ (set! current-loc (- (length linetable) 1))))))
50135026 ((and (length> e 2) (eq? (car e) 'meta) (eq? (cadr e) 'push_loc))
50145027 (set! locstack (cons (list current-loc current-line current-file) locstack))
50155028 (set! current-file (caddr e))
0 commit comments