]> gitweb.factorcode.org Git - factor.git/blob - basis/stack-checker/known-words/known-words.factor
Move call( and execute( to core
[factor.git] / basis / stack-checker / known-words / known-words.factor
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
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 combinators.private stack-checker.values
15 stack-checker.alien
16 stack-checker.state
17 stack-checker.errors
18 stack-checker.visitor
19 stack-checker.backend
20 stack-checker.branches
21 stack-checker.transforms
22 stack-checker.recursive-state ;
23 IN: stack-checker.known-words
24
25 : infer-primitive ( word -- )
26     dup
27     [ "input-classes" word-prop ]
28     [ "default-output-classes" word-prop ] bi <effect>
29     apply-word/effect ;
30
31 {
32     { drop  (( x     --             )) }
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
49
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
54     #shuffle, ;
55
56 : infer-shuffle-word ( word -- )
57     "shuffle" word-prop infer-shuffle ;
58
59 : infer-declare ( -- )
60     pop-literal nip
61     [ length ensure-d ] keep zip
62     #declare, ;
63
64 GENERIC: infer-call* ( value known -- )
65
66 : (infer-call) ( value -- ) dup known infer-call* ;
67
68 : infer-call ( -- ) pop-d (infer-call) ;
69
70 M: literal infer-call*
71     [ 1array #drop, ] [ infer-literal-quot ] bi* ;
72
73 M: curried infer-call*
74     swap push-d
75     [ uncurry ] infer-quot-here
76     [ quot>> known pop-d [ set-known ] keep ]
77     [ obj>> known pop-d [ set-known ] keep ] bi
78     push-d (infer-call) ;
79
80 M: composed infer-call*
81     swap push-d
82     [ uncompose ] infer-quot-here
83     [ quot2>> known pop-d [ set-known ] keep ]
84     [ quot1>> known pop-d [ set-known ] keep ] bi
85     push-d push-d
86     1 infer->r infer-call
87     terminated? get [ 1 infer-r> infer-call ] unless ;
88
89 M: object infer-call*
90     "literal quotation" literal-expected ;
91
92 : infer-nslip ( n -- )
93     [ infer->r infer-call ] [ infer-r> ] bi ;
94
95 : infer-slip ( -- ) 1 infer-nslip ;
96
97 : infer-2slip ( -- ) 2 infer-nslip ;
98
99 : infer-3slip ( -- ) 3 infer-nslip ;
100
101 : infer-ndip ( word n -- )
102     [ literals get ] 2dip
103     [ '[ _ def>> infer-quot-here ] ]
104     [ '[ _ [ pop ] dip [ infer->r infer-quot-here ] [ infer-r> ] bi ] ] bi*
105     if-empty ;
106
107 : infer-dip ( -- ) \ dip 1 infer-ndip ;
108
109 : infer-2dip ( -- ) \ 2dip 2 infer-ndip ;
110
111 : infer-3dip ( -- ) \ 3dip 3 infer-ndip ;
112
113 : infer-builder ( quot word -- )
114     [
115         [ 2 consume-d ] dip
116         [ dup first2 ] dip call make-known
117         [ push-d ] [ 1array ] bi
118     ] dip #call, ; inline
119
120 : infer-curry ( -- ) [ <curried> ] \ curry infer-builder ;
121
122 : infer-compose ( -- ) [ <composed> ] \ compose infer-builder ;
123
124 : infer-execute ( -- )
125     pop-literal nip
126     dup word? [
127         apply-object
128     ] [
129         drop
130         "execute must be given a word" time-bomb
131     ] if ;
132
133 : infer-<tuple-boa> ( -- )
134     \ <tuple-boa>
135     peek-d literal value>> second 1+ { tuple } <effect>
136     apply-word/effect ;
137
138 : infer-effect-unsafe ( word -- )
139     pop-literal nip
140     add-effect-input
141     apply-word/effect ;
142
143 : infer-execute-effect-unsafe ( -- )
144     \ execute infer-effect-unsafe ;
145
146 : infer-call-effect-unsafe ( -- )
147     \ call infer-effect-unsafe ;
148
149 : infer-exit ( -- )
150     \ exit (( n -- * )) apply-word/effect ;
151
152 : infer-load-locals ( -- )
153     pop-literal nip
154     consume-d dup copy-values dup output-r
155     [ [ f f ] dip ] [ swap zip ] 2bi #shuffle, ;
156
157 : infer-get-local ( -- )
158     [let* | n [ pop-literal nip 1 swap - ]
159             in-r [ n consume-r ]
160             out-d [ in-r first copy-value 1array ]
161             out-r [ in-r copy-values ] |
162          out-d output-d
163          out-r output-r
164          f out-d in-r out-r
165          out-r in-r zip out-d first in-r first 2array suffix
166          #shuffle,
167     ] ;
168
169 : infer-drop-locals ( -- )
170     f f pop-literal nip consume-r f f #shuffle, ;
171
172 : infer-special ( word -- )
173     {
174         { \ declare [ infer-declare ] }
175         { \ call [ infer-call ] }
176         { \ (call) [ infer-call ] }
177         { \ slip [ infer-slip ] }
178         { \ 2slip [ infer-2slip ] }
179         { \ 3slip [ infer-3slip ] }
180         { \ dip [ infer-dip ] }
181         { \ 2dip [ infer-2dip ] }
182         { \ 3dip [ infer-3dip ] }
183         { \ curry [ infer-curry ] }
184         { \ compose [ infer-compose ] }
185         { \ execute [ infer-execute ] }
186         { \ (execute) [ infer-execute ] }
187         { \ execute-effect-unsafe [ infer-execute-effect-unsafe ] }
188         { \ call-effect-unsafe [ infer-call-effect-unsafe ] }
189         { \ if [ infer-if ] }
190         { \ dispatch [ infer-dispatch ] }
191         { \ <tuple-boa> [ infer-<tuple-boa> ] }
192         { \ exit [ infer-exit ] }
193         { \ load-local [ 1 infer->r ] }
194         { \ load-locals [ infer-load-locals ] }
195         { \ get-local [ infer-get-local ] }
196         { \ drop-locals [ infer-drop-locals ] }
197         { \ do-primitive [ unknown-primitive-error ] }
198         { \ alien-invoke [ infer-alien-invoke ] }
199         { \ alien-indirect [ infer-alien-indirect ] }
200         { \ alien-callback [ infer-alien-callback ] }
201     } case ;
202
203 : infer-local-reader ( word -- )
204     (( -- value )) apply-word/effect ;
205
206 : infer-local-writer ( word -- )
207     (( value -- )) apply-word/effect ;
208
209 : infer-local-word ( word -- )
210     "local-word-def" word-prop infer-quot-here ;
211
212 {
213     declare call (call) slip 2slip 3slip dip 2dip 3dip curry compose
214     execute (execute) call-effect-unsafe execute-effect-unsafe if
215     dispatch <tuple-boa> exit load-local load-locals get-local
216     drop-locals do-primitive alien-invoke alien-indirect
217     alien-callback
218 } [ t "special" set-word-prop ] each
219
220 { call execute dispatch load-locals get-local drop-locals }
221 [ t "no-compile" set-word-prop ] each
222
223 : non-inline-word ( word -- )
224     dup called-dependency depends-on
225     {
226         { [ dup "shuffle" word-prop ] [ infer-shuffle-word ] }
227         { [ dup "special" word-prop ] [ infer-special ] }
228         { [ dup "primitive" word-prop ] [ infer-primitive ] }
229         { [ dup "transform-quot" word-prop ] [ apply-transform ] }
230         { [ dup "macro" word-prop ] [ apply-macro ] }
231         { [ dup "cannot-infer" word-prop ] [ cannot-infer-effect ] }
232         { [ dup "inferred-effect" word-prop ] [ cached-infer ] }
233         { [ dup local? ] [ infer-local-reader ] }
234         { [ dup local-reader? ] [ infer-local-reader ] }
235         { [ dup local-writer? ] [ infer-local-writer ] }
236         { [ dup local-word? ] [ infer-local-word ] }
237         { [ dup recursive-word? ] [ call-recursive-word ] }
238         [ dup infer-word apply-word/effect ]
239     } cond ;
240
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 ]
245     3tri ;
246
247 ! Stack effects for all primitives
248 \ fixnum< { fixnum fixnum } { object } define-primitive
249 \ fixnum< make-foldable
250
251 \ fixnum<= { fixnum fixnum } { object } define-primitive
252 \ fixnum<= make-foldable
253
254 \ fixnum> { fixnum fixnum } { object } define-primitive
255 \ fixnum> make-foldable
256
257 \ fixnum>= { fixnum fixnum } { object } define-primitive
258 \ fixnum>= make-foldable
259
260 \ eq? { object object } { object } define-primitive
261 \ eq? make-foldable
262
263 \ bignum>fixnum { bignum } { fixnum } define-primitive
264 \ bignum>fixnum make-foldable
265
266 \ float>fixnum { float } { fixnum } define-primitive
267 \ bignum>fixnum make-foldable
268
269 \ fixnum>bignum { fixnum } { bignum } define-primitive
270 \ fixnum>bignum make-foldable
271
272 \ float>bignum { float } { bignum } define-primitive
273 \ float>bignum make-foldable
274
275 \ fixnum>float { fixnum } { float } define-primitive
276 \ fixnum>float make-foldable
277
278 \ bignum>float { bignum } { float } define-primitive
279 \ bignum>float make-foldable
280
281 \ <ratio> { integer integer } { ratio } define-primitive
282 \ <ratio> make-foldable
283
284 \ string>float { string } { float } define-primitive
285 \ string>float make-foldable
286
287 \ float>string { float } { string } define-primitive
288 \ float>string make-foldable
289
290 \ float>bits { real } { integer } define-primitive
291 \ float>bits make-foldable
292
293 \ double>bits { real } { integer } define-primitive
294 \ double>bits make-foldable
295
296 \ bits>float { integer } { float } define-primitive
297 \ bits>float make-foldable
298
299 \ bits>double { integer } { float } define-primitive
300 \ bits>double make-foldable
301
302 \ <complex> { real real } { complex } define-primitive
303 \ <complex> make-foldable
304
305 \ both-fixnums? { object object } { object } define-primitive
306
307 \ fixnum+ { fixnum fixnum } { integer } define-primitive
308 \ fixnum+ make-foldable
309
310 \ fixnum+fast { fixnum fixnum } { fixnum } define-primitive
311 \ fixnum+fast make-foldable
312
313 \ fixnum- { fixnum fixnum } { integer } define-primitive
314 \ fixnum- make-foldable
315
316 \ fixnum-fast { fixnum fixnum } { fixnum } define-primitive
317 \ fixnum-fast make-foldable
318
319 \ fixnum* { fixnum fixnum } { integer } define-primitive
320 \ fixnum* make-foldable
321
322 \ fixnum*fast { fixnum fixnum } { fixnum } define-primitive
323 \ fixnum*fast make-foldable
324
325 \ fixnum/i { fixnum fixnum } { integer } define-primitive
326 \ fixnum/i make-foldable
327
328 \ fixnum/i-fast { fixnum fixnum } { fixnum } define-primitive
329 \ fixnum/i-fast make-foldable
330
331 \ fixnum-mod { fixnum fixnum } { fixnum } define-primitive
332 \ fixnum-mod make-foldable
333
334 \ fixnum/mod { fixnum fixnum } { integer fixnum } define-primitive
335 \ fixnum/mod make-foldable
336
337 \ fixnum/mod-fast { fixnum fixnum } { fixnum fixnum } define-primitive
338 \ fixnum/mod-fast make-foldable
339
340 \ fixnum-bitand { fixnum fixnum } { fixnum } define-primitive
341 \ fixnum-bitand make-foldable
342
343 \ fixnum-bitor { fixnum fixnum } { fixnum } define-primitive
344 \ fixnum-bitor make-foldable
345
346 \ fixnum-bitxor { fixnum fixnum } { fixnum } define-primitive
347 \ fixnum-bitxor make-foldable
348
349 \ fixnum-bitnot { fixnum } { fixnum } define-primitive
350 \ fixnum-bitnot make-foldable
351
352 \ fixnum-shift { fixnum fixnum } { integer } define-primitive
353 \ fixnum-shift make-foldable
354
355 \ fixnum-shift-fast { fixnum fixnum } { fixnum } define-primitive
356 \ fixnum-shift-fast make-foldable
357
358 \ bignum= { bignum bignum } { object } define-primitive
359 \ bignum= make-foldable
360
361 \ bignum+ { bignum bignum } { bignum } define-primitive
362 \ bignum+ make-foldable
363
364 \ bignum- { bignum bignum } { bignum } define-primitive
365 \ bignum- make-foldable
366
367 \ bignum* { bignum bignum } { bignum } define-primitive
368 \ bignum* make-foldable
369
370 \ bignum/i { bignum bignum } { bignum } define-primitive
371 \ bignum/i make-foldable
372
373 \ bignum-mod { bignum bignum } { bignum } define-primitive
374 \ bignum-mod make-foldable
375
376 \ bignum/mod { bignum bignum } { bignum bignum } define-primitive
377 \ bignum/mod make-foldable
378
379 \ bignum-bitand { bignum bignum } { bignum } define-primitive
380 \ bignum-bitand make-foldable
381
382 \ bignum-bitor { bignum bignum } { bignum } define-primitive
383 \ bignum-bitor make-foldable
384
385 \ bignum-bitxor { bignum bignum } { bignum } define-primitive
386 \ bignum-bitxor make-foldable
387
388 \ bignum-bitnot { bignum } { bignum } define-primitive
389 \ bignum-bitnot make-foldable
390
391 \ bignum-shift { bignum fixnum } { bignum } define-primitive
392 \ bignum-shift make-foldable
393
394 \ bignum< { bignum bignum } { object } define-primitive
395 \ bignum< make-foldable
396
397 \ bignum<= { bignum bignum } { object } define-primitive
398 \ bignum<= make-foldable
399
400 \ bignum> { bignum bignum } { object } define-primitive
401 \ bignum> make-foldable
402
403 \ bignum>= { bignum bignum } { object } define-primitive
404 \ bignum>= make-foldable
405
406 \ bignum-bit? { bignum integer } { object } define-primitive
407 \ bignum-bit? make-foldable
408
409 \ bignum-log2 { bignum } { bignum } define-primitive
410 \ bignum-log2 make-foldable
411
412 \ byte-array>bignum { byte-array } { bignum } define-primitive
413 \ byte-array>bignum make-foldable
414
415 \ float= { float float } { object } define-primitive
416 \ float= make-foldable
417
418 \ float+ { float float } { float } define-primitive
419 \ float+ make-foldable
420
421 \ float- { float float } { float } define-primitive
422 \ float- make-foldable
423
424 \ float* { float float } { float } define-primitive
425 \ float* make-foldable
426
427 \ float/f { float float } { float } define-primitive
428 \ float/f make-foldable
429
430 \ float< { float float } { object } define-primitive
431 \ float< make-foldable
432
433 \ float-mod { float float } { float } define-primitive
434 \ float-mod make-foldable
435
436 \ float<= { float float } { object } define-primitive
437 \ float<= make-foldable
438
439 \ float> { float float } { object } define-primitive
440 \ float> make-foldable
441
442 \ float>= { float float } { object } define-primitive
443 \ float>= make-foldable
444
445 \ <word> { object object } { word } define-primitive
446 \ <word> make-flushable
447
448 \ word-xt { word } { integer integer } define-primitive
449 \ word-xt make-flushable
450
451 \ getenv { fixnum } { object } define-primitive
452 \ getenv make-flushable
453
454 \ setenv { object fixnum } { } define-primitive
455
456 \ (exists?) { string } { object } define-primitive
457
458 \ gc { } { } define-primitive
459
460 \ gc-stats { } { array } define-primitive
461
462 \ save-image { string } { } define-primitive
463
464 \ save-image-and-exit { string } { } define-primitive
465
466 \ data-room { } { integer integer array } define-primitive
467 \ data-room make-flushable
468
469 \ code-room { } { integer integer integer integer } define-primitive
470 \ code-room  make-flushable
471
472 \ micros { } { integer } define-primitive
473 \ micros make-flushable
474
475 \ tag { object } { fixnum } define-primitive
476 \ tag make-foldable
477
478 \ dlopen { string } { dll } define-primitive
479
480 \ dlsym { string object } { c-ptr } define-primitive
481
482 \ dlclose { dll } { } define-primitive
483
484 \ <byte-array> { integer } { byte-array } define-primitive
485 \ <byte-array> make-flushable
486
487 \ (byte-array) { integer } { byte-array } define-primitive
488 \ (byte-array) make-flushable
489
490 \ <displaced-alien> { integer c-ptr } { c-ptr } define-primitive
491 \ <displaced-alien> make-flushable
492
493 \ alien-signed-cell { c-ptr integer } { integer } define-primitive
494 \ alien-signed-cell make-flushable
495
496 \ set-alien-signed-cell { integer c-ptr integer } { } define-primitive
497
498 \ alien-unsigned-cell { c-ptr integer } { integer } define-primitive
499 \ alien-unsigned-cell make-flushable
500
501 \ set-alien-unsigned-cell { integer c-ptr integer } { } define-primitive
502
503 \ alien-signed-8 { c-ptr integer } { integer } define-primitive
504 \ alien-signed-8 make-flushable
505
506 \ set-alien-signed-8 { integer c-ptr integer } { } define-primitive
507
508 \ alien-unsigned-8 { c-ptr integer } { integer } define-primitive
509 \ alien-unsigned-8 make-flushable
510
511 \ set-alien-unsigned-8 { integer c-ptr integer } { } define-primitive
512
513 \ alien-signed-4 { c-ptr integer } { integer } define-primitive
514 \ alien-signed-4 make-flushable
515
516 \ set-alien-signed-4 { integer c-ptr integer } { } define-primitive
517
518 \ alien-unsigned-4 { c-ptr integer } { integer } define-primitive
519 \ alien-unsigned-4 make-flushable
520
521 \ set-alien-unsigned-4 { integer c-ptr integer } { } define-primitive
522
523 \ alien-signed-2 { c-ptr integer } { fixnum } define-primitive
524 \ alien-signed-2 make-flushable
525
526 \ set-alien-signed-2 { integer c-ptr integer } { } define-primitive
527
528 \ alien-unsigned-2 { c-ptr integer } { fixnum } define-primitive
529 \ alien-unsigned-2 make-flushable
530
531 \ set-alien-unsigned-2 { integer c-ptr integer } { } define-primitive
532
533 \ alien-signed-1 { c-ptr integer } { fixnum } define-primitive
534 \ alien-signed-1 make-flushable
535
536 \ set-alien-signed-1 { integer c-ptr integer } { } define-primitive
537
538 \ alien-unsigned-1 { c-ptr integer } { fixnum } define-primitive
539 \ alien-unsigned-1 make-flushable
540
541 \ set-alien-unsigned-1 { integer c-ptr integer } { } define-primitive
542
543 \ alien-float { c-ptr integer } { float } define-primitive
544 \ alien-float make-flushable
545
546 \ set-alien-float { float c-ptr integer } { } define-primitive
547
548 \ alien-double { c-ptr integer } { float } define-primitive
549 \ alien-double make-flushable
550
551 \ set-alien-double { float c-ptr integer } { } define-primitive
552
553 \ alien-cell { c-ptr integer } { simple-c-ptr } define-primitive
554 \ alien-cell make-flushable
555
556 \ set-alien-cell { c-ptr c-ptr integer } { } define-primitive
557
558 \ alien-address { alien } { integer } define-primitive
559 \ alien-address make-flushable
560
561 \ slot { object fixnum } { object } define-primitive
562 \ slot make-flushable
563
564 \ set-slot { object object fixnum } { } define-primitive
565
566 \ string-nth { fixnum string } { fixnum } define-primitive
567 \ string-nth make-flushable
568
569 \ set-string-nth-slow { fixnum fixnum string } { } define-primitive
570 \ set-string-nth-fast { fixnum fixnum string } { } define-primitive
571
572 \ resize-array { integer array } { array } define-primitive
573 \ resize-array make-flushable
574
575 \ resize-byte-array { integer byte-array } { byte-array } define-primitive
576 \ resize-byte-array make-flushable
577
578 \ resize-string { integer string } { string } define-primitive
579 \ resize-string make-flushable
580
581 \ <array> { integer object } { array } define-primitive
582 \ <array> make-flushable
583
584 \ begin-scan { } { } define-primitive
585
586 \ next-object { } { object } define-primitive
587
588 \ end-scan { } { } define-primitive
589
590 \ size { object } { fixnum } define-primitive
591 \ size make-flushable
592
593 \ die { } { } define-primitive
594
595 \ fopen { string string } { alien } define-primitive
596
597 \ fgetc { alien } { object } define-primitive
598
599 \ fwrite { string alien } { } define-primitive
600
601 \ fputc { object alien } { } define-primitive
602
603 \ fread { integer string } { object } define-primitive
604
605 \ fflush { alien } { } define-primitive
606
607 \ fclose { alien } { } define-primitive
608
609 \ <wrapper> { object } { wrapper } define-primitive
610 \ <wrapper> make-foldable
611
612 \ (clone) { object } { object } define-primitive
613 \ (clone) make-flushable
614
615 \ <string> { integer integer } { string } define-primitive
616 \ <string> make-flushable
617
618 \ array>quotation { array } { quotation } define-primitive
619 \ array>quotation make-flushable
620
621 \ quotation-xt { quotation } { integer } define-primitive
622 \ quotation-xt make-flushable
623
624 \ <tuple> { tuple-layout } { tuple } define-primitive
625 \ <tuple> make-flushable
626
627 \ datastack { } { array } define-primitive
628 \ datastack make-flushable
629
630 \ check-datastack { array integer integer } { object } define-primitive
631 \ check-datastack make-flushable
632
633 \ retainstack { } { array } define-primitive
634 \ retainstack make-flushable
635
636 \ callstack { } { callstack } define-primitive
637 \ callstack make-flushable
638
639 \ callstack>array { callstack } { array } define-primitive
640 \ callstack>array make-flushable
641
642 \ (sleep) { integer } { } define-primitive
643
644 \ become { array array } { } define-primitive
645
646 \ innermost-frame-quot { callstack } { quotation } define-primitive
647
648 \ innermost-frame-scan { callstack } { fixnum } define-primitive
649
650 \ set-innermost-frame-quot { quotation callstack } { } define-primitive
651
652 \ dll-valid? { object } { object } define-primitive
653
654 \ modify-code-heap { array } { } define-primitive
655
656 \ unimplemented { } { } define-primitive
657
658 \ gc-reset { } { } define-primitive
659
660 \ gc-stats { } { array } define-primitive
661
662 \ jit-compile { quotation } { } define-primitive