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 any? not
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 ! Non-optimizing compiler
71 M: f update-call-sites
75 changed-definitions get members [ word? ] filter ;
78 [ dup def>> ] { } map>assoc ;
80 M: f process-forgotten-words drop ;
82 : without-optimizer ( quot -- )
83 [ f compiler-impl ] dip with-variable ; inline
85 : <definitions> ( -- pair ) { HS{ } HS{ } } [ clone ] map ;
87 SYMBOL: definition-observers
89 GENERIC: definitions-changed ( set obj -- )
91 [ V{ } clone definition-observers set-global ]
92 "compiler.units" add-startup-hook
94 ! This goes here because vocabs cannot depend on init
95 [ V{ } clone vocab-observers set-global ]
96 "vocabs" add-startup-hook
98 : add-definition-observer ( obj -- )
99 definition-observers get push ;
101 : remove-definition-observer ( obj -- )
102 definition-observers get remove-eq! drop ;
104 : notify-definition-observers ( set -- )
105 definition-observers get
106 [ definitions-changed ] with each ;
108 ! Incremented each time stack effects potentially changed, used
109 ! by compiler.tree.propagation.call-effect for call( and execute(
111 : effect-counter ( -- n ) REDEFINITION-COUNTER special-object ; inline
113 GENERIC: always-bump-effect-counter? ( defspec -- ? )
115 M: object always-bump-effect-counter? drop f ;
119 : changed-vocabs ( set -- vocabs )
120 members [ word? ] filter
121 [ vocabulary>> dup [ lookup-vocab ] when ] map ;
123 : updated-definitions ( -- set )
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 ;
132 : process-forgotten-definitions ( -- )
133 forgotten-definitions get members
134 [ [ word? ] filter process-forgotten-words ]
135 [ [ delete-definition-errors ] each ]
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? ;
144 : bump-effect-counter ( -- )
145 bump-effect-counter? [
146 REDEFINITION-COUNTER special-object 0 or
147 1 + REDEFINITION-COUNTER set-special-object
150 : notify-observers ( -- )
151 updated-definitions dup null?
152 [ drop ] [ notify-definition-observers notify-error-observers ] if ;
154 : update-existing? ( defs -- ? )
155 new-words get [ in? not ] curry any? ;
157 : reset-pics? ( -- ? )
158 outdated-generics get null? not ;
160 : finish-compilation-unit ( -- )
166 process-forgotten-definitions
167 ] keep update-existing? reset-pics? modify-code-heap
172 TUPLE: nesting-observer { new-words hash-set } ;
174 M: nesting-observer definitions-changed
175 [ members ] dip new-words>> [ delete ] curry each ;
177 : add-nesting-observer ( -- )
178 new-words get nesting-observer boa
179 [ nesting-observer set ] [ add-definition-observer ] bi ;
181 : remove-nesting-observer ( -- )
182 nesting-observer get remove-definition-observer ;
186 : with-nested-compilation-unit ( quot -- )
188 HS{ } clone changed-definitions pick set-at
189 HS{ } clone maybe-changed pick set-at
190 HS{ } clone changed-effects pick set-at
191 HS{ } clone outdated-generics pick set-at
192 H{ } clone outdated-tuples pick set-at
193 HS{ } clone new-words pick set-at [
196 remove-nesting-observer
197 finish-compilation-unit
199 ] with-variables ; inline
201 : with-compilation-unit ( quot -- )
203 <definitions> new-definitions pick set-at
204 <definitions> old-definitions pick set-at
205 HS{ } clone forgotten-definitions pick set-at [
206 with-nested-compilation-unit
207 ] with-variables ; inline