Skip to content

Commit

Permalink
more predictable global binding resolution
Browse files Browse the repository at this point in the history
fix #18933
  • Loading branch information
vtjnash committed Jul 24, 2017
1 parent 04d76f3 commit 9739329
Showing 1 changed file with 45 additions and 35 deletions.
80 changes: 45 additions & 35 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -2841,35 +2841,47 @@ f(x) = yt(x)
;; when doing this, the original value needs to be preserved, to
;; ensure the expression `a=b` always returns exactly `b`.
(define (convert-assignment var rhs0 fname lam interp)
(let* ((vi (assq var (car (lam:vinfo lam))))
(cv (assq var (cadr (lam:vinfo lam))))
(vt (or (and vi (vinfo:type vi))
(and cv (vinfo:type cv))
'(core Any)))
(closed (and cv (vinfo:asgn cv) (vinfo:capt cv)))
(capt (and vi (vinfo:asgn vi) (vinfo:capt vi))))
(if (and (not closed) (not capt) (equal? vt '(core Any)))
`(= ,var ,rhs0)
(let* ((rhs1 (if (or (ssavalue? rhs0) (simple-atom? rhs0)
(equal? rhs0 '(the_exception)))
rhs0
(make-ssavalue)))
(rhs (if (equal? vt '(core Any))
rhs1
(convert-for-type-decl rhs1 (cl-convert vt fname lam #f #f interp))))
(ex (cond (closed `(call (core setfield!)
,(if interp
`($ ,var)
`(call (core getfield) ,fname (inert ,var)))
(inert contents)
,rhs))
(capt `(call (core setfield!) ,var (inert contents) ,rhs))
(else `(= ,var ,rhs)))))
(if (eq? rhs1 rhs0)
`(block ,ex ,rhs0)
`(block (= ,rhs1 ,rhs0)
,ex
,rhs1))))))
(cond
((symbol? var)
(let* ((vi (assq var (car (lam:vinfo lam))))
(cv (assq var (cadr (lam:vinfo lam))))
(vt (or (and vi (vinfo:type vi))
(and cv (vinfo:type cv))
'(core Any)))
(closed (and cv (vinfo:asgn cv) (vinfo:capt cv)))
(capt (and vi (vinfo:asgn vi) (vinfo:capt vi))))
(if (and (not closed) (not capt) (equal? vt '(core Any)))
`(= ,var ,rhs0)
(let* ((rhs1 (if (or (ssavalue? rhs0) (simple-atom? rhs0)
(equal? rhs0 '(the_exception)))
rhs0
(make-ssavalue)))
(rhs (if (equal? vt '(core Any))
rhs1
(convert-for-type-decl rhs1 (cl-convert vt fname lam #f #f interp))))
(ex (cond (closed `(call (core setfield!)
,(if interp
`($ ,var)
`(call (core getfield) ,fname (inert ,var)))
(inert contents)
,rhs))
(capt `(call (core setfield!) ,var (inert contents) ,rhs))
(else `(= ,var ,rhs)))))
(if (eq? rhs1 rhs0)
`(block ,ex ,rhs0)
`(block (= ,rhs1 ,rhs0)
,ex
,rhs1))))))
((and (pair? var) (or (eq? (car var) 'outerref)
(eq? (car var) 'globalref)))

`(toplevel-butlast
(global ,var)
(= ,var ,rhs0)))
((ssavalue? var)
`(= ,var ,rhs0))
(else
(error (string "invalid assignment location \"" (deparse var) "\"")))))

;; replace leading (function) argument type with `typ`
(define (fix-function-arg-type te typ iskw namemap type-sp)
Expand Down Expand Up @@ -3056,9 +3068,7 @@ f(x) = yt(x)
((=)
(let ((var (cadr e))
(rhs (cl-convert (caddr e) fname lam namemap toplevel interp)))
(if (ssavalue? var)
`(= ,var ,rhs)
(convert-assignment var rhs fname lam interp))))
(convert-assignment var rhs fname lam interp)))
((local-def) ;; make new Box for local declaration of defined variable
(let ((vi (assq (cadr e) (car (lam:vinfo lam)))))
(if (and vi (vinfo:asgn vi) (vinfo:capt vi))
Expand Down Expand Up @@ -3100,10 +3110,10 @@ f(x) = yt(x)
(lam2 (if short #f (cadddr e)))
(vis (if short '(() () ()) (lam:vinfo lam2)))
(cvs (map car (cadr vis)))
(local? (lambda (s) (and (symbol? s)
(local? (lambda (s) (and lam (symbol? s)
(or (assq s (car (lam:vinfo lam)))
(assq s (cadr (lam:vinfo lam)))))))
(local (and lam (local? name)))
(local (local? name))
(sig (and (not short) (caddr e)))
(sp-inits (if (or short (not (eq? (car sig) 'block)))
'()
Expand Down Expand Up @@ -3180,7 +3190,7 @@ f(x) = yt(x)
(and (symbol? s)
(not (eq? name s))
(not (memq s capt-sp))
(or ;(local? s) ; TODO: make this work for local variables too?
(or ;(local? s) ; TODO: error for local variables
(memq s (lam:sp lam)))))))
(caddr methdef)
(lambda (e) (cadr e)))))
Expand Down

0 comments on commit 9739329

Please sign in to comment.