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