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