@@ -3059,14 +3059,29 @@ f(x) = yt(x)
3059
3059
(take body)
3060
3060
(reverse! acc)))
3061
3061
3062
+ ; ; find all methods for the same function as `ex` in `body`
3063
+ (define (all-methods-for ex body )
3064
+ (let ((mname (method-expr-name ex)))
3065
+ (expr-find-all (lambda (s )
3066
+ (and (length> s 2 ) (eq? (car s) 'method )
3067
+ (eq? (method-expr-name s) mname)))
3068
+ body
3069
+ identity
3070
+ (lambda (x ) (and (pair? x) (not (eq? (car x) 'lambda )))))))
3071
+
3062
3072
; ; clear capture bit for vars assigned once at the top, to avoid allocating
3063
3073
; ; some unnecessary Boxes.
3064
3074
(define (lambda-optimize-vars! lam )
3065
- (define (expr-uses-var ex v )
3075
+ (define (expr-uses-var ex v stmts )
3066
3076
(cond ((assignment? ex) (expr-contains-eq v (caddr ex)))
3067
3077
((eq? (car ex) 'method )
3068
3078
(and (length> ex 2 )
3069
- (assq v (cadr (lam:vinfo (cadddr ex))))))
3079
+ ; ; a method expression captures a variable if any methods for the
3080
+ ; ; same function do.
3081
+ (let ((all-methods (all-methods-for ex (cons 'body stmts))))
3082
+ (any (lambda (ex )
3083
+ (assq v (cadr (lam:vinfo (cadddr ex)))))
3084
+ all-methods))))
3070
3085
(else (expr-contains-eq v ex))))
3071
3086
(assert (eq? (car lam) 'lambda ))
3072
3087
(let ((vi (car (lam:vinfo lam))))
@@ -3092,7 +3107,7 @@ f(x) = yt(x)
3092
3107
; ; TODO: reorder leading statements to put assignments where the RHS is
3093
3108
; ; `simple-atom?` at the top.
3094
3109
(for-each (lambda (e )
3095
- (set! unused (filter (lambda (v ) (not (expr-uses-var e v)))
3110
+ (set! unused (filter (lambda (v ) (not (expr-uses-var e v leading )))
3096
3111
unused))
3097
3112
(if (and (memq (car e) ' (method =)) (memq (cadr e) unused))
3098
3113
(let ((v (assq (cadr e) vi)))
@@ -3273,9 +3288,8 @@ f(x) = yt(x)
3273
3288
(and name
3274
3289
(symbol (string " #" name " #" (current-julia-module-counter))))))
3275
3290
(alldefs (expr-find-all
3276
- (lambda (ex ) (and (eq? (car ex) 'method )
3291
+ (lambda (ex ) (and (length> ex 2 ) ( eq? (car ex) 'method )
3277
3292
(not (eq? ex e))
3278
- (length> ex 2 )
3279
3293
(eq? (method-expr-name ex) name)))
3280
3294
(lam:body lam)
3281
3295
identity
0 commit comments