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