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 init kernel kernel.private math namespaces sequences
6 sets source-files.errors vocabs words ;
9 PRIMITIVE: modify-code-heap ( alist update-existing? reset-pics? -- )
11 SYMBOL: old-definitions
12 SYMBOL: new-definitions
14 TUPLE: redefine-error def ;
16 : throw-redefine-error ( definition -- )
17 redefine-error boa throw-continue ;
21 : add-once ( key set -- )
22 dupd ?adjoin [ drop ] [ throw-redefine-error ] if ;
24 : (remember-definition) ( definition loc set -- )
25 [ over set-where ] dip add-once ;
29 : remember-definition ( definition loc -- )
30 new-definitions get first (remember-definition) ;
32 : fake-definition ( definition -- )
33 old-definitions get [ delete ] with each ;
35 : remember-class ( class loc -- )
36 new-definitions get first2
37 [ dupd in? [ dup throw-redefine-error ] when ]
38 [ (remember-definition) ] bi-curry* bi* ;
40 : forward-reference? ( word -- ? )
41 dup old-definitions get [ in? ] with any? [
42 new-definitions get [ in? ] with none?
47 HOOK: update-call-sites compiler-impl ( class generic -- words )
49 : changed-call-sites ( class generic -- )
50 update-call-sites [ changed-definition ] each ;
52 M: generic update-generic ( class generic -- )
53 [ changed-call-sites ]
54 [ remake-generic drop ]
55 [ changed-conditionally drop ]
58 M: sequence update-methods ( class seq -- )
59 implementors [ update-generic ] with each ;
61 HOOK: recompile compiler-impl ( words -- alist )
63 HOOK: to-recompile compiler-impl ( -- words )
65 HOOK: process-forgotten-words compiler-impl ( words -- )
67 : compile ( words -- )
68 recompile t f modify-code-heap ;
70 : filter-word-defs ( defset -- words )
71 members [ word? ] filter ;
73 ! Non-optimizing compiler
74 M: f update-call-sites
78 changed-definitions get filter-word-defs ;
81 [ dup def>> ] { } map>assoc ;
83 M: f process-forgotten-words drop ;
85 : without-optimizer ( quot -- )
86 [ f compiler-impl ] dip with-variable ; inline
88 : <definitions> ( -- pair ) { HS{ } HS{ } } [ clone ] map ;
90 SYMBOL: definition-observers
92 GENERIC: definitions-changed ( set obj -- )
94 [ V{ } clone definition-observers set-global ]
95 "compiler.units" add-startup-hook
97 ! This goes here because vocabs cannot depend on init
98 [ V{ } clone vocab-observers set-global ]
99 "vocabs" add-startup-hook
101 : add-definition-observer ( obj -- )
102 definition-observers get push ;
104 : remove-definition-observer ( obj -- )
105 definition-observers get remove-eq! drop ;
107 : notify-definition-observers ( set -- )
108 definition-observers get
109 [ definitions-changed ] with each ;
111 ! Incremented each time stack effects potentially changed, used
112 ! by compiler.tree.propagation.call-effect for call( and execute(
114 : effect-counter ( -- n ) REDEFINITION-COUNTER special-object ; inline
116 GENERIC: always-bump-effect-counter? ( defspec -- ? )
118 M: object always-bump-effect-counter? drop f ;
122 : changed-vocabs ( set -- vocabs )
123 filter-word-defs [ vocabulary>> dup [ lookup-vocab ] when ] map ;
125 : updated-definitions ( -- set )
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 ;
134 : process-forgotten-definitions ( forgotten-definitions -- )
136 [ [ word? ] filter process-forgotten-words ]
137 [ [ delete-definition-errors ] each ]
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 combine new-words get [ in? not ] curry any? ;
147 : bump-effect-counter ( -- )
148 bump-effect-counter? [
149 REDEFINITION-COUNTER special-object 0 or
150 1 + REDEFINITION-COUNTER set-special-object
153 : notify-observers ( -- )
154 updated-definitions dup null?
155 [ drop ] [ notify-definition-observers notify-error-observers ] if ;
157 : update-existing? ( defs -- ? )
158 new-words get [ in? not ] curry any? ;
160 : reset-pics? ( -- ? )
161 outdated-generics get null? not ;
163 : finish-compilation-unit ( -- )
168 outdated-tuples get update-tuples
169 forgotten-definitions get process-forgotten-definitions
170 ] keep update-existing? reset-pics? modify-code-heap
175 TUPLE: nesting-observer { new-words hash-set } ;
177 M: nesting-observer definitions-changed
178 [ members ] dip new-words>> [ delete ] curry each ;
180 : add-nesting-observer ( -- )
181 new-words get nesting-observer boa
182 [ nesting-observer namespaces:set ] [ add-definition-observer ] bi ;
184 : remove-nesting-observer ( -- )
185 nesting-observer get remove-definition-observer ;
189 : with-nested-compilation-unit ( quot -- )
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 [
199 remove-nesting-observer
200 finish-compilation-unit
202 ] with-variables ; inline
204 : with-compilation-unit ( quot -- )
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