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