]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/tests/alien.factor
Delete empty unit tests files, remove 1- and 1+, reorder IN: lines in a lot of places...
[factor.git] / basis / compiler / tests / alien.factor
1 USING: alien alien.c-types alien.syntax compiler kernel namespaces
2 sequences stack-checker stack-checker.errors words arrays parser
3 quotations continuations effects namespaces.private io
4 io.streams.string memory system threads tools.test math accessors
5 combinators specialized-arrays.float alien.libraries io.pathnames
6 io.backend ;
7 IN: compiler.tests.alien
8
9 <<
10 : libfactor-ffi-tests-path ( -- string )
11     "resource:" (normalize-path)
12     {
13         { [ os winnt? ]  [ "libfactor-ffi-test.dll" ] }
14         { [ os macosx? ] [ "libfactor-ffi-test.dylib" ] }
15         { [ os unix?  ]  [ "libfactor-ffi-test.so" ] }
16     } cond append-path ;
17
18 "f-cdecl" libfactor-ffi-tests-path "cdecl" add-library
19
20 "f-stdcall" libfactor-ffi-tests-path "stdcall" add-library
21 >>
22
23 LIBRARY: f-cdecl
24
25 FUNCTION: void ffi_test_0 ;
26 [ ] [ ffi_test_0 ] unit-test
27
28 FUNCTION: int ffi_test_1 ;
29 [ 3 ] [ ffi_test_1 ] unit-test
30
31 FUNCTION: int ffi_test_2 int x int y ;
32 [ 5 ] [ 2 3 ffi_test_2 ] unit-test
33 [ "hi" 3 ffi_test_2 ] must-fail
34
35 FUNCTION: int ffi_test_3 int x int y int z int t ;
36 [ 25 ] [ 2 3 4 5 ffi_test_3 ] unit-test
37
38 FUNCTION: float ffi_test_4 ;
39 [ 1.5 ] [ ffi_test_4 ] unit-test
40
41 FUNCTION: double ffi_test_5 ;
42 [ 1.5 ] [ ffi_test_5 ] unit-test
43
44 FUNCTION: int ffi_test_9 int a int b int c int d int e int f int g ;
45 [ 28 ] [ 1 2 3 4 5 6 7 ffi_test_9 ] unit-test
46 [ "a" 2 3 4 5 6 7 ffi_test_9 ] must-fail
47 [ 1 2 3 4 5 6 "a" ffi_test_9 ] must-fail
48
49 C-STRUCT: foo
50     { "int" "x" }
51     { "int" "y" }
52 ;
53
54 : make-foo ( x y -- foo )
55     "foo" <c-object> [ set-foo-y ] keep [ set-foo-x ] keep ;
56
57 FUNCTION: int ffi_test_11 int a foo b int c ;
58
59 [ 14 ] [ 1 2 3 make-foo 4 ffi_test_11 ] unit-test
60
61 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 ;
62
63 [ 66 ] [ 1 2 3 4 5 6 7 8 9 10 11 ffi_test_13 ] unit-test
64
65 FUNCTION: foo ffi_test_14 int x int y ;
66
67 [ 11 6 ] [ 11 6 ffi_test_14 dup foo-x swap foo-y ] unit-test
68
69 FUNCTION: char* ffi_test_15 char* x char* y ;
70
71 [ "foo" ] [ "xy" "zt" ffi_test_15 ] unit-test
72 [ "bar" ] [ "xy" "xy" ffi_test_15 ] unit-test
73 [ 1 2 ffi_test_15 ] must-fail
74
75 C-STRUCT: bar
76     { "long" "x" }
77     { "long" "y" }
78     { "long" "z" }
79 ;
80
81 FUNCTION: bar ffi_test_16 long x long y long z ;
82
83 [ 11 6 -7 ] [
84     11 6 -7 ffi_test_16 dup bar-x over bar-y rot bar-z
85 ] unit-test
86
87 C-STRUCT: tiny
88     { "int" "x" }
89 ;
90
91 FUNCTION: tiny ffi_test_17 int x ;
92
93 [ 11 ] [ 11 ffi_test_17 tiny-x ] unit-test
94
95 [ [ alien-indirect ] infer ] [ inference-error? ] must-fail-with
96
97 : indirect-test-1 ( ptr -- result )
98     "int" { } "cdecl" alien-indirect ;
99
100 { 1 1 } [ indirect-test-1 ] must-infer-as
101
102 [ 3 ] [ &: ffi_test_1 indirect-test-1 ] unit-test
103
104 : indirect-test-1' ( ptr -- )
105     "int" { } "cdecl" alien-indirect drop ;
106
107 { 1 0 } [ indirect-test-1' ] must-infer-as
108
109 [ ] [ &: ffi_test_1 indirect-test-1' ] unit-test
110
111 [ -1 indirect-test-1 ] must-fail
112
113 : indirect-test-2 ( x y ptr -- result )
114     "int" { "int" "int" } "cdecl" alien-indirect gc ;
115
116 { 3 1 } [ indirect-test-2 ] must-infer-as
117
118 [ 5 ]
119 [ 2 3 &: ffi_test_2 indirect-test-2 ]
120 unit-test
121
122 : indirect-test-3 ( a b c d ptr -- result )
123     "int" { "int" "int" "int" "int" } "stdcall" alien-indirect
124     gc ;
125
126 [ f ] [ "f-stdcall" load-library f = ] unit-test
127 [ "stdcall" ] [ "f-stdcall" library abi>> ] unit-test
128
129 : ffi_test_18 ( w x y z -- int )
130     "int" "f-stdcall" "ffi_test_18" { "int" "int" "int" "int" }
131     alien-invoke gc ;
132
133 [ 25 ] [ 2 3 4 5 ffi_test_18 ] unit-test
134
135 : ffi_test_19 ( x y z -- bar )
136     "bar" "f-stdcall" "ffi_test_19" { "long" "long" "long" }
137     alien-invoke gc ;
138
139 [ 11 6 -7 ] [
140     11 6 -7 ffi_test_19 dup bar-x over bar-y rot bar-z
141 ] unit-test
142
143 FUNCTION: double ffi_test_6 float x float y ;
144 [ 6.0 ] [ 3.0 2.0 ffi_test_6 ] unit-test
145 [ "a" "b" ffi_test_6 ] must-fail
146
147 FUNCTION: double ffi_test_7 double x double y ;
148 [ 6.0 ] [ 3.0 2.0 ffi_test_7 ] unit-test
149
150 FUNCTION: double ffi_test_8 double x float y double z float t int w ;
151 [ 19.0 ] [ 3.0 2.0 1.0 6.0 7 ffi_test_8 ] unit-test
152
153 FUNCTION: int ffi_test_10 int a int b double c int d float e int f int g int h ;
154 [ -34 ] [ 1 2 3.0 4 5.0 6 7 8 ffi_test_10 ] unit-test
155
156 FUNCTION: void ffi_test_20 double x1, double x2, double x3,
157     double y1, double y2, double y3,
158     double z1, double z2, double z3 ;
159
160 [ ] [ 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 ffi_test_20 ] unit-test
161
162 ! Make sure XT doesn't get clobbered in stack frame
163
164 : 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 )
165     "int"
166     "f-cdecl" "ffi_test_31"
167     { "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" }
168     alien-invoke gc 3 ;
169
170 [ 861 3 ] [ 42 [ ] each ffi_test_31 ] unit-test
171
172 : 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 )
173     "float"
174     "f-cdecl" "ffi_test_31_point_5"
175     { "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" }
176     alien-invoke ;
177
178 [ 861.0 ] [ 42 [ >float ] each ffi_test_31_point_5 ] unit-test
179
180 FUNCTION: longlong ffi_test_21 long x long y ;
181
182 [ 121932631112635269 ]
183 [ 123456789 987654321 ffi_test_21 ] unit-test
184
185 FUNCTION: long ffi_test_22 long x longlong y longlong z ;
186
187 [ 987655432 ]
188 [ 1111 121932631112635269 123456789 ffi_test_22 ] unit-test
189
190 [ 1111 f 123456789 ffi_test_22 ] must-fail
191
192 C-STRUCT: rect
193     { "float" "x" }
194     { "float" "y" }
195     { "float" "w" }
196     { "float" "h" }
197 ;
198
199 : <rect> ( x y w h -- rect )
200     "rect" <c-object>
201     [ set-rect-h ] keep
202     [ set-rect-w ] keep
203     [ set-rect-y ] keep
204     [ set-rect-x ] keep ;
205
206 FUNCTION: int ffi_test_12 int a int b rect c int d int e int f ;
207
208 [ 45 ] [ 1 2 3.0 4.0 5.0 6.0 <rect> 7 8 9 ffi_test_12 ] unit-test
209
210 [ 1 2 { 1 2 3 } 7 8 9 ffi_test_12 ] must-fail
211
212 FUNCTION: float ffi_test_23 ( float[3] x, float[3] y ) ;
213
214 [ 32.0 ] [
215     { 1.0 2.0 3.0 } >float-array
216     { 4.0 5.0 6.0 } >float-array
217     ffi_test_23
218 ] unit-test
219
220 ! Test odd-size structs
221 C-STRUCT: test-struct-1 { { "char" 1 } "x" } ;
222
223 FUNCTION: test-struct-1 ffi_test_24 ;
224
225 [ B{ 1 } ] [ ffi_test_24 ] unit-test
226
227 C-STRUCT: test-struct-2 { { "char" 2 } "x" } ;
228
229 FUNCTION: test-struct-2 ffi_test_25 ;
230
231 [ B{ 1 2 } ] [ ffi_test_25 ] unit-test
232
233 C-STRUCT: test-struct-3 { { "char" 3 } "x" } ;
234
235 FUNCTION: test-struct-3 ffi_test_26 ;
236
237 [ B{ 1 2 3 } ] [ ffi_test_26 ] unit-test
238
239 C-STRUCT: test-struct-4 { { "char" 4 } "x" } ;
240
241 FUNCTION: test-struct-4 ffi_test_27 ;
242
243 [ B{ 1 2 3 4 } ] [ ffi_test_27 ] unit-test
244
245 C-STRUCT: test-struct-5 { { "char" 5 } "x" } ;
246
247 FUNCTION: test-struct-5 ffi_test_28 ;
248
249 [ B{ 1 2 3 4 5 } ] [ ffi_test_28 ] unit-test
250
251 C-STRUCT: test-struct-6 { { "char" 6 } "x" } ;
252
253 FUNCTION: test-struct-6 ffi_test_29 ;
254
255 [ B{ 1 2 3 4 5 6 } ] [ ffi_test_29 ] unit-test
256
257 C-STRUCT: test-struct-7 { { "char" 7 } "x" } ;
258
259 FUNCTION: test-struct-7 ffi_test_30 ;
260
261 [ B{ 1 2 3 4 5 6 7 } ] [ ffi_test_30 ] unit-test
262
263 C-STRUCT: test-struct-8 { "double" "x" } { "double" "y" } ;
264
265 FUNCTION: double ffi_test_32 test-struct-8 x int y ;
266
267 [ 9.0 ] [
268     "test-struct-8" <c-object>
269     1.0 over set-test-struct-8-x
270     2.0 over set-test-struct-8-y
271     3 ffi_test_32
272 ] unit-test
273
274 C-STRUCT: test-struct-9 { "float" "x" } { "float" "y" } ;
275
276 FUNCTION: double ffi_test_33 test-struct-9 x int y ;
277
278 [ 9.0 ] [
279     "test-struct-9" <c-object>
280     1.0 over set-test-struct-9-x
281     2.0 over set-test-struct-9-y
282     3 ffi_test_33
283 ] unit-test
284
285 C-STRUCT: test-struct-10 { "float" "x" } { "int" "y" } ;
286
287 FUNCTION: double ffi_test_34 test-struct-10 x int y ;
288
289 [ 9.0 ] [
290     "test-struct-10" <c-object>
291     1.0 over set-test-struct-10-x
292     2 over set-test-struct-10-y
293     3 ffi_test_34
294 ] unit-test
295
296 C-STRUCT: test-struct-11 { "int" "x" } { "int" "y" } ;
297
298 FUNCTION: double ffi_test_35 test-struct-11 x int y ;
299
300 [ 9.0 ] [
301     "test-struct-11" <c-object>
302     1 over set-test-struct-11-x
303     2 over set-test-struct-11-y
304     3 ffi_test_35
305 ] unit-test
306
307 C-STRUCT: test-struct-12 { "int" "a" } { "double" "x" } ;
308
309 : make-struct-12 ( x -- alien )
310     "test-struct-12" <c-object>
311     [ set-test-struct-12-x ] keep ;
312
313 FUNCTION: double ffi_test_36 ( test-struct-12 x ) ;
314
315 [ 1.23456 ] [ 1.23456 make-struct-12 ffi_test_36 ] unit-test
316
317 FUNCTION: ulonglong ffi_test_38 ( ulonglong x, ulonglong y ) ;
318
319 [ t ] [ 31 2^ 32 2^ ffi_test_38 63 2^ = ] unit-test
320
321 ! Test callbacks
322
323 : callback-1 ( -- callback ) "void" { } "cdecl" [ ] alien-callback ;
324
325 [ 0 1 ] [ [ callback-1 ] infer [ in>> ] [ out>> ] bi ] unit-test
326
327 [ t ] [ callback-1 alien? ] unit-test
328
329 : callback_test_1 ( ptr -- ) "void" { } "cdecl" alien-indirect ;
330
331 [ ] [ callback-1 callback_test_1 ] unit-test
332
333 : callback-2 ( -- callback ) "void" { } "cdecl" [ [ 5 throw ] ignore-errors ] alien-callback ;
334
335 [ ] [ callback-2 callback_test_1 ] unit-test
336
337 : callback-3 ( -- callback ) "void" { } "cdecl" [ 5 "x" set ] alien-callback ;
338
339 [ t ] [
340     namestack*
341     3 "x" set callback-3 callback_test_1
342     namestack* eq?
343 ] unit-test
344
345 [ 5 ] [
346     [
347         3 "x" set callback-3 callback_test_1 "x" get
348     ] with-scope
349 ] unit-test
350
351 : callback-4 ( -- callback )
352     "void" { } "cdecl" [ "Hello world" write ] alien-callback
353     gc ;
354
355 [ "Hello world" ] [
356     [ callback-4 callback_test_1 ] with-string-writer
357 ] unit-test
358
359 : callback-5 ( -- callback )
360     "void" { } "cdecl" [ gc ] alien-callback ;
361
362 [ "testing" ] [
363     "testing" callback-5 callback_test_1
364 ] unit-test
365
366 : callback-5a ( -- callback )
367     "void" { } "cdecl" [ 8000000 f <array> drop ] alien-callback ;
368
369 ! Hack; if we're on ARM, we probably don't have much RAM, so
370 ! skip this test.
371 ! cpu "arm" = [
372 !     [ "testing" ] [
373 !         "testing" callback-5a callback_test_1
374 !     ] unit-test
375 ! ] unless
376
377 : callback-6 ( -- callback )
378     "void" { } "cdecl" [ [ continue ] callcc0 ] alien-callback ;
379
380 [ 1 2 3 ] [ callback-6 callback_test_1 1 2 3 ] unit-test
381
382 : callback-7 ( -- callback )
383     "void" { } "cdecl" [ 1000000 sleep ] alien-callback ;
384
385 [ 1 2 3 ] [ callback-7 callback_test_1 1 2 3 ] unit-test
386
387 [ f ] [ namespace global eq? ] unit-test
388
389 : callback-8 ( -- callback )
390     "void" { } "cdecl" [
391         [ continue ] callcc0
392     ] alien-callback ;
393
394 [ ] [ callback-8 callback_test_1 ] unit-test
395
396 : callback-9 ( -- callback )
397     "int" { "int" "int" "int" } "cdecl" [
398         + + 1 +
399     ] alien-callback ;
400
401 FUNCTION: void ffi_test_36_point_5 ( ) ;
402
403 [ ] [ ffi_test_36_point_5 ] unit-test
404
405 FUNCTION: int ffi_test_37 ( void* func ) ;
406
407 [ 1 ] [ callback-9 ffi_test_37 ] unit-test
408
409 [ 7 ] [ callback-9 ffi_test_37 ] unit-test
410
411 C-STRUCT: test_struct_13
412 { "float" "x1" }
413 { "float" "x2" }
414 { "float" "x3" }
415 { "float" "x4" }
416 { "float" "x5" }
417 { "float" "x6" } ;
418
419 : make-test-struct-13 ( -- alien )
420     "test_struct_13" <c-object>
421         1.0 over set-test_struct_13-x1
422         2.0 over set-test_struct_13-x2
423         3.0 over set-test_struct_13-x3
424         4.0 over set-test_struct_13-x4
425         5.0 over set-test_struct_13-x5
426         6.0 over set-test_struct_13-x6 ;
427
428 FUNCTION: int ffi_test_39 ( long a, long b, test_struct_13 s ) ;
429
430 [ 21 ] [ 12347 12347 make-test-struct-13 ffi_test_39 ] unit-test
431
432 ! Joe Groff found this problem
433 C-STRUCT: double-rect
434 { "double" "a" }
435 { "double" "b" }
436 { "double" "c" }
437 { "double" "d" } ;
438
439 : <double-rect> ( a b c d -- foo )
440     "double-rect" <c-object>
441     {
442         [ set-double-rect-d ]
443         [ set-double-rect-c ]
444         [ set-double-rect-b ]
445         [ set-double-rect-a ]
446         [ ]
447     } cleave ;
448
449 : >double-rect< ( foo -- a b c d )
450     {
451         [ double-rect-a ]
452         [ double-rect-b ]
453         [ double-rect-c ]
454         [ double-rect-d ]
455     } cleave ;
456
457 : double-rect-callback ( -- alien )
458     "void" { "void*" "void*" "double-rect" } "cdecl"
459     [ "example" set-global 2drop ] alien-callback ;
460
461 : double-rect-test ( arg -- arg' )
462     f f rot
463     double-rect-callback
464     "void" { "void*" "void*" "double-rect" } "cdecl" alien-indirect
465     "example" get-global ;
466
467 [ 1.0 2.0 3.0 4.0 ]
468 [ 1.0 2.0 3.0 4.0 <double-rect> double-rect-test >double-rect< ] unit-test
469
470 C-STRUCT: test_struct_14
471 { "double" "x1" }
472 { "double" "x2" } ;
473
474 FUNCTION: test_struct_14 ffi_test_40 ( double x1, double x2 ) ;
475
476 [ 1.0 2.0 ] [
477     1.0 2.0 ffi_test_40
478     [ test_struct_14-x1 ] [ test_struct_14-x2 ] bi
479 ] unit-test
480
481 : callback-10 ( -- callback )
482     "test_struct_14" { "double" "double" } "cdecl"
483     [
484         "test_struct_14" <c-object>
485         [ set-test_struct_14-x2 ] keep
486         [ set-test_struct_14-x1 ] keep
487     ] alien-callback ;
488
489 : callback-10-test ( x1 x2 callback -- result )
490     "test_struct_14" { "double" "double" } "cdecl" alien-indirect ;
491
492 [ 1.0 2.0 ] [
493     1.0 2.0 callback-10 callback-10-test
494     [ test_struct_14-x1 ] [ test_struct_14-x2 ] bi
495 ] unit-test
496
497 FUNCTION: test-struct-12 ffi_test_41 ( int a, double x ) ;
498
499 [ 1 2.0 ] [
500     1 2.0 ffi_test_41
501     [ test-struct-12-a ] [ test-struct-12-x ] bi
502 ] unit-test
503
504 : callback-11 ( -- callback )
505     "test-struct-12" { "int" "double" } "cdecl"
506     [
507         "test-struct-12" <c-object>
508         [ set-test-struct-12-x ] keep
509         [ set-test-struct-12-a ] keep
510     ] alien-callback ;
511
512 : callback-11-test ( x1 x2 callback -- result )
513     "test-struct-12" { "int" "double" } "cdecl" alien-indirect ;
514
515 [ 1 2.0 ] [
516     1 2.0 callback-11 callback-11-test
517     [ test-struct-12-a ] [ test-struct-12-x ] bi
518 ] unit-test
519
520 C-STRUCT: test_struct_15
521 { "float" "x" }
522 { "float" "y" } ;
523
524 FUNCTION: test_struct_15 ffi_test_42 ( float x, float y ) ;
525
526 [ 1.0 2.0 ] [ 1.0 2.0 ffi_test_42 [ test_struct_15-x ] [ test_struct_15-y ] bi ] unit-test
527
528 : callback-12 ( -- callback )
529     "test_struct_15" { "float" "float" } "cdecl"
530     [
531         "test_struct_15" <c-object>
532         [ set-test_struct_15-y ] keep
533         [ set-test_struct_15-x ] keep
534     ] alien-callback ;
535
536 : callback-12-test ( x1 x2 callback -- result )
537     "test_struct_15" { "float" "float" } "cdecl" alien-indirect ;
538
539 [ 1.0 2.0 ] [
540     1.0 2.0 callback-12 callback-12-test
541     [ test_struct_15-x ] [ test_struct_15-y ] bi
542 ] unit-test
543
544 C-STRUCT: test_struct_16
545 { "float" "x" }
546 { "int" "a" } ;
547
548 FUNCTION: test_struct_16 ffi_test_43 ( float x, int a ) ;
549
550 [ 1.0 2 ] [ 1.0 2 ffi_test_43 [ test_struct_16-x ] [ test_struct_16-a ] bi ] unit-test
551
552 : callback-13 ( -- callback )
553     "test_struct_16" { "float" "int" } "cdecl"
554     [
555         "test_struct_16" <c-object>
556         [ set-test_struct_16-a ] keep
557         [ set-test_struct_16-x ] keep
558     ] alien-callback ;
559
560 : callback-13-test ( x1 x2 callback -- result )
561     "test_struct_16" { "float" "int" } "cdecl" alien-indirect ;
562
563 [ 1.0 2 ] [
564     1.0 2 callback-13 callback-13-test
565     [ test_struct_16-x ] [ test_struct_16-a ] bi
566 ] unit-test
567
568 FUNCTION: test_struct_14 ffi_test_44 ( ) ; inline
569
570 [ 1.0 2.0 ] [ ffi_test_44 [ test_struct_14-x1 ] [ test_struct_14-x2 ] bi ] unit-test
571
572 : stack-frame-bustage ( -- a b ) ffi_test_44 gc 3 ;
573
574 [ ] [ stack-frame-bustage 2drop ] unit-test
575
576 FUNCTION: complex-float ffi_test_45 ( int x ) ;
577
578 [ C{ 3.0 0.0 } ] [ 3 ffi_test_45 ] unit-test
579
580 FUNCTION: complex-double ffi_test_46 ( int x ) ;
581
582 [ C{ 3.0 0.0 } ] [ 3 ffi_test_46 ] unit-test
583
584 FUNCTION: complex-float ffi_test_47 ( complex-float x, complex-double y ) ;
585
586 [ C{ 4.0 4.0 } ] [
587     C{ 1.0 2.0 }
588     C{ 1.5 1.0 } ffi_test_47
589 ] unit-test
590
591 ! Reported by jedahu
592 C-STRUCT: bool-field-test
593    { "char*" "name" }
594    { "bool"  "on" }
595    { "short" "parents" } ;
596
597 FUNCTION: short ffi_test_48 ( bool-field-test x ) ;
598
599 [ 123 ] [
600     "bool-field-test" <c-object> 123 over set-bool-field-test-parents
601     ffi_test_48
602 ] unit-test