1 ! Copyright (C) 2004, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: fry accessors alien alien.accessors arrays byte-arrays classes
4 continuations.private effects generic hashtables
5 hashtables.private io io.backend io.files io.files.private
6 io.streams.c kernel kernel.private math math.private
7 math.parser.private memory memory.private namespaces
8 namespaces.private parser quotations quotations.private sbufs
9 sbufs.private sequences sequences.private slots.private strings
10 strings.private system threads.private classes.tuple
11 classes.tuple.private vectors vectors.private words definitions assocs
12 summary compiler.units system.private combinators
13 combinators.short-circuit locals locals.backend locals.types
14 combinators.private stack-checker.values
15 generic.single generic.single.private
22 stack-checker.branches
23 stack-checker.transforms
24 stack-checker.recursive-state ;
25 IN: stack-checker.known-words
27 : infer-primitive ( word -- )
29 [ "input-classes" word-prop ]
30 [ "default-output-classes" word-prop ] bi <effect>
35 { 2drop (( x y -- )) }
36 { 3drop (( x y z -- )) }
37 { dup (( x -- x x )) }
38 { 2dup (( x y -- x y x y )) }
39 { 3dup (( x y z -- x y z x y z )) }
40 { rot (( x y z -- y z x )) }
41 { -rot (( x y z -- z x y )) }
42 { dupd (( x y -- x x y )) }
43 { swapd (( x y z -- y x z )) }
44 { nip (( x y -- y )) }
45 { 2nip (( x y z -- z )) }
46 { tuck (( x y -- y x y )) }
47 { over (( x y -- x y x )) }
48 { pick (( x y z -- x y z x )) }
49 { swap (( x y -- y x )) }
50 } [ "shuffle" set-word-prop ] assoc-each
52 : infer-shuffle ( shuffle -- )
53 [ in>> length consume-d ] keep ! inputs shuffle
54 [ drop ] [ shuffle dup copy-values dup output-d ] 2bi ! inputs outputs copies
55 [ nip f f ] [ swap zip ] 2bi ! in-d out-d in-r out-r mapping
58 : infer-shuffle-word ( word -- )
59 "shuffle" word-prop infer-shuffle ;
61 : check-declaration ( declaration -- declaration )
62 dup { [ array? ] [ [ class? ] all? ] } 1&&
63 [ bad-declaration-error ] unless ;
65 : infer-declare ( -- )
66 pop-literal nip check-declaration
67 [ length ensure-d ] keep zip
70 GENERIC: infer-call* ( value known -- )
72 : (infer-call) ( value -- ) dup known infer-call* ;
74 : infer-call ( -- ) pop-d (infer-call) ;
76 M: literal infer-call*
77 [ 1array #drop, ] [ infer-literal-quot ] bi* ;
79 M: curried infer-call*
81 [ uncurry ] infer-quot-here
82 [ quot>> known pop-d [ set-known ] keep ]
83 [ obj>> known pop-d [ set-known ] keep ] bi
86 M: composed infer-call*
88 [ uncompose ] infer-quot-here
89 [ quot2>> known pop-d [ set-known ] keep ]
90 [ quot1>> known pop-d [ set-known ] keep ] bi
93 terminated? get [ 1 infer-r> infer-call ] unless ;
96 "literal quotation" literal-expected ;
98 : infer-ndip ( word n -- )
100 [ '[ _ def>> infer-quot-here ] ]
101 [ '[ _ [ pop ] dip [ infer->r infer-quot-here ] [ infer-r> ] bi ] ] bi*
104 : infer-dip ( -- ) \ dip 1 infer-ndip ;
106 : infer-2dip ( -- ) \ 2dip 2 infer-ndip ;
108 : infer-3dip ( -- ) \ 3dip 3 infer-ndip ;
110 : infer-builder ( quot word -- )
113 [ dup first2 ] dip call make-known
114 [ push-d ] [ 1array ] bi
115 ] dip #call, ; inline
117 : infer-curry ( -- ) [ <curried> ] \ curry infer-builder ;
119 : infer-compose ( -- ) [ <composed> ] \ compose infer-builder ;
121 : infer-execute ( -- )
127 "execute must be given a word" time-bomb
130 : infer-<tuple-boa> ( -- )
132 peek-d literal value>> second 1+ { tuple } <effect>
135 : infer-effect-unsafe ( word -- )
140 : infer-execute-effect-unsafe ( -- )
141 \ (execute) infer-effect-unsafe ;
143 : infer-call-effect-unsafe ( -- )
144 \ call infer-effect-unsafe ;
147 \ exit (( n -- * )) apply-word/effect ;
149 : infer-load-locals ( -- )
151 consume-d dup copy-values dup output-r
152 [ [ f f ] dip ] [ swap zip ] 2bi #shuffle, ;
154 : infer-get-local ( -- )
155 [let* | n [ pop-literal nip 1 swap - ]
157 out-d [ in-r first copy-value 1array ]
158 out-r [ in-r copy-values ] |
162 out-r in-r zip out-d first in-r first 2array suffix
166 : infer-drop-locals ( -- )
167 f f pop-literal nip consume-r f f #shuffle, ;
169 : infer-special ( word -- )
171 { \ declare [ infer-declare ] }
172 { \ call [ infer-call ] }
173 { \ (call) [ infer-call ] }
174 { \ dip [ infer-dip ] }
175 { \ 2dip [ infer-2dip ] }
176 { \ 3dip [ infer-3dip ] }
177 { \ curry [ infer-curry ] }
178 { \ compose [ infer-compose ] }
179 { \ execute [ infer-execute ] }
180 { \ (execute) [ infer-execute ] }
181 { \ execute-effect-unsafe [ infer-execute-effect-unsafe ] }
182 { \ call-effect-unsafe [ infer-call-effect-unsafe ] }
183 { \ if [ infer-if ] }
184 { \ dispatch [ infer-dispatch ] }
185 { \ <tuple-boa> [ infer-<tuple-boa> ] }
186 { \ exit [ infer-exit ] }
187 { \ load-local [ 1 infer->r ] }
188 { \ load-locals [ infer-load-locals ] }
189 { \ get-local [ infer-get-local ] }
190 { \ drop-locals [ infer-drop-locals ] }
191 { \ do-primitive [ unknown-primitive-error ] }
192 { \ alien-invoke [ infer-alien-invoke ] }
193 { \ alien-indirect [ infer-alien-indirect ] }
194 { \ alien-callback [ infer-alien-callback ] }
197 : infer-local-reader ( word -- )
198 (( -- value )) apply-word/effect ;
200 : infer-local-writer ( word -- )
201 (( value -- )) apply-word/effect ;
203 : infer-local-word ( word -- )
204 "local-word-def" word-prop infer-quot-here ;
207 declare call (call) dip 2dip 3dip curry compose
208 execute (execute) call-effect-unsafe execute-effect-unsafe if
209 dispatch <tuple-boa> exit load-local load-locals get-local
210 drop-locals do-primitive alien-invoke alien-indirect
213 [ t "special" set-word-prop ]
214 [ t "no-compile" set-word-prop ] bi
217 ! Exceptions to the above
218 \ curry f "no-compile" set-word-prop
219 \ compose f "no-compile" set-word-prop
221 ! More words not to compile
222 \ call t "no-compile" set-word-prop
223 \ execute t "no-compile" set-word-prop
224 \ clear t "no-compile" set-word-prop
226 : non-inline-word ( word -- )
227 dup called-dependency depends-on
229 { [ dup "shuffle" word-prop ] [ infer-shuffle-word ] }
230 { [ dup "special" word-prop ] [ infer-special ] }
231 { [ dup "primitive" word-prop ] [ infer-primitive ] }
232 { [ dup "transform-quot" word-prop ] [ apply-transform ] }
233 { [ dup "macro" word-prop ] [ apply-macro ] }
234 { [ dup local? ] [ infer-local-reader ] }
235 { [ dup local-reader? ] [ infer-local-reader ] }
236 { [ dup local-writer? ] [ infer-local-writer ] }
237 { [ dup local-word? ] [ infer-local-word ] }
241 : define-primitive ( word inputs outputs -- )
242 [ 2drop t "primitive" set-word-prop ]
243 [ drop "input-classes" set-word-prop ]
244 [ nip "default-output-classes" set-word-prop ]
247 ! Stack effects for all primitives
248 \ fixnum< { fixnum fixnum } { object } define-primitive
249 \ fixnum< make-foldable
251 \ fixnum<= { fixnum fixnum } { object } define-primitive
252 \ fixnum<= make-foldable
254 \ fixnum> { fixnum fixnum } { object } define-primitive
255 \ fixnum> make-foldable
257 \ fixnum>= { fixnum fixnum } { object } define-primitive
258 \ fixnum>= make-foldable
260 \ eq? { object object } { object } define-primitive
263 \ bignum>fixnum { bignum } { fixnum } define-primitive
264 \ bignum>fixnum make-foldable
266 \ float>fixnum { float } { fixnum } define-primitive
267 \ bignum>fixnum make-foldable
269 \ fixnum>bignum { fixnum } { bignum } define-primitive
270 \ fixnum>bignum make-foldable
272 \ float>bignum { float } { bignum } define-primitive
273 \ float>bignum make-foldable
275 \ fixnum>float { fixnum } { float } define-primitive
276 \ fixnum>float make-foldable
278 \ bignum>float { bignum } { float } define-primitive
279 \ bignum>float make-foldable
281 \ (string>float) { byte-array } { float } define-primitive
282 \ (string>float) make-foldable
284 \ (float>string) { float } { byte-array } define-primitive
285 \ (float>string) make-foldable
287 \ float>bits { real } { integer } define-primitive
288 \ float>bits make-foldable
290 \ double>bits { real } { integer } define-primitive
291 \ double>bits make-foldable
293 \ bits>float { integer } { float } define-primitive
294 \ bits>float make-foldable
296 \ bits>double { integer } { float } define-primitive
297 \ bits>double make-foldable
299 \ both-fixnums? { object object } { object } define-primitive
301 \ fixnum+ { fixnum fixnum } { integer } define-primitive
302 \ fixnum+ make-foldable
304 \ fixnum+fast { fixnum fixnum } { fixnum } define-primitive
305 \ fixnum+fast make-foldable
307 \ fixnum- { fixnum fixnum } { integer } define-primitive
308 \ fixnum- make-foldable
310 \ fixnum-fast { fixnum fixnum } { fixnum } define-primitive
311 \ fixnum-fast make-foldable
313 \ fixnum* { fixnum fixnum } { integer } define-primitive
314 \ fixnum* make-foldable
316 \ fixnum*fast { fixnum fixnum } { fixnum } define-primitive
317 \ fixnum*fast make-foldable
319 \ fixnum/i { fixnum fixnum } { integer } define-primitive
320 \ fixnum/i make-foldable
322 \ fixnum/i-fast { fixnum fixnum } { fixnum } define-primitive
323 \ fixnum/i-fast make-foldable
325 \ fixnum-mod { fixnum fixnum } { fixnum } define-primitive
326 \ fixnum-mod make-foldable
328 \ fixnum/mod { fixnum fixnum } { integer fixnum } define-primitive
329 \ fixnum/mod make-foldable
331 \ fixnum/mod-fast { fixnum fixnum } { fixnum fixnum } define-primitive
332 \ fixnum/mod-fast make-foldable
334 \ fixnum-bitand { fixnum fixnum } { fixnum } define-primitive
335 \ fixnum-bitand make-foldable
337 \ fixnum-bitor { fixnum fixnum } { fixnum } define-primitive
338 \ fixnum-bitor make-foldable
340 \ fixnum-bitxor { fixnum fixnum } { fixnum } define-primitive
341 \ fixnum-bitxor make-foldable
343 \ fixnum-bitnot { fixnum } { fixnum } define-primitive
344 \ fixnum-bitnot make-foldable
346 \ fixnum-shift { fixnum fixnum } { integer } define-primitive
347 \ fixnum-shift make-foldable
349 \ fixnum-shift-fast { fixnum fixnum } { fixnum } define-primitive
350 \ fixnum-shift-fast make-foldable
352 \ bignum= { bignum bignum } { object } define-primitive
353 \ bignum= make-foldable
355 \ bignum+ { bignum bignum } { bignum } define-primitive
356 \ bignum+ make-foldable
358 \ bignum- { bignum bignum } { bignum } define-primitive
359 \ bignum- make-foldable
361 \ bignum* { bignum bignum } { bignum } define-primitive
362 \ bignum* make-foldable
364 \ bignum/i { bignum bignum } { bignum } define-primitive
365 \ bignum/i make-foldable
367 \ bignum-mod { bignum bignum } { bignum } define-primitive
368 \ bignum-mod make-foldable
370 \ bignum/mod { bignum bignum } { bignum bignum } define-primitive
371 \ bignum/mod make-foldable
373 \ bignum-bitand { bignum bignum } { bignum } define-primitive
374 \ bignum-bitand make-foldable
376 \ bignum-bitor { bignum bignum } { bignum } define-primitive
377 \ bignum-bitor make-foldable
379 \ bignum-bitxor { bignum bignum } { bignum } define-primitive
380 \ bignum-bitxor make-foldable
382 \ bignum-bitnot { bignum } { bignum } define-primitive
383 \ bignum-bitnot make-foldable
385 \ bignum-shift { bignum fixnum } { bignum } define-primitive
386 \ bignum-shift make-foldable
388 \ bignum< { bignum bignum } { object } define-primitive
389 \ bignum< make-foldable
391 \ bignum<= { bignum bignum } { object } define-primitive
392 \ bignum<= make-foldable
394 \ bignum> { bignum bignum } { object } define-primitive
395 \ bignum> make-foldable
397 \ bignum>= { bignum bignum } { object } define-primitive
398 \ bignum>= make-foldable
400 \ bignum-bit? { bignum integer } { object } define-primitive
401 \ bignum-bit? make-foldable
403 \ bignum-log2 { bignum } { bignum } define-primitive
404 \ bignum-log2 make-foldable
406 \ byte-array>bignum { byte-array } { bignum } define-primitive
407 \ byte-array>bignum make-foldable
409 \ float= { float float } { object } define-primitive
410 \ float= make-foldable
412 \ float+ { float float } { float } define-primitive
413 \ float+ make-foldable
415 \ float- { float float } { float } define-primitive
416 \ float- make-foldable
418 \ float* { float float } { float } define-primitive
419 \ float* make-foldable
421 \ float/f { float float } { float } define-primitive
422 \ float/f make-foldable
424 \ float< { float float } { object } define-primitive
425 \ float< make-foldable
427 \ float-mod { float float } { float } define-primitive
428 \ float-mod make-foldable
430 \ float<= { float float } { object } define-primitive
431 \ float<= make-foldable
433 \ float> { float float } { object } define-primitive
434 \ float> make-foldable
436 \ float>= { float float } { object } define-primitive
437 \ float>= make-foldable
439 \ <word> { object object } { word } define-primitive
440 \ <word> make-flushable
442 \ word-xt { word } { integer integer } define-primitive
443 \ word-xt make-flushable
445 \ getenv { fixnum } { object } define-primitive
446 \ getenv make-flushable
448 \ setenv { object fixnum } { } define-primitive
450 \ (exists?) { string } { object } define-primitive
452 \ gc { } { } define-primitive
454 \ gc-stats { } { array } define-primitive
456 \ (save-image) { byte-array } { } define-primitive
458 \ (save-image-and-exit) { byte-array } { } define-primitive
460 \ data-room { } { integer integer array } define-primitive
461 \ data-room make-flushable
463 \ code-room { } { integer integer integer integer } define-primitive
464 \ code-room make-flushable
466 \ micros { } { integer } define-primitive
467 \ micros make-flushable
469 \ tag { object } { fixnum } define-primitive
472 \ (dlopen) { byte-array } { dll } define-primitive
474 \ (dlsym) { byte-array object } { c-ptr } define-primitive
476 \ dlclose { dll } { } define-primitive
478 \ <byte-array> { integer } { byte-array } define-primitive
479 \ <byte-array> make-flushable
481 \ (byte-array) { integer } { byte-array } define-primitive
482 \ (byte-array) make-flushable
484 \ <displaced-alien> { integer c-ptr } { c-ptr } define-primitive
485 \ <displaced-alien> make-flushable
487 \ alien-signed-cell { c-ptr integer } { integer } define-primitive
488 \ alien-signed-cell make-flushable
490 \ set-alien-signed-cell { integer c-ptr integer } { } define-primitive
492 \ alien-unsigned-cell { c-ptr integer } { integer } define-primitive
493 \ alien-unsigned-cell make-flushable
495 \ set-alien-unsigned-cell { integer c-ptr integer } { } define-primitive
497 \ alien-signed-8 { c-ptr integer } { integer } define-primitive
498 \ alien-signed-8 make-flushable
500 \ set-alien-signed-8 { integer c-ptr integer } { } define-primitive
502 \ alien-unsigned-8 { c-ptr integer } { integer } define-primitive
503 \ alien-unsigned-8 make-flushable
505 \ set-alien-unsigned-8 { integer c-ptr integer } { } define-primitive
507 \ alien-signed-4 { c-ptr integer } { integer } define-primitive
508 \ alien-signed-4 make-flushable
510 \ set-alien-signed-4 { integer c-ptr integer } { } define-primitive
512 \ alien-unsigned-4 { c-ptr integer } { integer } define-primitive
513 \ alien-unsigned-4 make-flushable
515 \ set-alien-unsigned-4 { integer c-ptr integer } { } define-primitive
517 \ alien-signed-2 { c-ptr integer } { fixnum } define-primitive
518 \ alien-signed-2 make-flushable
520 \ set-alien-signed-2 { integer c-ptr integer } { } define-primitive
522 \ alien-unsigned-2 { c-ptr integer } { fixnum } define-primitive
523 \ alien-unsigned-2 make-flushable
525 \ set-alien-unsigned-2 { integer c-ptr integer } { } define-primitive
527 \ alien-signed-1 { c-ptr integer } { fixnum } define-primitive
528 \ alien-signed-1 make-flushable
530 \ set-alien-signed-1 { integer c-ptr integer } { } define-primitive
532 \ alien-unsigned-1 { c-ptr integer } { fixnum } define-primitive
533 \ alien-unsigned-1 make-flushable
535 \ set-alien-unsigned-1 { integer c-ptr integer } { } define-primitive
537 \ alien-float { c-ptr integer } { float } define-primitive
538 \ alien-float make-flushable
540 \ set-alien-float { float c-ptr integer } { } define-primitive
542 \ alien-double { c-ptr integer } { float } define-primitive
543 \ alien-double make-flushable
545 \ set-alien-double { float c-ptr integer } { } define-primitive
547 \ alien-cell { c-ptr integer } { simple-c-ptr } define-primitive
548 \ alien-cell make-flushable
550 \ set-alien-cell { c-ptr c-ptr integer } { } define-primitive
552 \ alien-address { alien } { integer } define-primitive
553 \ alien-address make-flushable
555 \ slot { object fixnum } { object } define-primitive
556 \ slot make-flushable
558 \ set-slot { object object fixnum } { } define-primitive
560 \ string-nth { fixnum string } { fixnum } define-primitive
561 \ string-nth make-flushable
563 \ set-string-nth-slow { fixnum fixnum string } { } define-primitive
564 \ set-string-nth-fast { fixnum fixnum string } { } define-primitive
566 \ resize-array { integer array } { array } define-primitive
567 \ resize-array make-flushable
569 \ resize-byte-array { integer byte-array } { byte-array } define-primitive
570 \ resize-byte-array make-flushable
572 \ resize-string { integer string } { string } define-primitive
573 \ resize-string make-flushable
575 \ <array> { integer object } { array } define-primitive
576 \ <array> make-flushable
578 \ begin-scan { } { } define-primitive
580 \ next-object { } { object } define-primitive
582 \ end-scan { } { } define-primitive
584 \ size { object } { fixnum } define-primitive
585 \ size make-flushable
587 \ die { } { } define-primitive
589 \ (fopen) { byte-array byte-array } { alien } define-primitive
591 \ fgetc { alien } { object } define-primitive
593 \ fwrite { string alien } { } define-primitive
595 \ fputc { object alien } { } define-primitive
597 \ fread { integer string } { object } define-primitive
599 \ fflush { alien } { } define-primitive
601 \ fseek { alien integer integer } { } 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 \ check-datastack { array integer integer } { object } define-primitive
627 \ check-datastack make-flushable
629 \ retainstack { } { array } define-primitive
630 \ retainstack make-flushable
632 \ callstack { } { callstack } define-primitive
633 \ callstack make-flushable
635 \ callstack>array { callstack } { array } define-primitive
636 \ callstack>array make-flushable
638 \ (sleep) { integer } { } define-primitive
640 \ become { array array } { } define-primitive
642 \ innermost-frame-executing { callstack } { object } define-primitive
644 \ innermost-frame-scan { callstack } { fixnum } define-primitive
646 \ set-innermost-frame-quot { quotation callstack } { } define-primitive
648 \ dll-valid? { object } { object } define-primitive
650 \ modify-code-heap { array } { } define-primitive
652 \ unimplemented { } { } define-primitive
654 \ gc-reset { } { } define-primitive
656 \ gc-stats { } { array } define-primitive
658 \ jit-compile { quotation } { } define-primitive
660 \ lookup-method { object array } { word } define-primitive
662 \ reset-dispatch-stats { } { } define-primitive
663 \ dispatch-stats { } { array } define-primitive
664 \ reset-inline-cache-stats { } { } define-primitive
665 \ inline-cache-stats { } { array } define-primitive
667 \ optimized? { word } { object } define-primitive