260
260
(or (overlay? e)
261
261
(sym-ref? e)))
262
262
263
+ (define (binding-to-globalref e )
264
+ (and (nodot-sym-ref? e)
265
+ (let ((mod (if (globalref? e) (cadr e) ' (thismodule)))
266
+ (sym (if (symbol? e) e (last e))))
267
+ `(globalref ,mod ,sym))))
268
+
263
269
; ; convert final (... x) to (curly Vararg x)
264
270
(define (dots->vararg a )
265
271
(if (null? a) a
@@ -3383,7 +3389,7 @@ f(x) = yt(x)
3383
3389
; ; declared types.
3384
3390
; ; when doing this, the original value needs to be preserved, to
3385
3391
; ; ensure the expression `a=b` always returns exactly `b`.
3386
- (define (convert-assignment var rhs0 fname lam interp opaq )
3392
+ (define (convert-assignment var rhs0 fname lam interp opaq globals )
3387
3393
(cond
3388
3394
((symbol? var)
3389
3395
(let* ((vi (assq var (car (lam:vinfo lam))))
@@ -3393,32 +3399,39 @@ f(x) = yt(x)
3393
3399
' (core Any)))
3394
3400
(closed (and cv (vinfo:asgn cv) (vinfo:capt cv)))
3395
3401
(capt (and vi (vinfo:asgn vi) (vinfo:capt vi))))
3396
- (if (and (not closed) (not capt) (equal? vt ' (core Any)))
3397
- `(= ,var ,rhs0)
3398
- (let* ((rhs1 (if (or (simple-atom? rhs0)
3399
- (equal? rhs0 ' (the_exception)))
3400
- rhs0
3401
- (make-ssavalue)))
3402
- (rhs (if (equal? vt ' (core Any))
3403
- rhs1
3404
- (convert-for-type-decl rhs1 (cl-convert vt fname lam #f #f #f interp opaq))))
3405
- (ex (cond (closed `(call (core setfield!)
3406
- ,(if interp
3407
- `($ ,var)
3408
- (capt-var-access var fname opaq))
3409
- (inert contents)
3410
- ,rhs))
3411
- (capt `(call (core setfield!) ,var (inert contents) ,rhs))
3412
- (else `(= ,var ,rhs)))))
3413
- (if (eq? rhs1 rhs0)
3414
- `(block ,ex ,rhs0)
3415
- `(block (= ,rhs1 ,rhs0)
3416
- ,ex
3417
- ,rhs1))))))
3418
- ((and (pair? var) (or (eq? (car var) 'outerref )
3419
- (eq? (car var) 'globalref )))
3420
-
3421
- `(= ,var ,rhs0))
3402
+ (let* ((rhs1 (if (or (simple-atom? rhs0)
3403
+ (equal? rhs0 ' (the_exception)))
3404
+ rhs0
3405
+ (make-ssavalue)))
3406
+ (rhs (if (equal? vt ' (core Any))
3407
+ (if (and (not closed) (not capt))
3408
+ (convert-for-type-decl rhs1 (get globals (binding-to-globalref var) ' (core Any)))
3409
+ rhs1)
3410
+ (convert-for-type-decl rhs1 (cl-convert vt fname lam #f #f #f interp opaq globals))))
3411
+ (ex (cond (closed `(call (core setfield!)
3412
+ ,(if interp
3413
+ `($ ,var)
3414
+ (capt-var-access var fname opaq))
3415
+ (inert contents)
3416
+ ,rhs))
3417
+ (capt `(call (core setfield!) ,var (inert contents) ,rhs))
3418
+ (else `(= ,var ,rhs)))))
3419
+ (if (eq? rhs1 rhs0)
3420
+ `(block ,ex ,rhs0)
3421
+ `(block (= ,rhs1 ,rhs0)
3422
+ ,ex
3423
+ ,rhs1)))))
3424
+ ((or (outerref? var) (globalref? var))
3425
+ (let* ((rhs1 (if (or (simple-atom? rhs0)
3426
+ (equal? rhs0 ' (the_exception)))
3427
+ rhs0
3428
+ (make-ssavalue)))
3429
+ (ex `(= ,var ,(convert-for-type-decl rhs1 (get globals (binding-to-globalref var) ' (core Any))))))
3430
+ (if (eq? rhs1 rhs0)
3431
+ `(block ,ex ,rhs0)
3432
+ `(block (= ,rhs1 ,rhs0)
3433
+ ,ex
3434
+ ,rhs1))))
3422
3435
((ssavalue? var)
3423
3436
`(= ,var ,rhs0))
3424
3437
(else
@@ -3678,17 +3691,17 @@ f(x) = yt(x)
3678
3691
(define (toplevel-preserving? e )
3679
3692
(and (pair? e) (memq (car e) ' (if elseif block trycatch tryfinally trycatchelse))))
3680
3693
3681
- (define (map-cl-convert exprs fname lam namemap defined toplevel interp opaq )
3694
+ (define (map-cl-convert exprs fname lam namemap defined toplevel interp opaq (globals (table)) )
3682
3695
(if toplevel
3683
3696
(map (lambda (x )
3684
3697
(let ((tl (lift-toplevel (cl-convert x fname lam namemap defined
3685
3698
(and toplevel (toplevel-preserving? x))
3686
- interp opaq))))
3699
+ interp opaq globals ))))
3687
3700
(if (null? (cdr tl))
3688
3701
(car tl)
3689
3702
`(block ,@(cdr tl) ,(car tl)))))
3690
3703
exprs)
3691
- (map (lambda (x ) (cl-convert x fname lam namemap defined #f interp opaq)) exprs)))
3704
+ (map (lambda (x ) (cl-convert x fname lam namemap defined #f interp opaq globals )) exprs)))
3692
3705
3693
3706
(define (prepare-lambda! lam )
3694
3707
; ; mark all non-arguments as assigned, since locals that are never assigned
@@ -3697,11 +3710,11 @@ f(x) = yt(x)
3697
3710
(list-tail (car (lam:vinfo lam)) (length (lam:args lam))))
3698
3711
(lambda-optimize-vars! lam))
3699
3712
3700
- (define (cl-convert e fname lam namemap defined toplevel interp opaq )
3713
+ (define (cl-convert e fname lam namemap defined toplevel interp opaq (globals (table)) )
3701
3714
(if (and (not lam)
3702
3715
(not (and (pair? e) (memq (car e) ' (lambda method macro opaque_closure)))))
3703
3716
(if (atom? e) e
3704
- (cons (car e) (map-cl-convert (cdr e) fname lam namemap defined toplevel interp opaq)))
3717
+ (cons (car e) (map-cl-convert (cdr e) fname lam namemap defined toplevel interp opaq globals )))
3705
3718
(cond
3706
3719
((symbol? e)
3707
3720
(define (new-undef-var name )
@@ -3720,7 +3733,7 @@ f(x) = yt(x)
3720
3733
(val (if (equal? typ ' (core Any))
3721
3734
val
3722
3735
`(call (core typeassert) ,val
3723
- ,(cl-convert typ fname lam namemap defined toplevel interp opaq)))))
3736
+ ,(cl-convert typ fname lam namemap defined toplevel interp opaq globals )))))
3724
3737
`(block
3725
3738
,@(if (eq? box access) '() `((= ,access ,box)))
3726
3739
,undefcheck
@@ -3752,8 +3765,8 @@ f(x) = yt(x)
3752
3765
e)
3753
3766
((=)
3754
3767
(let ((var (cadr e))
3755
- (rhs (cl-convert (caddr e) fname lam namemap defined toplevel interp opaq)))
3756
- (convert-assignment var rhs fname lam interp opaq)))
3768
+ (rhs (cl-convert (caddr e) fname lam namemap defined toplevel interp opaq globals )))
3769
+ (convert-assignment var rhs fname lam interp opaq globals )))
3757
3770
((local-def) ; ; make new Box for local declaration of defined variable
3758
3771
(let ((vi (assq (cadr e) (car (lam:vinfo lam)))))
3759
3772
(if (and vi (vinfo:asgn vi) (vinfo:capt vi))
@@ -3819,7 +3832,7 @@ f(x) = yt(x)
3819
3832
(sp-inits (if (or short (not (eq? (car sig) 'block )))
3820
3833
'()
3821
3834
(map-cl-convert (butlast (cdr sig))
3822
- fname lam namemap defined toplevel interp opaq)))
3835
+ fname lam namemap defined toplevel interp opaq globals )))
3823
3836
(sig (and sig (if (eq? (car sig) 'block )
3824
3837
(last sig)
3825
3838
sig))))
@@ -3846,7 +3859,7 @@ f(x) = yt(x)
3846
3859
; ; anonymous functions with keyword args generate global
3847
3860
; ; functions that refer to the type of a local function
3848
3861
(rename-sig-types sig namemap)
3849
- fname lam namemap defined toplevel interp opaq)
3862
+ fname lam namemap defined toplevel interp opaq globals )
3850
3863
,(let ((body (add-box-inits-to-body
3851
3864
lam2
3852
3865
(cl-convert (cadddr lam2) 'anon lam2 (table) (table) #f interp opaq))))
@@ -3860,7 +3873,7 @@ f(x) = yt(x)
3860
3873
(newlam (compact-and-renumber (linearize (car exprs)) 'none 0 )))
3861
3874
`(toplevel-butfirst
3862
3875
(block ,@sp-inits
3863
- (method ,name ,(cl-convert sig fname lam namemap defined toplevel interp opaq)
3876
+ (method ,name ,(cl-convert sig fname lam namemap defined toplevel interp opaq globals )
3864
3877
,(julia-bq-macro newlam)))
3865
3878
,@top-stmts))))
3866
3879
@@ -3963,7 +3976,7 @@ f(x) = yt(x)
3963
3976
(append (map (lambda (gs tvar )
3964
3977
(make-assignment gs `(call (core TypeVar) ',tvar (core Any))))
3965
3978
closure-param-syms closure-param-names)
3966
- `((method #f ,(cl-convert arg-defs fname lam namemap defined toplevel interp opaq)
3979
+ `((method #f ,(cl-convert arg-defs fname lam namemap defined toplevel interp opaq globals )
3967
3980
,(convert-lambda lam2
3968
3981
(if iskw
3969
3982
(caddr (lam:args lam2))
@@ -4002,7 +4015,7 @@ f(x) = yt(x)
4002
4015
(begin
4003
4016
(put! defined name #t )
4004
4017
`(toplevel-butfirst
4005
- ,(convert-assignment name mk-closure fname lam interp opaq)
4018
+ ,(convert-assignment name mk-closure fname lam interp opaq globals )
4006
4019
,@typedef
4007
4020
,@(map (lambda (v ) `(moved-local ,v)) moved-vars)
4008
4021
,@sp-inits
@@ -4015,30 +4028,42 @@ f(x) = yt(x)
4015
4028
(table)
4016
4029
(table)
4017
4030
(null? (cadr e)) ; ; only toplevel thunks have 0 args
4018
- interp opaq)))
4031
+ interp opaq globals )))
4019
4032
`(lambda ,(cadr e)
4020
4033
(,(clear-capture-bits (car (lam:vinfo e)))
4021
4034
() ,@(cddr (lam:vinfo e)))
4022
4035
(block ,@body))))
4023
4036
; ; remaining `::` expressions are type assertions
4024
4037
((|::|)
4025
- (cl-convert `(call (core typeassert) ,@(cdr e)) fname lam namemap defined toplevel interp opaq))
4038
+ (cl-convert `(call (core typeassert) ,@(cdr e)) fname lam namemap defined toplevel interp opaq globals ))
4026
4039
; ; remaining `decl` expressions are only type assertions if the
4027
4040
; ; argument is global or a non-symbol.
4028
4041
((decl)
4029
4042
(cond ((and (symbol? (cadr e))
4030
4043
(local-in? (cadr e) lam))
4031
4044
' (null))
4032
4045
(else
4033
- (if (or (symbol? (cadr e)) (and (pair? (cadr e)) (eq? (caadr e) 'outerref )))
4034
- (error " type declarations on global variables are not yet supported" ))
4035
- (cl-convert `(call (core typeassert) ,@(cdr e)) fname lam namemap defined toplevel interp opaq))))
4046
+ (cl-convert
4047
+ (let ((ref (binding-to-globalref (cadr e))))
4048
+ (and ref (get globals ref #f )
4049
+ (error (string " multiple type annotations for global \" "
4050
+ (deparse (cadr e)) " \" ." )))
4051
+ (if ref
4052
+ (let* ((rhs0 (caddr e))
4053
+ (temp (and (not (effect-free? rhs0)) (make-ssavalue)))
4054
+ (rhs (or temp rhs0)))
4055
+ (put! globals ref rhs)
4056
+ `(toplevel-butfirst
4057
+ ,(if temp `(block (= ,temp ,rhs0) (null)) ' (null))
4058
+ (call (core _set_typeof!) ,(cadr ref) (inert ,(caddr ref)) ,(caddr e))))
4059
+ `(call (core typeassert) ,@(cdr e))))
4060
+ fname lam namemap defined toplevel interp opaq globals))))
4036
4061
; ; `with-static-parameters` expressions can be removed now; used only by analyze-vars
4037
4062
((with-static-parameters)
4038
- (cl-convert (cadr e) fname lam namemap defined toplevel interp opaq))
4063
+ (cl-convert (cadr e) fname lam namemap defined toplevel interp opaq globals ))
4039
4064
(else
4040
4065
(cons (car e)
4041
- (map-cl-convert (cdr e) fname lam namemap defined toplevel interp opaq))))))))
4066
+ (map-cl-convert (cdr e) fname lam namemap defined toplevel interp opaq globals ))))))))
4042
4067
4043
4068
(define (closure-convert e ) (cl-convert e #f #f #f #f #f #f #f ))
4044
4069
0 commit comments