]> gitweb.factorcode.org Git - factor.git/blob - core/compiler/units/units.factor
classes:
[factor.git] / core / compiler / units / units.factor
1 ! Copyright (C) 2008, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs classes classes.private
4 classes.tuple classes.tuple.private continuations definitions
5 generic init kernel kernel.private math namespaces sequences
6 sets source-files.errors vocabs words classes.algebra ;
7 FROM: namespaces => set ;
8 IN: compiler.units
9
10 SYMBOL: old-definitions
11 SYMBOL: new-definitions
12
13 TUPLE: redefine-error def ;
14
15 : redefine-error ( definition -- )
16     \ redefine-error boa throw-continue ;
17
18 <PRIVATE
19
20 : add-once ( key assoc -- )
21     ! 2dup keys swap [ class= ] curry any? [ over redefine-error ] when conjoin ;
22     2dup key? [ over redefine-error ] when conjoin ;
23
24 : (remember-definition) ( definition loc assoc -- )
25     [ over set-where ] dip add-once ;
26
27 PRIVATE>
28
29 : remember-definition ( definition loc -- )
30     new-definitions get first (remember-definition) ;
31
32 : fake-definition ( definition -- )
33     old-definitions get [ delete-at ] with each ;
34
35 : remember-class ( class loc -- )
36     [ dup new-definitions get first key? [ dup redefine-error ] when ] dip
37     new-definitions get second (remember-definition) ;
38
39 : forward-reference? ( word -- ? )
40     dup old-definitions get assoc-stack
41     [ new-definitions get assoc-stack not ]
42     [ drop f ] if ;
43
44 SYMBOL: compiler-impl
45
46 HOOK: update-call-sites compiler-impl ( class generic -- words )
47
48 : changed-call-sites ( class generic -- )
49     update-call-sites [ changed-definition ] each ;
50
51 M: generic update-generic ( class generic -- )
52     [ changed-call-sites ]
53     [ remake-generic drop ]
54     [ changed-conditionally drop ]
55     2tri ;
56
57 M: sequence update-methods ( class seq -- )
58     implementors [ update-generic ] with each ;
59
60 HOOK: recompile compiler-impl ( words -- alist )
61
62 HOOK: to-recompile compiler-impl ( -- words )
63
64 HOOK: process-forgotten-words compiler-impl ( words -- )
65
66 : compile ( words -- )
67     recompile t f modify-code-heap ;
68
69 ! Non-optimizing compiler
70 M: f update-call-sites
71     2drop { } ;
72
73 M: f to-recompile
74     changed-definitions get [ drop word? ] assoc-filter keys ;
75
76 M: f recompile
77     [ dup def>> ] { } map>assoc ;
78
79 M: f process-forgotten-words drop ;
80
81 : without-optimizer ( quot -- )
82     [ f compiler-impl ] dip with-variable ; inline
83
84 : <definitions> ( -- pair ) { H{ } H{ } } [ clone ] map ;
85
86 SYMBOL: definition-observers
87
88 GENERIC: definitions-changed ( assoc obj -- )
89
90 [ V{ } clone definition-observers set-global ]
91 "compiler.units" add-startup-hook
92
93 ! This goes here because vocabs cannot depend on init
94 [ V{ } clone vocab-observers set-global ]
95 "vocabs" add-startup-hook
96
97 : add-definition-observer ( obj -- )
98     definition-observers get push ;
99
100 : remove-definition-observer ( obj -- )
101     definition-observers get remove-eq! drop ;
102
103 : notify-definition-observers ( assoc -- )
104     definition-observers get
105     [ definitions-changed ] with each ;
106
107 ! Incremented each time stack effects potentially changed, used
108 ! by compiler.tree.propagation.call-effect for call( and execute(
109 ! inline caching
110 : effect-counter ( -- n ) REDEFINITION-COUNTER special-object ; inline
111
112 GENERIC: always-bump-effect-counter? ( defspec -- ? )
113
114 M: object always-bump-effect-counter? drop f ;
115
116 <PRIVATE
117
118 : changed-vocabs ( assoc -- vocabs )
119     [ drop word? ] assoc-filter
120     [ drop vocabulary>> dup [ lookup-vocab ] when dup ] assoc-map ;
121
122 : updated-definitions ( -- assoc )
123     H{ } clone
124     forgotten-definitions get assoc-union!
125     new-definitions get first assoc-union!
126     new-definitions get second assoc-union!
127     changed-definitions get assoc-union!
128     maybe-changed get assoc-union!
129     dup changed-vocabs assoc-union! ;
130
131 : process-forgotten-definitions ( -- )
132     forgotten-definitions get keys
133     [ [ word? ] filter process-forgotten-words ]
134     [ [ delete-definition-errors ] each ]
135     bi ;
136
137 : bump-effect-counter? ( -- ? )
138     changed-effects get
139     maybe-changed get
140     changed-definitions get [ drop always-bump-effect-counter? ] assoc-filter
141     3array assoc-combine new-words get assoc-diff assoc-empty? not ;
142
143 : bump-effect-counter ( -- )
144     bump-effect-counter? [
145         REDEFINITION-COUNTER special-object 0 or
146         1 + REDEFINITION-COUNTER set-special-object
147     ] when ;
148
149 : notify-observers ( -- )
150     updated-definitions dup assoc-empty?
151     [ drop ] [ notify-definition-observers notify-error-observers ] if ;
152
153 : update-existing? ( defs -- ? )
154     new-words get keys diff empty? not ;
155
156 : reset-pics? ( -- ? )
157     outdated-generics get assoc-empty? not ;
158
159 : finish-compilation-unit ( -- )
160     [ ] [
161         remake-generics
162         to-recompile [
163             recompile
164             update-tuples
165             process-forgotten-definitions
166         ] keep update-existing? reset-pics? modify-code-heap
167         bump-effect-counter
168         notify-observers
169     ] if-bootstrapping ;
170
171 TUPLE: nesting-observer new-words ;
172
173 M: nesting-observer definitions-changed new-words>> swap assoc-diff! drop ;
174
175 : add-nesting-observer ( -- )
176     new-words get nesting-observer boa
177     [ nesting-observer set ] [ add-definition-observer ] bi ;
178
179 : remove-nesting-observer ( -- )
180     nesting-observer get remove-definition-observer ;
181
182 PRIVATE>
183
184 : with-nested-compilation-unit ( quot -- )
185     [
186         H{ } clone changed-definitions set
187         H{ } clone maybe-changed set
188         H{ } clone changed-effects set
189         H{ } clone outdated-generics set
190         H{ } clone outdated-tuples set
191         H{ } clone new-words set
192         add-nesting-observer
193         [
194             remove-nesting-observer
195             finish-compilation-unit
196         ] [ ] cleanup
197     ] with-scope ; inline
198
199 : with-compilation-unit ( quot -- )
200     [
201         <definitions> new-definitions set
202         <definitions> old-definitions set
203         H{ } clone forgotten-definitions set
204         with-nested-compilation-unit
205     ] with-scope ; inline