]> gitweb.factorcode.org Git - factor.git/blob - core/compiler/units/units.factor
core: trim using lists with lint.vocabs tool
[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.private continuations definitions generic
5 hash-sets kernel kernel.private math namespaces sequences
6 sets source-files.errors vocabs words ;
7 IN: compiler.units
8
9 PRIMITIVE: modify-code-heap ( alist update-existing? reset-pics? -- )
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 none?
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
53     [ changed-call-sites ]
54     [ remake-generic drop ]
55     [ changed-conditionally drop ]
56     2tri ;
57
58 M: sequence update-methods
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 : filter-word-defs ( defset -- words )
71     members [ word? ] filter ;
72
73 ! Non-optimizing compiler
74 M: f update-call-sites
75     2drop { } ;
76
77 M: f to-recompile
78     changed-definitions get filter-word-defs ;
79
80 M: f recompile
81     [ def>> ] zip-with ;
82
83 M: f process-forgotten-words drop ;
84
85 : without-optimizer ( quot -- )
86     [ f compiler-impl ] dip with-variable ; inline
87
88 : <definitions> ( -- pair ) { HS{ } HS{ } } [ clone ] map ;
89
90 SYMBOL: definition-observers
91
92 GENERIC: definitions-changed ( set obj -- )
93
94 STARTUP-HOOK: [
95     V{ } clone definition-observers set-global
96
97     ! This goes here because vocabs cannot depend on init
98     V{ } clone vocab-observers set-global
99 ]
100
101 : add-definition-observer ( obj -- )
102     definition-observers get push ;
103
104 : remove-definition-observer ( obj -- )
105     definition-observers get remove-eq! drop ;
106
107 : notify-definition-observers ( set -- )
108     definition-observers get
109     [ definitions-changed ] with each ;
110
111 ! Incremented each time stack effects potentially changed, used
112 ! by compiler.tree.propagation.call-effect for call( and execute(
113 ! inline caching
114 : effect-counter ( -- n ) REDEFINITION-COUNTER special-object ; inline
115
116 GENERIC: always-bump-effect-counter? ( defspec -- ? )
117
118 M: object always-bump-effect-counter? drop f ;
119
120 <PRIVATE
121
122 : changed-vocabs ( set -- vocabs )
123     filter-word-defs [ 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 ( forgotten-definitions -- )
135     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
144     [ always-bump-effect-counter? ] filter
145     3array union-all new-words get [ in? not ] curry any? ;
146
147 : bump-effect-counter ( -- )
148     bump-effect-counter? [
149         REDEFINITION-COUNTER special-object 0 or
150         1 + REDEFINITION-COUNTER set-special-object
151     ] when ;
152
153 : notify-observers ( -- )
154     updated-definitions notify-definition-observers
155     notify-error-observers ;
156
157 : update-existing? ( defs -- ? )
158     new-words get [ in? not ] curry any? ;
159
160 : reset-pics? ( -- ? )
161     outdated-generics get null? not ;
162
163 : finish-compilation-unit ( -- )
164     [ ] [
165         remake-generics
166         to-recompile [
167             recompile
168             outdated-tuples get update-tuples
169             forgotten-definitions get process-forgotten-definitions
170         ] keep update-existing? reset-pics? modify-code-heap
171         bump-effect-counter
172         notify-observers
173     ] if-bootstrapping ;
174
175 TUPLE: nesting-observer { new-words hash-set } ;
176
177 M: nesting-observer definitions-changed
178     [ members ] dip new-words>> [ delete ] curry each ;
179
180 : add-nesting-observer ( -- )
181     new-words get nesting-observer boa
182     [ nesting-observer namespaces:set ] [ add-definition-observer ] bi ;
183
184 : remove-nesting-observer ( -- )
185     nesting-observer get remove-definition-observer ;
186
187 PRIVATE>
188
189 : with-nested-compilation-unit ( quot -- )
190     H{ } clone
191     HS{ } clone changed-definitions pick set-at
192     HS{ } clone maybe-changed pick set-at
193     HS{ } clone changed-effects pick set-at
194     HS{ } clone outdated-generics pick set-at
195     H{ } clone outdated-tuples pick set-at
196     HS{ } clone new-words pick set-at [
197         add-nesting-observer
198         [
199             remove-nesting-observer
200             finish-compilation-unit
201         ] finally
202     ] with-variables ; inline
203
204 : with-compilation-unit ( quot -- )
205     H{ } clone
206     <definitions> new-definitions pick set-at
207     <definitions> old-definitions pick set-at
208     HS{ } clone forgotten-definitions pick set-at [
209         with-nested-compilation-unit
210     ] with-variables ; inline