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