1 ! Copyright (C) 2004, 2011 Slava Pestov, Daniel Ehrenberg.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: fry accessors alien alien.accessors alien.private arrays
4 byte-arrays classes continuations.private effects generic
5 hashtables hashtables.private io io.backend io.files
6 io.files.private io.streams.c kernel kernel.private math
7 math.private math.parser.private memory memory.private
8 namespaces namespaces.private parser quotations
9 quotations.private sbufs sbufs.private sequences
10 sequences.private slots.private strings strings.private system
11 threads.private classes.tuple classes.tuple.private vectors
12 vectors.private words words.private definitions assocs summary
13 compiler.units system.private combinators tools.memory.private
14 combinators.short-circuit locals locals.backend locals.types
15 combinators.private stack-checker.values generic.single
16 generic.single.private alien.libraries tools.dispatch.private
17 macros tools.profiler.sampling.private classes.algebra
23 stack-checker.branches
24 stack-checker.transforms
25 stack-checker.dependencies
26 stack-checker.recursive-state
27 stack-checker.row-polymorphism ;
28 QUALIFIED-WITH: generic.single.private gsp
29 IN: stack-checker.known-words
31 : infer-special ( word -- )
32 [ current-word set ] [ "special" word-prop call( -- ) ] bi ;
34 : infer-shuffle ( shuffle -- )
35 [ in>> length consume-d ] keep ! inputs shuffle
36 [ drop ] [ shuffle dup copy-values dup output-d ] 2bi ! inputs outputs copies
37 [ nip f f ] [ swap zip ] 2bi ! in-d out-d in-r out-r mapping
40 : infer-shuffle-word ( word -- )
41 "shuffle" word-prop infer-shuffle ;
43 : infer-local-reader ( word -- )
44 ( -- value ) apply-word/effect ;
46 : infer-local-writer ( word -- )
47 ( value -- ) apply-word/effect ;
49 : non-inline-word ( word -- )
50 dup +effect+ depends-on
52 { [ dup "shuffle" word-prop ] [ infer-shuffle-word ] }
53 { [ dup "special" word-prop ] [ infer-special ] }
54 { [ dup "transform-quot" word-prop ] [ apply-transform ] }
55 { [ dup macro? ] [ apply-macro ] }
56 { [ dup local? ] [ infer-local-reader ] }
57 { [ dup local-reader? ] [ infer-local-reader ] }
58 { [ dup local-writer? ] [ infer-local-writer ] }
59 { [ dup "no-compile" word-prop ] [ do-not-compile ] }
60 [ dup required-stack-effect apply-word/effect ]
66 { 3drop ( x y z -- ) }
67 { 4drop ( w x y z -- ) }
69 { 2dup ( x y -- x y x y ) }
70 { 3dup ( x y z -- x y z x y z ) }
71 { 4dup ( w x y z -- w x y z w x y z ) }
72 { rot ( x y z -- y z x ) }
73 { -rot ( x y z -- z x y ) }
74 { dupd ( x y -- x x y ) }
75 { swapd ( x y z -- y x z ) }
77 { 2nip ( x y z -- z ) }
78 { over ( x y -- x y x ) }
79 { pick ( x y z -- x y z x ) }
80 { swap ( x y -- y x ) }
81 } [ "shuffle" set-word-prop ] assoc-each
83 : check-declaration ( declaration -- declaration )
84 dup { [ array? ] [ [ classoid? ] all? ] } 1&&
85 [ bad-declaration-error ] unless ;
87 : infer-declare ( -- )
88 pop-literal check-declaration
89 [ length ensure-d ] keep zip
92 \ declare [ infer-declare ] "special" set-word-prop
95 GENERIC: infer-call* ( value known -- )
97 : (infer-call) ( value -- ) dup known infer-call* ;
99 : infer-call ( -- ) pop-d (infer-call) ;
101 \ call [ infer-call ] "special" set-word-prop
103 \ (call) [ infer-call ] "special" set-word-prop
105 M: literal-tuple infer-call*
106 [ 1array #drop, ] [ infer-literal-quot ] bi* ;
108 M: curried-effect infer-call*
110 [ uncurry ] infer-quot-here
111 [ quot>> known pop-d [ set-known ] keep ]
112 [ obj>> known pop-d [ set-known ] keep ] bi
113 push-d (infer-call) ;
115 M: composed-effect infer-call*
117 [ uncompose ] infer-quot-here
118 [ quot2>> known pop-d [ set-known ] keep ]
119 [ quot1>> known pop-d [ set-known ] keep ] bi
121 1 infer->r infer-call
122 terminated? get [ 1 infer-r> infer-call ] unless ;
124 M: declared-effect infer-call*
125 [ [ known>> infer-call* ] keep ] with-effect-here check-declared-effect ;
127 M: input-parameter infer-call* \ call unknown-macro-input ;
129 M: object infer-call* \ call bad-macro-input ;
131 :: infer-ndip ( word n -- )
133 word def>> infer-quot-here
135 pop n [ infer->r infer-quot-here ] [ infer-r> ] bi
138 : infer-dip ( -- ) \ dip 1 infer-ndip ;
140 \ dip [ infer-dip ] "special" set-word-prop
142 : infer-2dip ( -- ) \ 2dip 2 infer-ndip ;
144 \ 2dip [ infer-2dip ] "special" set-word-prop
146 : infer-3dip ( -- ) \ 3dip 3 infer-ndip ;
148 \ 3dip [ infer-3dip ] "special" set-word-prop
150 :: infer-builder ( quot word -- )
151 2 consume-d dup first2 quot call make-known
152 [ push-d ] [ 1array ] bi word #call, ; inline
154 : infer-curry ( -- ) [ <curried-effect> ] \ curry infer-builder ;
156 \ curry [ infer-curry ] "special" set-word-prop
158 : infer-compose ( -- ) [ <composed-effect> ] \ compose infer-builder ;
160 \ compose [ infer-compose ] "special" set-word-prop
162 : infer-execute ( -- )
170 \ execute [ infer-execute ] "special" set-word-prop
172 \ (execute) [ infer-execute ] "special" set-word-prop
174 : infer-<tuple-boa> ( -- )
176 peek-d literal value>> second 1 + "obj" <array> { tuple } <effect>
179 \ <tuple-boa> [ infer-<tuple-boa> ] "special" set-word-prop
181 : infer-effect-unsafe ( word -- )
186 : infer-execute-effect-unsafe ( -- )
187 \ (execute) infer-effect-unsafe ;
189 \ execute-effect-unsafe [ infer-execute-effect-unsafe ] "special" set-word-prop
191 : infer-call-effect-unsafe ( -- )
192 \ call infer-effect-unsafe ;
194 \ call-effect-unsafe [ infer-call-effect-unsafe ] "special" set-word-prop
196 : infer-load-locals ( -- )
198 consume-d dup copy-values dup output-r
199 [ [ f f ] dip ] [ swap zip ] 2bi #shuffle, ;
201 \ load-locals [ infer-load-locals ] "special" set-word-prop
203 : infer-load-local ( -- )
206 \ load-local [ infer-load-local ] "special" set-word-prop
208 :: infer-get-local ( -- )
209 pop-literal 1 swap - :> n
211 in-r first copy-value 1array :> out-d
212 in-r copy-values :> out-r
217 out-r in-r zip out-d first in-r first 2array suffix
220 \ get-local [ infer-get-local ] "special" set-word-prop
222 : infer-drop-locals ( -- )
223 f f pop-literal consume-r f f #shuffle, ;
225 \ drop-locals [ infer-drop-locals ] "special" set-word-prop
227 : infer-call-effect ( word -- )
228 1 ensure-d first literal value>>
229 add-effect-input add-effect-input
232 { call-effect execute-effect } [
233 dup t "no-compile" set-word-prop
234 dup '[ _ infer-call-effect ] "special" set-word-prop
237 \ if [ infer-if ] "special" set-word-prop
238 \ dispatch [ infer-dispatch ] "special" set-word-prop
240 \ alien-invoke [ infer-alien-invoke ] "special" set-word-prop
241 \ alien-indirect [ infer-alien-indirect ] "special" set-word-prop
242 \ alien-assembly [ infer-alien-assembly ] "special" set-word-prop
243 \ alien-callback [ infer-alien-callback ] "special" set-word-prop
251 inline-cache-miss-tail
257 } [ dup '[ _ do-not-compile ] "special" set-word-prop ] each
260 declare call (call) dip 2dip 3dip curry compose
261 execute (execute) call-effect-unsafe execute-effect-unsafe
262 if dispatch <tuple-boa> do-primitive
263 load-local load-locals get-local drop-locals
264 alien-invoke alien-indirect alien-callback alien-assembly
265 } [ t "no-compile" set-word-prop ] each
267 ! Exceptions to the above
268 \ curry f "no-compile" set-word-prop
269 \ compose f "no-compile" set-word-prop
271 ! More words not to compile
272 \ clear t "no-compile" set-word-prop