1 USING: accessors alien alien.c-types alien.libraries
2 alien.syntax arrays classes.struct combinators
3 compiler continuations destructors effects fry generalizations io
4 io.backend io.pathnames io.streams.string kernel
5 math memory namespaces namespaces.private parser
6 quotations sequences specialized-arrays stack-checker
7 stack-checker.errors system threads tools.test words
8 alien.complex concurrency.promises alien.data
9 byte-arrays classes compiler.test libc layouts
11 FROM: alien.c-types => float short ;
12 SPECIALIZED-ARRAY: float
13 SPECIALIZED-ARRAY: char
14 IN: compiler.tests.alien
16 : unit-test-with-destructors ( exp quot -- )
17 '[ _ with-destructors ] unit-test ; inline
19 ! Make sure that invalid inputs don't pass the stack checker
20 [ [ void { } "cdecl" alien-indirect ] infer ] must-fail
21 [ [ "void" { } cdecl alien-indirect ] infer ] must-fail
22 [ [ void* 3 cdecl alien-indirect ] infer ] must-fail
23 [ [ void* { "int" } cdecl alien-indirect ] infer ] must-fail
24 [ [ void* { int } cdecl { } alien-callback ] infer ] must-fail
27 : libfactor-ffi-tests-path ( -- string )
28 "resource:" absolute-path
30 { [ os windows? ] [ "libfactor-ffi-test.dll" ] }
31 { [ os macosx? ] [ "libfactor-ffi-test.dylib" ] }
32 { [ os unix? ] [ "libfactor-ffi-test.so" ] }
35 : mingw? ( -- ? ) os windows? vm-compiler "GCC" head? and ;
37 "f-cdecl" libfactor-ffi-tests-path mingw? mingw cdecl ? add-library
39 "f-stdcall" libfactor-ffi-tests-path stdcall add-library
41 "f-fastcall" libfactor-ffi-tests-path fastcall add-library
46 FUNCTION: void ffi_test_0 ;
47 [ ] [ ffi_test_0 ] unit-test
49 FUNCTION: int ffi_test_1 ;
50 [ 3 ] [ ffi_test_1 ] unit-test
52 [ ] [ \ ffi_test_1 def>> [ drop ] append compile-call ] unit-test
54 FUNCTION: int ffi_test_2 int x int y ;
55 [ 5 ] [ 2 3 ffi_test_2 ] unit-test
56 [ "hi" 3 ffi_test_2 ] must-fail
58 FUNCTION: int ffi_test_3 int x int y int z int t ;
59 [ 25 ] [ 2 3 4 5 ffi_test_3 ] unit-test
61 FUNCTION: float ffi_test_4 ;
62 [ 1.5 ] [ ffi_test_4 ] unit-test
64 FUNCTION: double ffi_test_5 ;
65 [ 1.5 ] [ ffi_test_5 ] unit-test
67 FUNCTION: int ffi_test_9 int a int b int c int d int e int f int g ;
68 [ 28 ] [ 1 2 3 4 5 6 7 ffi_test_9 ] unit-test
69 [ "a" 2 3 4 5 6 7 ffi_test_9 ] must-fail
70 [ 1 2 3 4 5 6 "a" ffi_test_9 ] must-fail
72 STRUCT: FOO { x int } { y int } ;
74 : make-FOO ( x y -- FOO )
75 FOO <struct> swap >>y swap >>x ;
77 FUNCTION: int ffi_test_11 int a FOO b int c ;
79 [ 14 ] [ 1 2 3 make-FOO 4 ffi_test_11 ] unit-test
81 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 ;
83 [ 66 ] [ 1 2 3 4 5 6 7 8 9 10 11 ffi_test_13 ] unit-test
85 FUNCTION: FOO ffi_test_14 int x int y ;
87 [ 11 6 ] [ 11 6 ffi_test_14 [ x>> ] [ y>> ] bi ] unit-test
89 FUNCTION: c-string ffi_test_15 c-string x c-string y ;
91 [ "foo" ] [ "xy" "zt" ffi_test_15 ] unit-test
92 [ "bar" ] [ "xy" "xy" ffi_test_15 ] unit-test
93 [ 1 2 ffi_test_15 ] must-fail
95 STRUCT: BAR { x long } { y long } { z long } ;
97 FUNCTION: BAR ffi_test_16 long x long y long z ;
100 11 6 -7 ffi_test_16 [ x>> ] [ y>> ] [ z>> ] tri
103 STRUCT: TINY { x int } ;
105 FUNCTION: TINY ffi_test_17 int x ;
107 [ 11 ] [ 11 ffi_test_17 x>> ] unit-test
109 [ [ alien-indirect ] infer ] [ inference-error? ] must-fail-with
111 : indirect-test-1 ( ptr -- result )
112 int { } cdecl alien-indirect ;
114 { 1 1 } [ indirect-test-1 ] must-infer-as
116 [ 3 ] [ &: ffi_test_1 indirect-test-1 ] unit-test
118 : indirect-test-1' ( ptr -- )
119 int { } cdecl alien-indirect drop ;
121 { 1 0 } [ indirect-test-1' ] must-infer-as
123 [ ] [ &: ffi_test_1 indirect-test-1' ] unit-test
125 [ -1 indirect-test-1 ] must-fail
127 : indirect-test-2 ( x y ptr -- result )
128 int { int int } cdecl alien-indirect gc ;
130 { 3 1 } [ indirect-test-2 ] must-infer-as
133 [ 2 3 &: ffi_test_2 indirect-test-2 ]
136 : indirect-test-3 ( a b c d ptr -- result )
137 int { int int int int } stdcall alien-indirect
140 [ f ] [ "f-stdcall" load-library f = ] unit-test
141 [ stdcall ] [ "f-stdcall" lookup-library abi>> ] unit-test
143 : ffi_test_18 ( w x y z -- int )
144 int "f-stdcall" "ffi_test_18" { int int int int }
147 [ 25 ] [ 2 3 4 5 ffi_test_18 ] unit-test
149 : ffi_test_19 ( x y z -- BAR )
150 BAR "f-stdcall" "ffi_test_19" { long long long }
154 11 6 -7 ffi_test_19 [ x>> ] [ y>> ] [ z>> ] tri
157 : multi_ffi_test_18 ( w x y z w' x' y' z' -- int int )
158 [ int "f-stdcall" "ffi_test_18" { int int int int } alien-invoke ]
160 int "f-stdcall" "ffi_test_18" { int int int int } alien-invoke
163 [ 25 85 ] [ 2 3 4 5 6 7 8 9 multi_ffi_test_18 ] unit-test
165 FUNCTION: double ffi_test_6 float x float y ;
166 [ 6.0 ] [ 3.0 2.0 ffi_test_6 ] unit-test
167 [ "a" "b" ffi_test_6 ] must-fail
169 FUNCTION: double ffi_test_7 double x double y ;
170 [ 6.0 ] [ 3.0 2.0 ffi_test_7 ] unit-test
172 FUNCTION: double ffi_test_8 double x float y double z float t int w ;
173 [ 19.0 ] [ 3.0 2.0 1.0 6.0 7 ffi_test_8 ] unit-test
175 FUNCTION: int ffi_test_10 int a int b double c int d float e int f int g int h ;
176 [ -34 ] [ 1 2 3.0 4 5.0 6 7 8 ffi_test_10 ] unit-test
178 FUNCTION: void ffi_test_20 double x1, double x2, double x3,
179 double y1, double y2, double y3,
180 double z1, double z2, double z3 ;
182 [ ] [ 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 ffi_test_20 ] unit-test
184 ! Make sure XT doesn't get clobbered in stack frame
186 : 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 )
188 "f-cdecl" "ffi_test_31"
189 { 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 }
192 [ 861 3 ] [ 42 [ ] each-integer ffi_test_31 ] unit-test
194 : 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 )
196 "f-cdecl" "ffi_test_31_point_5"
197 { 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 }
200 [ 861.0 ] [ 42 [ >float ] each-integer ffi_test_31_point_5 ] unit-test
202 FUNCTION: longlong ffi_test_21 long x long y ;
204 [ 121932631112635269 ]
205 [ 123456789 987654321 ffi_test_21 ] unit-test
207 FUNCTION: long ffi_test_22 long x longlong y longlong z ;
210 [ 1111 121932631112635269 123456789 ffi_test_22 ] unit-test
212 [ 1111 f 123456789 ffi_test_22 ] must-fail
215 { x float } { y float }
216 { w float } { h float } ;
218 : <RECT> ( x y w h -- rect )
225 FUNCTION: int ffi_test_12 int a int b RECT c int d int e int f ;
227 [ 45 ] [ 1 2 3.0 4.0 5.0 6.0 <RECT> 7 8 9 ffi_test_12 ] unit-test
229 [ 1 2 { 1 2 3 } 7 8 9 ffi_test_12 ] must-fail
231 FUNCTION: float ffi_test_23 ( float[3] x, float[3] y ) ;
234 { 1.0 2.0 3.0 } float >c-array
235 { 4.0 5.0 6.0 } float >c-array
239 ! Test odd-size structs
240 STRUCT: test-struct-1 { x char[1] } ;
242 FUNCTION: test-struct-1 ffi_test_24 ;
244 [ S{ test-struct-1 { x char-array{ 1 } } } ] [ ffi_test_24 ] unit-test
246 STRUCT: test-struct-2 { x char[2] } ;
248 FUNCTION: test-struct-2 ffi_test_25 ;
250 [ S{ test-struct-2 { x char-array{ 1 2 } } } ] [ ffi_test_25 ] unit-test
252 STRUCT: test-struct-3 { x char[3] } ;
254 FUNCTION: test-struct-3 ffi_test_26 ;
256 [ S{ test-struct-3 { x char-array{ 1 2 3 } } } ] [ ffi_test_26 ] unit-test
258 STRUCT: test-struct-4 { x char[4] } ;
260 FUNCTION: test-struct-4 ffi_test_27 ;
262 [ S{ test-struct-4 { x char-array{ 1 2 3 4 } } } ] [ ffi_test_27 ] unit-test
264 STRUCT: test-struct-5 { x char[5] } ;
266 FUNCTION: test-struct-5 ffi_test_28 ;
268 [ S{ test-struct-5 { x char-array{ 1 2 3 4 5 } } } ] [ ffi_test_28 ] unit-test
270 STRUCT: test-struct-6 { x char[6] } ;
272 FUNCTION: test-struct-6 ffi_test_29 ;
274 [ S{ test-struct-6 { x char-array{ 1 2 3 4 5 6 } } } ] [ ffi_test_29 ] unit-test
276 STRUCT: test-struct-7 { x char[7] } ;
278 FUNCTION: test-struct-7 ffi_test_30 ;
280 [ S{ test-struct-7 { x char-array{ 1 2 3 4 5 6 7 } } } ] [ ffi_test_30 ] unit-test
282 STRUCT: test-struct-8 { x double } { y double } ;
284 FUNCTION: double ffi_test_32 test-struct-8 x int y ;
287 test-struct-8 <struct>
293 STRUCT: test-struct-9 { x float } { y float } ;
295 FUNCTION: double ffi_test_33 test-struct-9 x int y ;
298 test-struct-9 <struct>
304 STRUCT: test-struct-10 { x float } { y int } ;
306 FUNCTION: double ffi_test_34 test-struct-10 x int y ;
309 test-struct-10 <struct>
315 STRUCT: test-struct-11 { x int } { y int } ;
317 FUNCTION: double ffi_test_35 test-struct-11 x int y ;
320 test-struct-11 <struct>
326 STRUCT: test-struct-12 { a int } { x double } ;
328 : make-struct-12 ( x -- alien )
329 test-struct-12 <struct>
332 FUNCTION: double ffi_test_36 ( test-struct-12 x ) ;
334 [ 1.23456 ] [ 1.23456 make-struct-12 ffi_test_36 ] unit-test
336 FUNCTION: ulonglong ffi_test_38 ( ulonglong x, ulonglong y ) ;
338 [ t ] [ 31 2^ 32 2^ ffi_test_38 63 2^ = ] unit-test
341 : callback-throws ( -- x )
342 int { } cdecl [ "Hi" throw ] alien-callback ;
344 { t } [ callback-throws alien? ] unit-test-with-destructors
346 : callback-1 ( -- callback ) void { } cdecl [ ] alien-callback ;
348 [ 0 1 ] [ [ callback-1 ] infer [ in>> length ] [ out>> length ] bi ] unit-test
350 { t } [ callback-1 alien? ] unit-test-with-destructors
352 : callback_test_1 ( ptr -- ) void { } cdecl alien-indirect ;
354 { } [ callback-1 callback_test_1 ] unit-test-with-destructors
356 : callback-2 ( -- callback ) void { } cdecl [ [ 5 throw ] ignore-errors ] alien-callback ;
358 { } [ callback-2 callback_test_1 ] unit-test-with-destructors
360 : callback-3 ( -- callback ) void { } cdecl [ 5 "x" set ] alien-callback ;
365 3 "x" set callback-3 callback_test_1
367 "x" get "x" get-global
369 ] unit-test-with-destructors
371 : callback-5 ( -- callback )
372 void { } cdecl [ gc ] alien-callback ;
375 "testing" callback-5 callback_test_1
376 ] unit-test-with-destructors
378 : callback-5b ( -- callback )
379 void { } cdecl [ compact-gc ] alien-callback ;
382 "testing" callback-5b callback_test_1
383 ] unit-test-with-destructors
385 : callback-6 ( -- callback )
386 void { } cdecl [ [ continue ] callcc0 ] alien-callback ;
389 callback-6 callback_test_1 1 2 3
390 ] unit-test-with-destructors
392 : callback-7 ( -- callback )
393 void { } cdecl [ 1000000 sleep ] alien-callback ;
395 [ 1 2 3 ] [ callback-7 callback_test_1 1 2 3 ] unit-test-with-destructors
397 [ f ] [ namespace global eq? ] unit-test
399 : callback-8 ( -- callback )
400 void { } cdecl [ [ ] in-thread yield ] alien-callback ;
402 [ ] [ callback-8 callback_test_1 ] unit-test-with-destructors
404 : callback-9 ( -- callback )
405 int { int int int } cdecl [
409 FUNCTION: void ffi_test_36_point_5 ( ) ;
411 [ ] [ ffi_test_36_point_5 ] unit-test
413 FUNCTION: int ffi_test_37 ( void* func ) ;
415 [ 1 ] [ callback-9 ffi_test_37 ] unit-test-with-destructors
417 [ 7 ] [ callback-9 ffi_test_37 ] unit-test-with-destructors
419 STRUCT: test_struct_13
427 : make-test-struct-13 ( -- alien )
428 test_struct_13 <struct>
436 FUNCTION: int ffi_test_39 ( long a, long b, test_struct_13 s ) ;
438 [ 21 ] [ 12347 12347 make-test-struct-13 ffi_test_39 ] unit-test
440 ! Joe Groff found this problem
447 : <double-rect> ( a b c d -- foo )
454 : >double-rect< ( foo -- a b c d )
462 : double-rect-callback ( -- alien )
463 void { void* void* double-rect } cdecl
464 [ "example" set-global 2drop ] alien-callback ;
466 : double-rect-test ( arg callback -- arg' )
468 void { void* void* double-rect } cdecl alien-indirect
469 "example" get-global ;
471 { byte-array 1.0 2.0 3.0 4.0 } [
472 1.0 2.0 3.0 4.0 <double-rect>
473 double-rect-callback double-rect-test
474 [ >c-ptr class-of ] [ >double-rect< ] bi
475 ] unit-test-with-destructors
477 STRUCT: test_struct_14
481 FUNCTION: test_struct_14 ffi_test_40 ( double x1, double x2 ) ;
484 1.0 2.0 ffi_test_40 [ x1>> ] [ x2>> ] bi
487 : callback-10 ( -- callback )
488 test_struct_14 { double double } cdecl
490 test_struct_14 <struct>
495 : callback-10-test ( x1 x2 callback -- result )
496 test_struct_14 { double double } cdecl alien-indirect ;
499 1.0 2.0 callback-10 callback-10-test
501 ] unit-test-with-destructors
503 FUNCTION: test-struct-12 ffi_test_41 ( int a, double x ) ;
510 : callback-11 ( -- callback )
511 test-struct-12 { int double } cdecl
513 test-struct-12 <struct>
518 : callback-11-test ( x1 x2 callback -- result )
519 test-struct-12 { int double } cdecl alien-indirect ;
522 1 2.0 callback-11 callback-11-test
524 ] unit-test-with-destructors
526 STRUCT: test_struct_15
530 FUNCTION: test_struct_15 ffi_test_42 ( float x, float y ) ;
532 [ 1.0 2.0 ] [ 1.0 2.0 ffi_test_42 [ x>> ] [ y>> ] bi ] unit-test
534 : callback-12 ( -- callback )
535 test_struct_15 { float float } cdecl
537 test_struct_15 <struct>
542 : callback-12-test ( x1 x2 callback -- result )
543 test_struct_15 { float float } cdecl alien-indirect ;
546 1.0 2.0 callback-12 callback-12-test [ x>> ] [ y>> ] bi
547 ] unit-test-with-destructors
549 STRUCT: test_struct_16
553 FUNCTION: test_struct_16 ffi_test_43 ( float x, int a ) ;
555 [ 1.0 2 ] [ 1.0 2 ffi_test_43 [ x>> ] [ a>> ] bi ] unit-test
557 : callback-13 ( -- callback )
558 test_struct_16 { float int } cdecl
560 test_struct_16 <struct>
565 : callback-13-test ( x1 x2 callback -- result )
566 test_struct_16 { float int } cdecl alien-indirect ;
569 1.0 2 callback-13 callback-13-test
571 ] unit-test-with-destructors
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 2drop ] unit-test
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-1 thread-callback-invoker "p" get fulfill
632 thread-callback-2 thread-callback-invoker
633 ] unit-test-with-destructors
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" load-library 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 }
647 : ffi_test_50 ( x y -- int )
648 int "f-fastcall" "ffi_test_50" { int int }
650 : ffi_test_51 ( x y z -- int )
651 int "f-fastcall" "ffi_test_51" { int int int }
653 : multi_ffi_test_51 ( x y z x' y' z' -- int int )
654 [ int "f-fastcall" "ffi_test_51" { int int int } alien-invoke ]
656 int "f-fastcall" "ffi_test_51" { int int int } 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 }
666 : ffi_test_53 ( x y z w -- int )
667 int "f-fastcall" "ffi_test_53" { int float int int }
669 : ffi_test_57 ( x y -- test-struct-11 )
670 test-struct-11 "f-fastcall" "ffi_test_57" { int int }
672 : ffi_test_58 ( x y z -- test-struct-11 )
673 test-struct-11 "f-fastcall" "ffi_test_58" { int int int }
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 ;
717 : win32? ( -- ? ) os windows? cpu x86.32? and ;
721 win32? [ &: @ffi_test_50@8 ] [ &: ffi_test_50 ] if
727 win32? [ &: @ffi_test_51@12 ] [ &: ffi_test_51 ] if
728 fastcall-iii-indirect
734 win32? [ &: @ffi_test_52@12 ] [ &: ffi_test_52 ] if
735 fastcall-ifi-indirect
740 win32? [ &: @ffi_test_53@16 ] [ &: ffi_test_53 ] if
741 fastcall-ifii-indirect
745 [ S{ test-struct-11 f 7 -1 } ]
748 win32? [ &: @ffi_test_57@8 ] [ &: ffi_test_57 ] if
749 fastcall-struct-return-ii-indirect
752 [ S{ test-struct-11 f 7 -3 } ]
755 win32? [ &: @ffi_test_58@12 ] [ &: ffi_test_58 ] if
756 fastcall-struct-return-iii-indirect
759 : fastcall-ii-callback ( -- ptr )
760 int { int int } fastcall [ + 1 + ] alien-callback ;
762 : fastcall-iii-callback ( -- ptr )
763 int { int int int } fastcall [ + + 1 + ] alien-callback ;
765 : fastcall-ifi-callback ( -- ptr )
766 int { int float int } fastcall
767 [ [ >integer ] dip + + 1 + ] alien-callback ;
769 : fastcall-ifii-callback ( -- ptr )
770 int { int float int int } fastcall
771 [ [ >integer ] 2dip + + + 1 + ] alien-callback ;
773 : fastcall-struct-return-ii-callback ( -- ptr )
774 test-struct-11 { int int } fastcall
775 [ [ + ] [ - ] 2bi test-struct-11 <struct-boa> ] alien-callback ;
777 : fastcall-struct-return-iii-callback ( -- ptr )
778 test-struct-11 { int int int } fastcall
779 [ [ drop + ] [ - nip ] 3bi test-struct-11 <struct-boa> ] alien-callback ;
782 3 4 fastcall-ii-callback fastcall-ii-indirect
783 ] unit-test-with-destructors
786 3 4 5 fastcall-iii-callback fastcall-iii-indirect
787 ] unit-test-with-destructors
790 3 4.0 5 fastcall-ifi-callback fastcall-ifi-indirect
791 ] unit-test-with-destructors
794 3 4.0 5 6 fastcall-ifii-callback fastcall-ifii-indirect
795 ] unit-test-with-destructors
797 [ S{ test-struct-11 f 7 -1 } ] [
798 3 4 fastcall-struct-return-ii-callback fastcall-struct-return-ii-indirect
799 ] unit-test-with-destructors
801 [ S{ test-struct-11 f 7 -3 } ] [
802 3 4 7 fastcall-struct-return-iii-callback fastcall-struct-return-iii-indirect
803 ] unit-test-with-destructors
805 : x64-regression-1 ( -- c )
806 int { int int int int int } cdecl [ + + + + ] alien-callback ;
808 : x64-regression-2 ( x x x x x c -- y )
809 int { int int int int int } cdecl alien-indirect ; inline
812 100 500 50 10 1 x64-regression-1 x64-regression-2
813 ] unit-test-with-destructors
816 : blah ( -- x ) { RECT } [ 1.5 >>x 2.0 >>y [ x>> ] [ y>> ] bi * >fixnum ] with-scoped-allocation ;
818 [ 3 ] [ blah ] unit-test
820 : out-param-test-1 ( -- b )
821 { int } [ [ 12 ] dip 0 int set-alien-value ] with-out-parameters ;
823 [ 12 ] [ out-param-test-1 ] unit-test
825 : out-param-test-2 ( -- b )
826 { { int initial: 12 } } [ drop ] with-out-parameters ;
828 [ 12 ] [ out-param-test-2 ] unit-test
830 : out-param-test-3 ( -- x y )
831 { { RECT initial: S{ RECT { x 3 } { y 4 } } } } [ drop ]
835 [ 3.0 4.0 ] [ out-param-test-3 ] unit-test
837 : out-param-callback ( -- a )
838 void { int pointer: int } cdecl
839 [ [ 2 * ] dip 0 int set-alien-value ] alien-callback ;
841 : out-param-indirect ( a a -- b )
843 swap void { int pointer: int } cdecl
845 ] with-out-parameters ;
848 6 out-param-callback out-param-indirect
849 ] unit-test-with-destructors
851 ! Alias analysis regression
852 : aa-callback-1 ( -- c )
853 double { } cdecl [ 5.0 ] alien-callback ;
855 : aa-indirect-1 ( c -- x )
856 double { } cdecl alien-indirect ; inline
858 TUPLE: some-tuple x ;
860 [ T{ some-tuple f 5.0 } ] [
866 ] unit-test-with-destructors
869 : anton's-regression ( -- )
872 [ ] [ anton's-regression ] unit-test