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