1 ! Copyright (C) 2004, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: fry accessors alien alien.accessors arrays byte-arrays
4 classes sequences.private 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 memory namespaces namespaces.private parser
8 quotations quotations.private sbufs sbufs.private
9 sequences sequences.private slots.private strings
10 strings.private system threads.private classes.tuple
11 classes.tuple.private vectors vectors.private words definitions
12 words.private assocs summary compiler.units system.private
13 combinators locals locals.backend locals.types words.private
14 quotations.private stack-checker.values
20 stack-checker.branches
21 stack-checker.transforms
22 stack-checker.recursive-state ;
23 IN: stack-checker.known-words
25 : infer-primitive ( word -- )
27 [ "input-classes" word-prop ]
28 [ "default-output-classes" word-prop ] bi <effect>
33 { 2drop (( x y -- )) }
34 { 3drop (( x y z -- )) }
35 { dup (( x -- x x )) }
36 { 2dup (( x y -- x y x y )) }
37 { 3dup (( x y z -- x y z x y z )) }
38 { rot (( x y z -- y z x )) }
39 { -rot (( x y z -- z x y )) }
40 { dupd (( x y -- x x y )) }
41 { swapd (( x y z -- y x z )) }
42 { nip (( x y -- y )) }
43 { 2nip (( x y z -- z )) }
44 { tuck (( x y -- y x y )) }
45 { over (( x y -- x y x )) }
46 { pick (( x y z -- x y z x )) }
47 { swap (( x y -- y x )) }
48 } [ "shuffle" set-word-prop ] assoc-each
50 : infer-shuffle ( shuffle -- )
51 [ in>> length consume-d ] keep ! inputs shuffle
52 [ drop ] [ shuffle dup copy-values dup output-d ] 2bi ! inputs outputs copies
53 [ nip f f ] [ swap zip ] 2bi ! in-d out-d in-r out-r mapping
56 : infer-shuffle-word ( word -- )
57 "shuffle" word-prop infer-shuffle ;
59 : infer-declare ( -- )
61 [ length ensure-d ] keep zip
64 GENERIC: infer-call* ( value known -- )
66 : (infer-call) ( value -- ) dup known infer-call* ;
68 : infer-call ( -- ) pop-d (infer-call) ;
70 M: literal infer-call*
71 [ 1array #drop, ] [ infer-literal-quot ] bi* ;
73 M: curried infer-call*
75 [ uncurry ] infer-quot-here
76 [ quot>> known pop-d [ set-known ] keep ]
77 [ obj>> known pop-d [ set-known ] keep ] bi
80 M: composed infer-call*
82 [ uncompose ] infer-quot-here
83 [ quot2>> known pop-d [ set-known ] keep ]
84 [ quot1>> known pop-d [ set-known ] keep ] bi
87 terminated? get [ 1 infer-r> infer-call ] unless ;
90 \ literal-expected inference-warning ;
93 1 infer->r infer-call 1 infer-r> ;
96 2 infer->r infer-call 2 infer-r> ;
99 3 infer->r infer-call 3 infer-r> ;
103 [ \ dip def>> infer-quot-here ]
104 [ pop 1 infer->r infer-quot-here 1 infer-r> ]
109 [ \ 2dip def>> infer-quot-here ]
110 [ pop 2 infer->r infer-quot-here 2 infer-r> ]
115 [ \ 3dip def>> infer-quot-here ]
116 [ pop 3 infer->r infer-quot-here 3 infer-r> ]
121 dup first2 <curried> make-known
122 [ push-d ] [ 1array ] bi
125 : infer-compose ( -- )
127 dup first2 <composed> make-known
128 [ push-d ] [ 1array ] bi
131 : infer-execute ( -- )
137 "execute must be given a word" time-bomb
140 : infer-<tuple-boa> ( -- )
142 peek-d literal value>> second 1+ { tuple } <effect>
145 : infer-(throw) ( -- )
147 peek-d literal value>> 2 + f <effect> t >>terminated?
152 { integer } { } t >>terminated? <effect>
155 : infer-load-locals ( -- )
157 consume-d dup copy-values dup output-r
158 [ [ f f ] dip ] [ swap zip ] 2bi #shuffle, ;
160 : infer-get-local ( -- )
161 [let* | n [ pop-literal nip 1 swap - ]
163 out-d [ in-r first copy-value 1array ]
164 out-r [ in-r copy-values ] |
168 out-r in-r zip out-d first in-r first 2array suffix
172 : infer-drop-locals ( -- )
173 f f pop-literal nip consume-r f f #shuffle, ;
175 : infer-special ( word -- )
177 { \ >r [ 1 infer->r ] }
178 { \ r> [ 1 infer-r> ] }
179 { \ declare [ infer-declare ] }
180 { \ call [ infer-call ] }
181 { \ (call) [ infer-call ] }
182 { \ slip [ infer-slip ] }
183 { \ 2slip [ infer-2slip ] }
184 { \ 3slip [ infer-3slip ] }
185 { \ dip [ infer-dip ] }
186 { \ 2dip [ infer-2dip ] }
187 { \ 3dip [ infer-3dip ] }
188 { \ curry [ infer-curry ] }
189 { \ compose [ infer-compose ] }
190 { \ execute [ infer-execute ] }
191 { \ (execute) [ infer-execute ] }
192 { \ if [ infer-if ] }
193 { \ dispatch [ infer-dispatch ] }
194 { \ <tuple-boa> [ infer-<tuple-boa> ] }
195 { \ (throw) [ infer-(throw) ] }
196 { \ exit [ infer-exit ] }
197 { \ load-locals [ infer-load-locals ] }
198 { \ get-local [ infer-get-local ] }
199 { \ drop-locals [ infer-drop-locals ] }
200 { \ do-primitive [ unknown-primitive-error inference-warning ] }
201 { \ alien-invoke [ infer-alien-invoke ] }
202 { \ alien-indirect [ infer-alien-indirect ] }
203 { \ alien-callback [ infer-alien-callback ] }
206 : infer-local-reader ( word -- )
207 (( -- value )) apply-word/effect ;
209 : infer-local-writer ( word -- )
210 (( value -- )) apply-word/effect ;
212 : infer-local-word ( word -- )
213 "local-word-def" word-prop infer-quot-here ;
216 >r r> declare call (call) slip 2slip 3slip dip 2dip 3dip
217 curry compose execute (execute) if dispatch <tuple-boa>
218 (throw) load-locals get-local drop-locals do-primitive
219 alien-invoke alien-indirect alien-callback
220 } [ t "special" set-word-prop ] each
222 { call execute dispatch load-locals get-local drop-locals }
223 [ t "no-compile" set-word-prop ] each
225 : non-inline-word ( word -- )
226 dup called-dependency depends-on
228 { [ dup "shuffle" word-prop ] [ infer-shuffle-word ] }
229 { [ dup "special" word-prop ] [ infer-special ] }
230 { [ dup "primitive" word-prop ] [ infer-primitive ] }
231 { [ dup "transform-quot" word-prop ] [ apply-transform ] }
232 { [ dup "macro" word-prop ] [ apply-macro ] }
233 { [ dup "cannot-infer" word-prop ] [ cannot-infer-effect ] }
234 { [ dup "inferred-effect" word-prop ] [ cached-infer ] }
235 { [ dup local? ] [ infer-local-reader ] }
236 { [ dup local-reader? ] [ infer-local-reader ] }
237 { [ dup local-writer? ] [ infer-local-writer ] }
238 { [ dup local-word? ] [ infer-local-word ] }
239 { [ dup recursive-word? ] [ call-recursive-word ] }
240 [ dup infer-word apply-word/effect ]
243 : define-primitive ( word inputs outputs -- )
244 [ 2drop t "primitive" set-word-prop ]
245 [ drop "input-classes" set-word-prop ]
246 [ nip "default-output-classes" set-word-prop ]
249 ! Stack effects for all primitives
250 \ fixnum< { fixnum fixnum } { object } define-primitive
251 \ fixnum< make-foldable
253 \ fixnum<= { fixnum fixnum } { object } define-primitive
254 \ fixnum<= make-foldable
256 \ fixnum> { fixnum fixnum } { object } define-primitive
257 \ fixnum> make-foldable
259 \ fixnum>= { fixnum fixnum } { object } define-primitive
260 \ fixnum>= make-foldable
262 \ eq? { object object } { object } define-primitive
265 \ bignum>fixnum { bignum } { fixnum } define-primitive
266 \ bignum>fixnum make-foldable
268 \ float>fixnum { float } { fixnum } define-primitive
269 \ bignum>fixnum make-foldable
271 \ fixnum>bignum { fixnum } { bignum } define-primitive
272 \ fixnum>bignum make-foldable
274 \ float>bignum { float } { bignum } define-primitive
275 \ float>bignum make-foldable
277 \ fixnum>float { fixnum } { float } define-primitive
278 \ fixnum>float make-foldable
280 \ bignum>float { bignum } { float } define-primitive
281 \ bignum>float make-foldable
283 \ <ratio> { integer integer } { ratio } define-primitive
284 \ <ratio> make-foldable
286 \ string>float { string } { float } define-primitive
287 \ string>float make-foldable
289 \ float>string { float } { string } define-primitive
290 \ float>string make-foldable
292 \ float>bits { real } { integer } define-primitive
293 \ float>bits make-foldable
295 \ double>bits { real } { integer } define-primitive
296 \ double>bits make-foldable
298 \ bits>float { integer } { float } define-primitive
299 \ bits>float make-foldable
301 \ bits>double { integer } { float } define-primitive
302 \ bits>double make-foldable
304 \ <complex> { real real } { complex } define-primitive
305 \ <complex> make-foldable
307 \ both-fixnums? { object object } { object } define-primitive
309 \ fixnum+ { fixnum fixnum } { integer } define-primitive
310 \ fixnum+ make-foldable
312 \ fixnum+fast { fixnum fixnum } { fixnum } define-primitive
313 \ fixnum+fast make-foldable
315 \ fixnum- { fixnum fixnum } { integer } define-primitive
316 \ fixnum- make-foldable
318 \ fixnum-fast { fixnum fixnum } { fixnum } define-primitive
319 \ fixnum-fast make-foldable
321 \ fixnum* { fixnum fixnum } { integer } define-primitive
322 \ fixnum* make-foldable
324 \ fixnum*fast { fixnum fixnum } { fixnum } define-primitive
325 \ fixnum*fast make-foldable
327 \ fixnum/i { fixnum fixnum } { integer } define-primitive
328 \ fixnum/i make-foldable
330 \ fixnum-mod { fixnum fixnum } { fixnum } define-primitive
331 \ fixnum-mod make-foldable
333 \ fixnum/mod { fixnum fixnum } { integer fixnum } define-primitive
334 \ fixnum/mod make-foldable
336 \ fixnum-bitand { fixnum fixnum } { fixnum } define-primitive
337 \ fixnum-bitand make-foldable
339 \ fixnum-bitor { fixnum fixnum } { fixnum } define-primitive
340 \ fixnum-bitor make-foldable
342 \ fixnum-bitxor { fixnum fixnum } { fixnum } define-primitive
343 \ fixnum-bitxor make-foldable
345 \ fixnum-bitnot { fixnum } { fixnum } define-primitive
346 \ fixnum-bitnot make-foldable
348 \ fixnum-shift { fixnum fixnum } { integer } define-primitive
349 \ fixnum-shift make-foldable
351 \ fixnum-shift-fast { fixnum fixnum } { fixnum } define-primitive
352 \ fixnum-shift-fast make-foldable
354 \ bignum= { bignum bignum } { object } define-primitive
355 \ bignum= make-foldable
357 \ bignum+ { bignum bignum } { bignum } define-primitive
358 \ bignum+ make-foldable
360 \ bignum- { bignum bignum } { bignum } define-primitive
361 \ bignum- make-foldable
363 \ bignum* { bignum bignum } { bignum } define-primitive
364 \ bignum* make-foldable
366 \ bignum/i { bignum bignum } { bignum } define-primitive
367 \ bignum/i make-foldable
369 \ bignum-mod { bignum bignum } { bignum } define-primitive
370 \ bignum-mod make-foldable
372 \ bignum/mod { bignum bignum } { bignum bignum } define-primitive
373 \ bignum/mod make-foldable
375 \ bignum-bitand { bignum bignum } { bignum } define-primitive
376 \ bignum-bitand make-foldable
378 \ bignum-bitor { bignum bignum } { bignum } define-primitive
379 \ bignum-bitor make-foldable
381 \ bignum-bitxor { bignum bignum } { bignum } define-primitive
382 \ bignum-bitxor make-foldable
384 \ bignum-bitnot { bignum } { bignum } define-primitive
385 \ bignum-bitnot make-foldable
387 \ bignum-shift { bignum fixnum } { bignum } define-primitive
388 \ bignum-shift make-foldable
390 \ bignum< { bignum bignum } { object } define-primitive
391 \ bignum< make-foldable
393 \ bignum<= { bignum bignum } { object } define-primitive
394 \ bignum<= make-foldable
396 \ bignum> { bignum bignum } { object } define-primitive
397 \ bignum> make-foldable
399 \ bignum>= { bignum bignum } { object } define-primitive
400 \ bignum>= make-foldable
402 \ bignum-bit? { bignum integer } { object } define-primitive
403 \ bignum-bit? make-foldable
405 \ bignum-log2 { bignum } { bignum } define-primitive
406 \ bignum-log2 make-foldable
408 \ byte-array>bignum { byte-array } { bignum } define-primitive
409 \ byte-array>bignum make-foldable
411 \ float= { float float } { object } define-primitive
412 \ float= make-foldable
414 \ float+ { float float } { float } define-primitive
415 \ float+ make-foldable
417 \ float- { float float } { float } define-primitive
418 \ float- make-foldable
420 \ float* { float float } { float } define-primitive
421 \ float* make-foldable
423 \ float/f { float float } { float } define-primitive
424 \ float/f make-foldable
426 \ float< { float float } { object } define-primitive
427 \ float< make-foldable
429 \ float-mod { float float } { float } define-primitive
430 \ float-mod make-foldable
432 \ float<= { float float } { object } define-primitive
433 \ float<= make-foldable
435 \ float> { float float } { object } define-primitive
436 \ float> make-foldable
438 \ float>= { float float } { object } define-primitive
439 \ float>= make-foldable
441 \ <word> { object object } { word } define-primitive
442 \ <word> make-flushable
444 \ word-xt { word } { integer integer } define-primitive
445 \ word-xt make-flushable
447 \ getenv { fixnum } { object } define-primitive
448 \ getenv make-flushable
450 \ setenv { object fixnum } { } define-primitive
452 \ (exists?) { string } { object } define-primitive
454 \ gc { } { } define-primitive
456 \ gc-stats { } { array } define-primitive
458 \ save-image { string } { } define-primitive
460 \ save-image-and-exit { string } { } define-primitive
462 \ data-room { } { integer integer array } define-primitive
463 \ data-room make-flushable
465 \ code-room { } { integer integer integer integer } define-primitive
466 \ code-room make-flushable
468 \ micros { } { integer } define-primitive
469 \ micros make-flushable
471 \ tag { object } { fixnum } define-primitive
474 \ dlopen { string } { dll } define-primitive
476 \ dlsym { string object } { c-ptr } define-primitive
478 \ dlclose { dll } { } define-primitive
480 \ <byte-array> { integer } { byte-array } define-primitive
481 \ <byte-array> make-flushable
483 \ (byte-array) { integer } { byte-array } define-primitive
484 \ (byte-array) make-flushable
486 \ <displaced-alien> { integer c-ptr } { c-ptr } define-primitive
487 \ <displaced-alien> make-flushable
489 \ alien-signed-cell { c-ptr integer } { integer } define-primitive
490 \ alien-signed-cell make-flushable
492 \ set-alien-signed-cell { integer c-ptr integer } { } define-primitive
494 \ alien-unsigned-cell { c-ptr integer } { integer } define-primitive
495 \ alien-unsigned-cell make-flushable
497 \ set-alien-unsigned-cell { integer c-ptr integer } { } define-primitive
499 \ alien-signed-8 { c-ptr integer } { integer } define-primitive
500 \ alien-signed-8 make-flushable
502 \ set-alien-signed-8 { integer c-ptr integer } { } define-primitive
504 \ alien-unsigned-8 { c-ptr integer } { integer } define-primitive
505 \ alien-unsigned-8 make-flushable
507 \ set-alien-unsigned-8 { integer c-ptr integer } { } define-primitive
509 \ alien-signed-4 { c-ptr integer } { integer } define-primitive
510 \ alien-signed-4 make-flushable
512 \ set-alien-signed-4 { integer c-ptr integer } { } define-primitive
514 \ alien-unsigned-4 { c-ptr integer } { integer } define-primitive
515 \ alien-unsigned-4 make-flushable
517 \ set-alien-unsigned-4 { integer c-ptr integer } { } define-primitive
519 \ alien-signed-2 { c-ptr integer } { fixnum } define-primitive
520 \ alien-signed-2 make-flushable
522 \ set-alien-signed-2 { integer c-ptr integer } { } define-primitive
524 \ alien-unsigned-2 { c-ptr integer } { fixnum } define-primitive
525 \ alien-unsigned-2 make-flushable
527 \ set-alien-unsigned-2 { integer c-ptr integer } { } define-primitive
529 \ alien-signed-1 { c-ptr integer } { fixnum } define-primitive
530 \ alien-signed-1 make-flushable
532 \ set-alien-signed-1 { integer c-ptr integer } { } define-primitive
534 \ alien-unsigned-1 { c-ptr integer } { fixnum } define-primitive
535 \ alien-unsigned-1 make-flushable
537 \ set-alien-unsigned-1 { integer c-ptr integer } { } define-primitive
539 \ alien-float { c-ptr integer } { float } define-primitive
540 \ alien-float make-flushable
542 \ set-alien-float { float c-ptr integer } { } define-primitive
544 \ alien-double { c-ptr integer } { float } define-primitive
545 \ alien-double make-flushable
547 \ set-alien-double { float c-ptr integer } { } define-primitive
549 \ alien-cell { c-ptr integer } { simple-c-ptr } define-primitive
550 \ alien-cell make-flushable
552 \ set-alien-cell { c-ptr c-ptr integer } { } define-primitive
554 \ alien-address { alien } { integer } define-primitive
555 \ alien-address make-flushable
557 \ slot { object fixnum } { object } define-primitive
558 \ slot make-flushable
560 \ set-slot { object object fixnum } { } define-primitive
562 \ string-nth { fixnum string } { fixnum } define-primitive
563 \ string-nth make-flushable
565 \ set-string-nth-slow { fixnum fixnum string } { } define-primitive
566 \ set-string-nth-fast { fixnum fixnum string } { } define-primitive
568 \ resize-array { integer array } { array } define-primitive
569 \ resize-array make-flushable
571 \ resize-byte-array { integer byte-array } { byte-array } define-primitive
572 \ resize-byte-array make-flushable
574 \ resize-string { integer string } { string } define-primitive
575 \ resize-string make-flushable
577 \ <array> { integer object } { array } define-primitive
578 \ <array> make-flushable
580 \ begin-scan { } { } define-primitive
582 \ next-object { } { object } define-primitive
584 \ end-scan { } { } define-primitive
586 \ size { object } { fixnum } define-primitive
587 \ size make-flushable
589 \ die { } { } define-primitive
591 \ fopen { string string } { alien } define-primitive
593 \ fgetc { alien } { object } define-primitive
595 \ fwrite { string alien } { } define-primitive
597 \ fputc { object alien } { } define-primitive
599 \ fread { integer string } { object } define-primitive
601 \ fflush { alien } { } define-primitive
603 \ fclose { alien } { } define-primitive
605 \ <wrapper> { object } { wrapper } define-primitive
606 \ <wrapper> make-foldable
608 \ (clone) { object } { object } define-primitive
609 \ (clone) make-flushable
611 \ <string> { integer integer } { string } define-primitive
612 \ <string> make-flushable
614 \ array>quotation { array } { quotation } define-primitive
615 \ array>quotation make-flushable
617 \ quotation-xt { quotation } { integer } define-primitive
618 \ quotation-xt make-flushable
620 \ <tuple> { tuple-layout } { tuple } define-primitive
621 \ <tuple> make-flushable
623 \ datastack { } { array } define-primitive
624 \ datastack make-flushable
626 \ retainstack { } { array } define-primitive
627 \ retainstack make-flushable
629 \ callstack { } { callstack } define-primitive
630 \ callstack make-flushable
632 \ callstack>array { callstack } { array } define-primitive
633 \ callstack>array make-flushable
635 \ (sleep) { integer } { } define-primitive
637 \ become { array array } { } define-primitive
639 \ innermost-frame-quot { callstack } { quotation } define-primitive
641 \ innermost-frame-scan { callstack } { fixnum } define-primitive
643 \ set-innermost-frame-quot { quotation callstack } { } define-primitive
645 \ dll-valid? { object } { object } define-primitive
647 \ modify-code-heap { array object } { } define-primitive
649 \ unimplemented { } { } define-primitive
651 \ gc-reset { } { } define-primitive
653 \ gc-stats { } { array } define-primitive
655 \ jit-compile { quotation } { } define-primitive