1 USING: accessors alien alien.c-types alien.complex alien.data alien.libraries
2 alien.syntax arrays byte-arrays classes classes.struct combinators
3 combinators.extras compiler compiler.test concurrency.promises continuations
4 destructors effects generalizations io io.backend io.pathnames
5 io.streams.string kernel kernel.private libc layouts locals math math.bitwise
6 math.private memory namespaces namespaces.private random parser quotations
7 sequences slots.private specialized-arrays stack-checker stack-checker.errors
8 system threads tools.test words ;
9 FROM: alien.c-types => float short ;
10 SPECIALIZED-ARRAY: float
11 SPECIALIZED-ARRAY: char
12 IN: compiler.tests.alien
14 ! Make sure that invalid inputs don't pass the stack checker
15 [ [ void { } "cdecl" alien-indirect ] infer ] must-fail
16 [ [ "void" { } cdecl alien-indirect ] infer ] must-fail
17 [ [ void* 3 cdecl alien-indirect ] infer ] must-fail
18 [ [ void* { "int" } cdecl alien-indirect ] infer ] must-fail
19 [ [ void* { int } cdecl { } alien-callback ] infer ] must-fail
22 : libfactor-ffi-tests-path ( -- string )
23 "resource:" absolute-path
25 { [ os windows? ] [ "libfactor-ffi-test.dll" ] }
26 { [ os macosx? ] [ "libfactor-ffi-test.dylib" ] }
27 { [ os unix? ] [ "libfactor-ffi-test.so" ] }
30 : mingw? ( -- ? ) os windows? vm-compiler "GCC" head? and ;
32 "f-cdecl" libfactor-ffi-tests-path mingw? mingw cdecl ? add-library
34 "f-stdcall" libfactor-ffi-tests-path stdcall add-library
36 "f-fastcall" libfactor-ffi-tests-path fastcall add-library
41 FUNCTION: void ffi_test_0 ( )
42 { } [ ffi_test_0 ] unit-test
44 FUNCTION: int ffi_test_1 ( )
45 { 3 } [ ffi_test_1 ] unit-test
47 { } [ \ ffi_test_1 def>> [ drop ] append compile-call ] unit-test
49 FUNCTION: int ffi_test_2 ( int x, int y )
50 { 5 } [ 2 3 ffi_test_2 ] unit-test
51 [ "hi" 3 ffi_test_2 ] must-fail
53 FUNCTION: int ffi_test_3 ( int x, int y, int z, int t )
54 { 25 } [ 2 3 4 5 ffi_test_3 ] unit-test
56 FUNCTION: float ffi_test_4 ( )
57 { 1.5 } [ ffi_test_4 ] unit-test
59 FUNCTION: double ffi_test_5 ( )
60 { 1.5 } [ ffi_test_5 ] unit-test
62 FUNCTION: int ffi_test_9 ( int a, int b, int c, int d, int e, int f, int g )
63 { 28 } [ 1 2 3 4 5 6 7 ffi_test_9 ] unit-test
64 [ "a" 2 3 4 5 6 7 ffi_test_9 ] must-fail
65 [ 1 2 3 4 5 6 "a" ffi_test_9 ] must-fail
67 STRUCT: FOO { x int } { y int } ;
69 : make-FOO ( x y -- FOO )
70 FOO <struct> swap >>y swap >>x ;
72 FUNCTION: int ffi_test_11 ( int a, FOO b, int c )
74 { 14 } [ 1 2 3 make-FOO 4 ffi_test_11 ] unit-test
76 FUNCTION: int ffi_test_13 ( int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k )
78 { 66 } [ 1 2 3 4 5 6 7 8 9 10 11 ffi_test_13 ] unit-test
80 FUNCTION: FOO ffi_test_14 ( int x, int y )
82 { 11 6 } [ 11 6 ffi_test_14 [ x>> ] [ y>> ] bi ] unit-test
84 FUNCTION: c-string ffi_test_15 ( c-string x, c-string y )
86 { "foo" } [ "xy" "zt" ffi_test_15 ] unit-test
87 { "bar" } [ "xy" "xy" ffi_test_15 ] unit-test
88 [ 1 2 ffi_test_15 ] must-fail
90 STRUCT: BAR { x long } { y long } { z long } ;
92 FUNCTION: BAR ffi_test_16 ( long x, long y, long z )
95 11 6 -7 ffi_test_16 [ x>> ] [ y>> ] [ z>> ] tri
98 STRUCT: TINY { x int } ;
100 FUNCTION: TINY ffi_test_17 ( int x )
102 { 11 } [ 11 ffi_test_17 x>> ] unit-test
104 [ [ alien-indirect ] infer ] [ inference-error? ] must-fail-with
106 : indirect-test-1 ( ptr -- result )
107 int { } cdecl alien-indirect ;
109 { 1 1 } [ indirect-test-1 ] must-infer-as
111 { 3 } [ &: ffi_test_1 indirect-test-1 ] unit-test
113 : indirect-test-1' ( ptr -- )
114 int { } cdecl alien-indirect drop ;
116 { 1 0 } [ indirect-test-1' ] must-infer-as
118 { } [ &: ffi_test_1 indirect-test-1' ] unit-test
120 [ -1 indirect-test-1 ] must-fail
122 : indirect-test-2 ( x y ptr -- result )
123 int { int int } cdecl alien-indirect gc ;
125 { 3 1 } [ indirect-test-2 ] must-infer-as
127 { 5 } [ 2 3 &: ffi_test_2 indirect-test-2 ] unit-test
129 : indirect-test-3 ( a b c d ptr -- result )
130 int { int int int int } stdcall alien-indirect
133 { f } [ "f-stdcall" library-dll f = ] unit-test
134 { stdcall } [ "f-stdcall" lookup-library abi>> ] unit-test
136 : ffi_test_18 ( w x y z -- int )
137 int "f-stdcall" "ffi_test_18" { int int int int } f
140 { 25 } [ 2 3 4 5 ffi_test_18 ] unit-test
142 : ffi_test_19 ( x y z -- BAR )
143 BAR "f-stdcall" "ffi_test_19" { long long long } f
147 11 6 -7 ffi_test_19 [ x>> ] [ y>> ] [ z>> ] tri
150 : multi_ffi_test_18 ( w x y z w' x' y' z' -- int int )
151 [ int "f-stdcall" "ffi_test_18" { int int int int } f alien-invoke ]
153 int "f-stdcall" "ffi_test_18" { int int int int } f alien-invoke
156 { 25 85 } [ 2 3 4 5 6 7 8 9 multi_ffi_test_18 ] unit-test
158 FUNCTION: double ffi_test_6 ( float x, float y )
159 { 6.0 } [ 3.0 2.0 ffi_test_6 ] unit-test
160 [ "a" "b" ffi_test_6 ] must-fail
162 FUNCTION: double ffi_test_7 ( double x, double y )
163 { 6.0 } [ 3.0 2.0 ffi_test_7 ] unit-test
165 FUNCTION: double ffi_test_8 ( double x, float y, double z, float t, int w )
166 { 19.0 } [ 3.0 2.0 1.0 6.0 7 ffi_test_8 ] unit-test
168 FUNCTION: int ffi_test_10 ( int a, int b, double c, int d, float e, int f, int g, int h )
169 { -34 } [ 1 2 3.0 4 5.0 6 7 8 ffi_test_10 ] unit-test
171 FUNCTION: void ffi_test_20 ( double x1, double x2, double x3,
172 double y1, double y2, double y3,
173 double z1, double z2, double z3 )
175 { } [ 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 ffi_test_20 ] unit-test
177 ! Make sure XT doesn't get clobbered in stack frame
179 : ffi_test_31 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a -- result y )
181 "f-cdecl" "ffi_test_31"
182 { int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int int } f
185 { 861 3 } [ 42 [ ] each-integer ffi_test_31 ] unit-test
187 : ffi_test_31_point_5 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a -- result )
189 "f-cdecl" "ffi_test_31_point_5"
190 { float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float float } f
193 { 861.0 } [ 42 [ >float ] each-integer ffi_test_31_point_5 ] unit-test
195 FUNCTION: longlong ffi_test_21 ( long x, long y )
197 { 121932631112635269 } [ 123456789 987654321 ffi_test_21 ] unit-test
199 FUNCTION: long ffi_test_22 ( long x, longlong y, longlong z )
201 { 987655432 } [ 1111 121932631112635269 123456789 ffi_test_22 ] unit-test
203 [ 1111 f 123456789 ffi_test_22 ] must-fail
206 { x float } { y float }
207 { w float } { h float } ;
209 : <RECT> ( x y w h -- rect )
216 FUNCTION: int ffi_test_12 ( int a, int b, RECT c, int d, int e, int f )
218 { 45 } [ 1 2 3.0 4.0 5.0 6.0 <RECT> 7 8 9 ffi_test_12 ] unit-test
220 [ 1 2 { 1 2 3 } 7 8 9 ffi_test_12 ] must-fail
222 FUNCTION: float ffi_test_23 ( float[3] x, float[3] y )
225 { 1.0 2.0 3.0 } float >c-array
226 { 4.0 5.0 6.0 } float >c-array
230 ! Test odd-size structs
231 STRUCT: test-struct-1 { x char[1] } ;
233 FUNCTION: test-struct-1 ffi_test_24 ( )
235 { S{ test-struct-1 { x char-array{ 1 } } } } [ ffi_test_24 ] unit-test
237 STRUCT: test-struct-2 { x char[2] } ;
239 FUNCTION: test-struct-2 ffi_test_25 ( )
241 { S{ test-struct-2 { x char-array{ 1 2 } } } } [ ffi_test_25 ] unit-test
243 STRUCT: test-struct-3 { x char[3] } ;
245 FUNCTION: test-struct-3 ffi_test_26 ( )
247 { S{ test-struct-3 { x char-array{ 1 2 3 } } } } [ ffi_test_26 ] unit-test
249 STRUCT: test-struct-4 { x char[4] } ;
251 FUNCTION: test-struct-4 ffi_test_27 ( )
253 { S{ test-struct-4 { x char-array{ 1 2 3 4 } } } } [ ffi_test_27 ] unit-test
255 STRUCT: test-struct-5 { x char[5] } ;
257 FUNCTION: test-struct-5 ffi_test_28 ( )
259 { S{ test-struct-5 { x char-array{ 1 2 3 4 5 } } } } [ ffi_test_28 ] unit-test
261 STRUCT: test-struct-6 { x char[6] } ;
263 FUNCTION: test-struct-6 ffi_test_29 ( )
265 { S{ test-struct-6 { x char-array{ 1 2 3 4 5 6 } } } } [ ffi_test_29 ] unit-test
267 STRUCT: test-struct-7 { x char[7] } ;
269 FUNCTION: test-struct-7 ffi_test_30 ( )
271 { S{ test-struct-7 { x char-array{ 1 2 3 4 5 6 7 } } } } [ ffi_test_30 ] unit-test
273 STRUCT: test-struct-8 { x double } { y double } ;
275 FUNCTION: double ffi_test_32 ( test-struct-8 x, int y )
278 test-struct-8 <struct>
284 STRUCT: test-struct-9 { x float } { y float } ;
286 FUNCTION: double ffi_test_33 ( test-struct-9 x, int y )
289 test-struct-9 <struct>
295 STRUCT: test-struct-10 { x float } { y int } ;
297 FUNCTION: double ffi_test_34 ( test-struct-10 x, int y )
300 test-struct-10 <struct>
306 STRUCT: test-struct-11 { x int } { y int } ;
308 FUNCTION: double ffi_test_35 ( test-struct-11 x, int y )
311 test-struct-11 <struct>
317 STRUCT: test-struct-12 { a int } { x double } ;
319 : make-struct-12 ( x -- alien )
320 test-struct-12 <struct>
323 FUNCTION: double ffi_test_36 ( test-struct-12 x )
325 { 1.23456 } [ 1.23456 make-struct-12 ffi_test_36 ] unit-test
327 FUNCTION: ulonglong ffi_test_38 ( ulonglong x, ulonglong y )
329 { t } [ 31 2^ 32 2^ ffi_test_38 63 2^ = ] unit-test
332 : callback-throws ( -- x )
333 int { } cdecl [ "Hi" throw ] alien-callback ;
336 callback-throws [ alien? ] with-callback
339 : callback-1 ( -- callback ) void { } cdecl [ ] alien-callback ;
341 { 0 1 } [ [ callback-1 ] infer [ in>> length ] [ out>> length ] bi ] unit-test
343 { t } [ callback-1 [ alien? ] with-callback ] unit-test
345 : callback_test_1 ( ptr -- ) void { } cdecl alien-indirect ;
347 { } [ callback-1 [ callback_test_1 ] with-callback ] unit-test
349 : callback-2 ( -- callback ) void { } cdecl [ [ 5 throw ] ignore-errors ] alien-callback ;
351 { } [ callback-2 [ callback_test_1 ] with-callback ] unit-test
353 : callback-3 ( -- callback ) void { } cdecl [ 5 "x" set ] alien-callback ;
358 3 "x" set callback-3 [ callback_test_1 ] with-callback
360 "x" get "x" get-global
364 : callback-5 ( -- callback )
365 void { } cdecl [ gc ] alien-callback ;
368 "testing" callback-5 [ callback_test_1 ] with-callback
371 : callback-5b ( -- callback )
372 void { } cdecl [ compact-gc ] alien-callback ;
375 "testing" callback-5b [ callback_test_1 ] with-callback
378 : callback-6 ( -- callback )
379 void { } cdecl [ [ continue ] callcc0 ] alien-callback ;
382 callback-6 [ callback_test_1 1 2 3 ] with-callback
385 : callback-7 ( -- callback )
386 void { } cdecl [ 1000000 sleep ] alien-callback ;
388 { 1 2 3 } [ callback-7 [ callback_test_1 1 2 3 ] with-callback ] unit-test
390 { f } [ namespace global eq? ] unit-test
392 : callback-8 ( -- callback )
393 void { } cdecl [ [ ] in-thread yield ] alien-callback ;
395 { } [ callback-8 [ callback_test_1 ] with-callback ] unit-test
397 : callback-9 ( -- callback )
398 int { int int int } cdecl [
402 FUNCTION: void ffi_test_36_point_5 ( )
404 { } [ ffi_test_36_point_5 ] unit-test
406 FUNCTION: int ffi_test_37 ( void* func )
408 { 1 } [ callback-9 [ ffi_test_37 ] with-callback ] unit-test
410 { 7 } [ callback-9 [ ffi_test_37 ] with-callback ] unit-test
412 STRUCT: test_struct_13
420 : make-test-struct-13 ( -- alien )
421 test_struct_13 <struct>
429 FUNCTION: int ffi_test_39 ( long a, long b, test_struct_13 s )
431 { 21 } [ 12347 12347 make-test-struct-13 ffi_test_39 ] unit-test
433 ! Joe Groff found this problem
440 : <double-rect> ( a b c d -- foo )
447 : >double-rect< ( foo -- a b c d )
455 : double-rect-callback ( -- alien )
456 void { void* void* double-rect } cdecl
457 [ "example" set-global 2drop ] alien-callback ;
459 : double-rect-test ( arg callback -- arg' )
461 void { void* void* double-rect } cdecl alien-indirect
462 "example" get-global ;
464 { byte-array 1.0 2.0 3.0 4.0 } [
465 1.0 2.0 3.0 4.0 <double-rect>
466 double-rect-callback [
468 [ >c-ptr class-of ] [ >double-rect< ] bi
472 STRUCT: test_struct_14
476 FUNCTION: test_struct_14 ffi_test_40 ( double x1, double x2 )
479 1.0 2.0 ffi_test_40 [ x1>> ] [ x2>> ] bi
482 : callback-10 ( -- callback )
483 test_struct_14 { double double } cdecl
485 test_struct_14 <struct>
490 : callback-10-test ( x1 x2 callback -- result )
491 test_struct_14 { double double } cdecl alien-indirect ;
494 1.0 2.0 callback-10 [
495 callback-10-test [ x1>> ] [ x2>> ] bi
499 FUNCTION: test-struct-12 ffi_test_41 ( int a, double x )
506 : callback-11 ( -- callback )
507 test-struct-12 { int double } cdecl
509 test-struct-12 <struct>
514 : callback-11-test ( x1 x2 callback -- result )
515 test-struct-12 { int double } cdecl alien-indirect ;
519 callback-11-test [ a>> ] [ x>> ] bi
523 STRUCT: test_struct_15
527 FUNCTION: test_struct_15 ffi_test_42 ( float x, float y )
529 { 1.0 2.0 } [ 1.0 2.0 ffi_test_42 [ x>> ] [ y>> ] bi ] unit-test
531 : callback-12 ( -- callback )
532 test_struct_15 { float float } cdecl
534 test_struct_15 <struct>
539 : callback-12-test ( x1 x2 callback -- result )
540 test_struct_15 { float float } cdecl alien-indirect ;
543 1.0 2.0 callback-12 [
544 callback-12-test [ x>> ] [ y>> ] bi
548 STRUCT: test_struct_16
552 FUNCTION: test_struct_16 ffi_test_43 ( float x, int a )
554 { 1.0 2 } [ 1.0 2 ffi_test_43 [ x>> ] [ a>> ] bi ] unit-test
556 : callback-13 ( -- callback )
557 test_struct_16 { float int } cdecl
559 test_struct_16 <struct>
564 : callback-13-test ( x1 x2 callback -- result )
565 test_struct_16 { float int } cdecl alien-indirect ;
569 callback-13-test [ x>> ] [ a>> ] bi
573 FUNCTION: test_struct_14 ffi_test_44 ( ) inline
575 { 1.0 2.0 } [ ffi_test_44 [ x1>> ] [ x2>> ] bi ] unit-test
577 : stack-frame-bustage ( -- a b ) ffi_test_44 gc 3 ;
579 [ stack-frame-bustage ] must-not-fail
584 FUNCTION: complex-float ffi_test_45 ( int x )
586 { C{ 3.0 0.0 } } [ 3 ffi_test_45 ] unit-test
588 FUNCTION: complex-double ffi_test_46 ( int x )
590 { C{ 3.0 0.0 } } [ 3 ffi_test_46 ] unit-test
592 FUNCTION: complex-float ffi_test_47 ( complex-float x, complex-double y )
596 C{ 1.5 1.0 } ffi_test_47
600 STRUCT: bool-field-test
605 FUNCTION: short ffi_test_48 ( bool-field-test x )
608 bool-field-test <struct>
615 ! Test interaction between threads and callbacks
616 : thread-callback-1 ( -- callback )
617 int { } cdecl [ yield 100 ] alien-callback ;
619 : thread-callback-2 ( -- callback )
620 int { } cdecl [ yield 200 ] alien-callback ;
622 : thread-callback-invoker ( callback -- n )
623 int { } cdecl alien-indirect ;
628 thread-callback-invoker
629 ] with-callback "p" get fulfill
632 thread-callback-2 [ thread-callback-invoker ] with-callback
634 { 100 } [ "p" get ?promise ] unit-test
636 ! More alien-assembly tests are in cpu.* vocabs
637 : assembly-test-1 ( -- ) void { } cdecl [ ] alien-assembly ;
639 { } [ assembly-test-1 ] unit-test
641 { f } [ "f-fastcall" library-dll f = ] unit-test
642 { fastcall } [ "f-fastcall" lookup-library abi>> ] unit-test
644 : ffi_test_49 ( x -- int )
645 int "f-fastcall" "ffi_test_49" { int } f
647 : ffi_test_50 ( x y -- int )
648 int "f-fastcall" "ffi_test_50" { int int } f
650 : ffi_test_51 ( x y z -- int )
651 int "f-fastcall" "ffi_test_51" { int int int } f
653 : multi_ffi_test_51 ( x y z x' y' z' -- int int )
654 [ int "f-fastcall" "ffi_test_51" { int int int } f alien-invoke ]
656 int "f-fastcall" "ffi_test_51" { int int int } f alien-invoke gc ;
658 { 4 } [ 3 ffi_test_49 ] unit-test
659 { 8 } [ 3 4 ffi_test_50 ] unit-test
660 { 13 } [ 3 4 5 ffi_test_51 ] unit-test
661 { 13 22 } [ 3 4 5 6 7 8 multi_ffi_test_51 ] unit-test
663 : ffi_test_52 ( x y z -- int )
664 int "f-fastcall" "ffi_test_52" { int float int } f
666 : ffi_test_53 ( x y z w -- int )
667 int "f-fastcall" "ffi_test_53" { int float int int } f
669 : ffi_test_57 ( x y -- test-struct-11 )
670 test-struct-11 "f-fastcall" "ffi_test_57" { int int } f
672 : ffi_test_58 ( x y z -- test-struct-11 )
673 test-struct-11 "f-fastcall" "ffi_test_58" { int int int } f
676 ! Make sure that large longlong/ulonglong are correctly dealt with
677 FUNCTION: longlong ffi_test_59 ( longlong x )
678 FUNCTION: ulonglong ffi_test_60 ( ulonglong x )
680 { t } [ most-positive-fixnum 1 + [ ffi_test_59 ] keep = ] unit-test
681 { t } [ most-positive-fixnum 1 + [ ffi_test_60 ] keep = ] unit-test
683 { -1 } [ -1 ffi_test_59 ] unit-test
684 { -1 } [ 0xffffffffffffffff ffi_test_59 ] unit-test
685 { 0xffffffffffffffff } [ -1 ffi_test_60 ] unit-test
686 { 0xffffffffffffffff } [ 0xffffffffffffffff ffi_test_60 ] unit-test
690 { 13 } [ 3 4.0 5 ffi_test_52 ] unit-test
692 { 19 } [ 3 4.0 5 6 ffi_test_53 ] unit-test
695 { S{ test-struct-11 f 7 -1 } } [ 3 4 ffi_test_57 ] unit-test
697 { S{ test-struct-11 f 7 -3 } } [ 3 4 7 ffi_test_58 ] unit-test
699 : fastcall-ii-indirect ( x y ptr -- result )
700 int { int int } fastcall alien-indirect ;
702 : fastcall-iii-indirect ( x y z ptr -- result )
703 int { int int int } fastcall alien-indirect ;
705 : fastcall-ifi-indirect ( x y z ptr -- result )
706 int { int float int } fastcall alien-indirect ;
708 : fastcall-ifii-indirect ( x y z w ptr -- result )
709 int { int float int int } fastcall alien-indirect ;
711 : fastcall-struct-return-ii-indirect ( x y ptr -- result )
712 test-struct-11 { int int } fastcall alien-indirect ;
714 : fastcall-struct-return-iii-indirect ( x y z ptr -- result )
715 test-struct-11 { int int int } fastcall alien-indirect ;
718 3 4 &: ffi_test_50 fastcall-ii-indirect
722 3 4 5 &: ffi_test_51 fastcall-iii-indirect
727 3 4.0 5 &: ffi_test_52 fastcall-ifi-indirect
731 3 4.0 5 6 &: ffi_test_53 fastcall-ifii-indirect
735 { S{ test-struct-11 f 7 -1 } } [
736 3 4 &: ffi_test_57 fastcall-struct-return-ii-indirect
739 { S{ test-struct-11 f 7 -3 } } [
740 3 4 7 &: ffi_test_58 fastcall-struct-return-iii-indirect
743 : fastcall-ii-callback ( -- ptr )
744 int { int int } fastcall [ + 1 + ] alien-callback ;
746 : fastcall-iii-callback ( -- ptr )
747 int { int int int } fastcall [ + + 1 + ] alien-callback ;
749 : fastcall-ifi-callback ( -- ptr )
750 int { int float int } fastcall
751 [ [ >integer ] dip + + 1 + ] alien-callback ;
753 : fastcall-ifii-callback ( -- ptr )
754 int { int float int int } fastcall
755 [ [ >integer ] 2dip + + + 1 + ] alien-callback ;
757 : fastcall-struct-return-ii-callback ( -- ptr )
758 test-struct-11 { int int } fastcall
759 [ [ + ] [ - ] 2bi test-struct-11 boa ] alien-callback ;
761 : fastcall-struct-return-iii-callback ( -- ptr )
762 test-struct-11 { int int int } fastcall
763 [ [ drop + ] [ - nip ] 3bi test-struct-11 boa ] alien-callback ;
766 3 4 fastcall-ii-callback [ fastcall-ii-indirect ] with-callback
770 3 4 5 fastcall-iii-callback [ fastcall-iii-indirect ] with-callback
774 3 4.0 5 fastcall-ifi-callback [ fastcall-ifi-indirect ] with-callback
778 3 4.0 5 6 fastcall-ifii-callback [ fastcall-ifii-indirect ] with-callback
781 { S{ test-struct-11 f 7 -1 } } [
782 3 4 fastcall-struct-return-ii-callback [
783 fastcall-struct-return-ii-indirect
787 { S{ test-struct-11 f 7 -3 } } [
788 3 4 7 fastcall-struct-return-iii-callback [
789 fastcall-struct-return-iii-indirect
793 : x64-regression-1 ( -- c )
794 int { int int int int int } cdecl [ + + + + ] alien-callback ;
796 : x64-regression-2 ( x x x x x c -- y )
797 int { int int int int int } cdecl alien-indirect ; inline
800 100 500 50 10 1 x64-regression-1 [ x64-regression-2 ] with-callback
804 : blah ( -- x ) { RECT } [
805 1.5 >>x 2.0 >>y [ x>> ] [ y>> ] bi * >fixnum
806 ] with-scoped-allocation ;
808 { 3 } [ blah ] unit-test
810 : out-param-test-1 ( -- b )
811 { int } [ [ 12 ] dip 0 int set-alien-value ] with-out-parameters ;
813 { 12 } [ out-param-test-1 ] unit-test
815 : out-param-test-2 ( -- b )
816 { { int initial: 12 } } [ drop ] with-out-parameters ;
818 { 12 } [ out-param-test-2 ] unit-test
820 : out-param-test-3 ( -- x y )
821 { { RECT initial: S{ RECT { x 3 } { y 4 } } } } [ drop ]
825 { 3.0 4.0 } [ out-param-test-3 ] unit-test
827 : out-param-callback ( -- a )
828 void { int pointer: int } cdecl
829 [ [ 2 * ] dip 0 int set-alien-value ] alien-callback ;
831 : out-param-indirect ( a a -- b )
833 swap void { int pointer: int } cdecl
835 ] with-out-parameters ;
838 6 out-param-callback [ out-param-indirect ] with-callback
841 ! Alias analysis regression
842 : aa-callback-1 ( -- c )
843 double { } cdecl [ 5.0 ] alien-callback ;
845 : aa-indirect-1 ( c -- x )
846 double { } cdecl alien-indirect ; inline
848 TUPLE: some-tuple x ;
850 { T{ some-tuple f 5.0 } } [
860 : anton's-regression ( -- )
863 { } [ anton's-regression ] unit-test
871 FUNCTION: bool-and-ptr ffi_test_61 ( )
873 ! { S{ bool-and-ptr { b t } { ptr f } } } [ ffi_test_61 ] unit-test
874 { t } [ ffi_test_61 bool-and-ptr? ] unit-test
875 { { t f } } [ ffi_test_61 [ b>> ] [ ptr>> ] bi 2array ] unit-test
883 FUNCTION: uint-pair ffi_test_62 ( )
886 S{ uint-pair { a 0xabcdefab } { b 0x12345678 } }
887 } [ ffi_test_62 ] unit-test
889 STRUCT: ulonglong-pair
893 FUNCTION: ulonglong-pair ffi_test_63 ( )
896 S{ ulonglong-pair { a 0xabcdefabcdefabcd } { b 0x1234567891234567 } }
897 } [ ffi_test_63 ] unit-test
899 FUNCTION: void* bug1021_test_1 ( void* s, int x )
901 ! Sanity test the formula: x sq s +
903 10 [ [ 100 random ] twice 2array ] replicate
904 [ [ first2 [ <alien> ] dip bug1021_test_1 alien-address ] map ]
905 [ [ first2 sq + ] map ] bi =
908 : each-to100 ( ... quot: ( ... i -- ... ) i -- ... )
910 2dup swap (call) 1 + each-to100
911 ] [ 2drop ] if ; inline recursive
913 : run-test ( alien -- seq )
920 ] curry curry 0 each-to100 ;
925 ! If #1021 ever comes back it will blow up here because
926 ! alien-address wants an alien not a fixnum.
927 [ alien-address ] map drop
931 ! Varargs with non-float parameters works.
932 FUNCTION-ALIAS: do-sum-ints2 int ffi_test_64 ( int n, int a, int b )
933 FUNCTION-ALIAS: do-sum-ints3 int ffi_test_64 ( int n, int a, int b, int c )
937 3 10 20 30 do-sum-ints3
940 ! Varargs with non-floats doesn't work on windows
941 FUNCTION-ALIAS: do-sum-doubles2 double ffi_test_65 ( int n, double a, double b )
942 FUNCTION-ALIAS: do-sum-doubles3 double ffi_test_65 ( int n, double a, double b, double c )
946 2 7 20 do-sum-doubles2
947 3 5 10 7 do-sum-doubles3
951 FUNCTION: int bug1021_test_2 ( int a, char* b, void* c )
952 FUNCTION: void* bug1021_test_3 ( c-string a )
955 33 1byte-array "bar" bug1021_test_3 bug1021_test_2 ;
958 10000 [ 0 doit 33 assert= ] times
961 ! Tests for System V AMD64 ABI
962 STRUCT: test_struct_66 { mem1 ulong } { mem2 ulong } ;
963 STRUCT: test_struct_68 { mem1 ulong } { mem2 ulong } { mem3 ulong } ;
964 STRUCT: test_struct_69 { mem1 float } { mem2 ulong } { mem3 ulong } ;
965 FUNCTION: ulong ffi_test_66 ( ulong a, ulong b, ulong c, test_struct_66 d, test_struct_66 e )
966 FUNCTION: ulong ffi_test_67 ( ulong a, ulong b, ulong c, test_struct_66 d, test_struct_66 e ulong _f )
967 FUNCTION: ulong ffi_test_68 ( ulong a, ulong b, ulong c, test_struct_66 d, test_struct_68 e test_struct_66 _f )
968 FUNCTION: ulong ffi_test_69 ( ulong a, ulong b, ulong c, test_struct_66 d, test_struct_69 e test_struct_66 _f )
969 FUNCTION: ulong ffi_test_70 ( test_struct_68 a test_struct_68 b, test_struct_66 c )
971 { 28 } [ 1 2 3 S{ test_struct_66 f 4 5 } S{ test_struct_66 f 6 7 } ffi_test_66 ] unit-test
973 : callback-14 ( -- callback )
974 ulong { ulong ulong ulong test_struct_66 test_struct_66 } cdecl
977 d [ mem1>> + ] [ mem2>> + ] bi
978 e [ mem1>> + ] [ mem2>> + ] bi
981 : callback-14-test ( a b c d e callback -- result )
982 ulong { ulong ulong ulong test_struct_66 test_struct_66 } cdecl alien-indirect ;
985 1 2 3 S{ test_struct_66 f 4 5 } S{ test_struct_66 f 6 7 } callback-14 [
990 { 44 } [ 1 2 3 S{ test_struct_66 f 4 5 } S{ test_struct_66 f 6 7 } 8 ffi_test_67 ] unit-test
992 : callback-15 ( -- callback )
993 ulong { ulong ulong ulong test_struct_66 test_struct_66 ulong } cdecl
996 d [ mem1>> + ] [ mem2>> + ] bi
997 e [ mem1>> + ] [ mem2>> + ] bi
1001 : callback-15-test ( a b c d e _f callback -- result )
1002 ulong { ulong ulong ulong test_struct_66 test_struct_66 ulong } cdecl alien-indirect ;
1005 1 2 3 S{ test_struct_66 f 4 5 } S{ test_struct_66 f 6 7 } 8 callback-15 [
1011 1 2 3 S{ test_struct_66 f 4 5 } S{ test_struct_68 f 6 7 8 } S{ test_struct_66 f 9 10 } ffi_test_68
1014 : callback-16 ( -- callback )
1015 ulong { ulong ulong ulong test_struct_66 test_struct_68 test_struct_66 } cdecl
1018 d [ mem1>> + ] [ mem2>> + ] bi
1019 e [ mem1>> + ] [ mem2>> + ] [ mem3>> + ] tri
1020 _f [ mem1>> + ] [ mem2>> + ] bi
1023 : callback-16-test ( a b c d e _f callback -- result )
1024 ulong { ulong ulong ulong test_struct_66 test_struct_68 test_struct_66 } cdecl alien-indirect ;
1027 1 2 3 S{ test_struct_66 f 4 5 } S{ test_struct_68 f 6 7 8 } S{ test_struct_66 f 9 10 } callback-16 [
1033 1 2 3 S{ test_struct_66 f 4 5 } S{ test_struct_69 f 6.0 7 8 } S{ test_struct_66 f 9 10 } ffi_test_69
1036 : callback-17 ( -- callback )
1037 ulong { ulong ulong ulong test_struct_66 test_struct_69 test_struct_66 } cdecl
1040 d [ mem1>> + ] [ mem2>> + ] bi
1041 e [ mem1>> >integer + ] [ mem2>> + ] [ mem3>> + ] tri
1042 _f [ mem1>> + ] [ mem2>> + ] bi
1045 : callback-17-test ( a b c d e _f callback -- result )
1046 ulong { ulong ulong ulong test_struct_66 test_struct_69 test_struct_66 } cdecl alien-indirect ;
1049 1 2 3 S{ test_struct_66 f 4 5 } S{ test_struct_69 f 6.0 7 8 } S{ test_struct_66 f 9 10 } callback-17 [
1055 S{ test_struct_68 f 1 2 3 } S{ test_struct_68 f 4 5 6 } S{ test_struct_66 f 7 8 } ffi_test_70
1058 : callback-18 ( -- callback )
1059 ulong { test_struct_68 test_struct_68 test_struct_66 } cdecl
1061 a [ mem1>> ] [ mem2>> + ] [ mem3>> + ] tri
1062 b [ mem1>> + ] [ mem2>> + ] [ mem3>> + ] tri
1063 c [ mem1>> + ] [ mem2>> + ] bi
1066 : callback-18-test ( a b c callback -- result )
1067 ulong { test_struct_68 test_struct_68 test_struct_66 } cdecl alien-indirect ;
1070 S{ test_struct_68 f 1 2 3 } S{ test_struct_68 f 4 5 6 } S{ test_struct_66 f 7 8 } callback-18 [