1 /* -----------------------------------------------------------------------
2 ffitest.c - Copyright (c) 1996, 1997, 1998, 2002, 2003 Red Hat, Inc.
4 Permission is hereby granted, free of charge, to any person obtaining
5 a copy of this software and associated documentation files (the
6 ``Software''), to deal in the Software without restriction, including
7 without limitation the rights to use, copy, modify, merge, publish,
8 distribute, sublicense, and/or sell copies of the Software, and to
9 permit persons to whom the Software is furnished to do so, subject to
10 the following conditions:
12 The above copyright notice and this permission notice shall be included
13 in all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 OTHER DEALINGS IN THE SOFTWARE.
22 ----------------------------------------------------------------------- */
30 /* This is lame. Long double support is barely there under SunOS 4.x */
31 #if defined(SPARC) && (SIZEOF_LONG_DOUBLE != 16)
32 #define BROKEN_LONG_DOUBLE
35 #define CHECK(x) !(x) ? fail(__FILE__, __LINE__) : 0
37 static int fail(char *file
, int line
)
39 fprintf(stderr
, "Test failure: %s line %d\n", file
, line
);
47 static size_t my_strlen(char *s
)
53 static size_t __attribute__((stdcall)) my_stdcall_strlen(char *s
)
57 #endif /* X86_WIN32 */
59 static int promotion(signed char sc
, signed short ss
,
60 unsigned char uc
, unsigned short us
)
62 int r
= (int) sc
+ (int) ss
+ (int) uc
+ (int) us
;
67 static signed char return_sc(signed char sc
)
72 static unsigned char return_uc(unsigned char uc
)
77 static long long return_ll(long long ll
)
82 static int floating(int a
, float b
, double c
, long double d
, int e
)
87 /* This is ifdef'd out for now. long double support under SunOS/gcc
88 is pretty much non-existent. You'll get the odd bus error in library
89 routines like printf(). */
90 printf("%d %f %f %Lf %d\n", a
, (double)b
, c
, d
, e
);
93 i
= (int) ((float)a
/b
+ ((float)c
/(float)d
));
98 static float many(float f1
,
113 printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
114 (double) f1
, (double) f2
, (double) f3
, (double) f4
, (double) f5
,
115 (double) f6
, (double) f7
, (double) f8
, (double) f9
, (double) f10
,
116 (double) f11
, (double) f12
, (double) f13
);
119 return ((f1
/f2
+f3
/f4
+f5
/f6
+f7
/f8
+f9
/f10
+f11
/f12
) * f13
);
123 static float __attribute__((stdcall)) stdcall_many(float f1
,
137 return ((f1
/f2
+f3
/f4
+f5
/f6
+f7
/f8
+f9
/f10
+f11
/f12
) * f13
);
139 #endif /* X86_WIN32 */
141 static double dblit(float f
)
146 static long double ldblit(float f
)
148 return (long double) (((long double) f
)/ (long double) 3.0);
209 static test_structure_1
struct1(test_structure_1 ts
)
220 static test_structure_2
struct2(test_structure_2 ts
)
228 static test_structure_3
struct3(test_structure_3 ts
)
235 static test_structure_4
struct4(test_structure_4 ts
)
237 ts
.ui3
= ts
.ui1
* ts
.ui2
* ts
.ui3
;
242 static test_structure_5
struct5(test_structure_5 ts1
, test_structure_5 ts2
)
250 static test_structure_6
struct6 (test_structure_6 ts
)
258 static test_structure_7
struct7 (test_structure_7 ts
)
267 static test_structure_8
struct8 (test_structure_8 ts
)
277 static test_structure_9
struct9 (test_structure_9 ts
)
285 /* Take an int and a float argument, together with int userdata, and */
286 /* return the sum. */
289 closure_test_fn(ffi_cif
* cif
,void* resp
,void** args
, void* userdata
)
292 (int)*(unsigned long long *)args
[0] + (int)(*(int *)args
[1]) +
293 (int)(*(unsigned long long *)args
[2]) + (int)*(int *)args
[3] +
294 (int)(*(signed short *)args
[4]) +
295 (int)(*(unsigned long long *)args
[5]) +
296 (int)*(int *)args
[6] + (int)(*(int *)args
[7]) +
297 (int)(*(double *)args
[8]) + (int)*(int *)args
[9] +
298 (int)(*(int *)args
[10]) + (int)(*(float *)args
[11]) +
299 (int)*(int *)args
[12] + (int)(*(int *)args
[13]) +
300 (int)(*(int *)args
[14]) + *(int *)args
[15] + (int)(long)userdata
;
302 printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
303 (int)*(unsigned long long *)args
[0], (int)(*(int *)args
[1]),
304 (int)(*(unsigned long long *)args
[2]),
305 (int)*(int *)args
[3], (int)(*(signed short *)args
[4]),
306 (int)(*(unsigned long long *)args
[5]),
307 (int)*(int *)args
[6], (int)(*(int *)args
[7]),
308 (int)(*(double *)args
[8]), (int)*(int *)args
[9],
309 (int)(*(int *)args
[10]), (int)(*(float *)args
[11]),
310 (int)*(int *)args
[12], (int)(*(int *)args
[13]),
311 (int)(*(int *)args
[14]),*(int *)args
[15],
312 (int)(long)userdata
, *(int*)resp
);
315 typedef int (*closure_test_type
)(unsigned long long, int, unsigned long long,
316 int, signed short, unsigned long long, int,
317 int, double, int, int, float, int, int,
320 static void closure_test_fn1(ffi_cif
* cif
,void* resp
,void** args
,
324 (int)*(float *)args
[0] +(int)(*(float *)args
[1]) +
325 (int)(*(float *)args
[2]) + (int)*(float *)args
[3] +
326 (int)(*(signed short *)args
[4]) + (int)(*(float *)args
[5]) +
327 (int)*(float *)args
[6] + (int)(*(int *)args
[7]) +
328 (int)(*(double*)args
[8]) + (int)*(int *)args
[9] +
329 (int)(*(int *)args
[10]) + (int)(*(float *)args
[11]) +
330 (int)*(int *)args
[12] + (int)(*(int *)args
[13]) +
331 (int)(*(int *)args
[14]) + *(int *)args
[15] + (int)(long)userdata
;
333 printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
334 (int)*(float *)args
[0], (int)(*(float *)args
[1]),
335 (int)(*(float *)args
[2]), (int)*(float *)args
[3],
336 (int)(*(signed short *)args
[4]), (int)(*(float *)args
[5]),
337 (int)*(float *)args
[6], (int)(*(int *)args
[7]),
338 (int)(*(double *)args
[8]), (int)*(int *)args
[9],
339 (int)(*(int *)args
[10]), (int)(*(float *)args
[11]),
340 (int)*(int *)args
[12], (int)(*(int *)args
[13]),
341 (int)(*(int *)args
[14]), *(int *)args
[15],
342 (int)(long)userdata
, *(int*)resp
);
345 typedef int (*closure_test_type1
)(float, float, float, float, signed short,
346 float, float, int, double, int, int, float,
349 static void closure_test_fn2(ffi_cif
* cif
,void* resp
,void** args
,
353 (int)*(double *)args
[0] +(int)(*(double *)args
[1]) +
354 (int)(*(double *)args
[2]) + (int)*(double *)args
[3] +
355 (int)(*(signed short *)args
[4]) + (int)(*(double *)args
[5]) +
356 (int)*(double *)args
[6] + (int)(*(int *)args
[7]) +
357 (int)(*(double *)args
[8]) + (int)*(int *)args
[9] +
358 (int)(*(int *)args
[10]) + (int)(*(float *)args
[11]) +
359 (int)*(int *)args
[12] + (int)(*(float *)args
[13]) +
360 (int)(*(int *)args
[14]) + *(int *)args
[15] + (int)(long)userdata
;
362 printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
363 (int)*(double *)args
[0], (int)(*(double *)args
[1]),
364 (int)(*(double *)args
[2]), (int)*(double *)args
[3],
365 (int)(*(signed short *)args
[4]), (int)(*(double *)args
[5]),
366 (int)*(double *)args
[6], (int)(*(int *)args
[7]),
367 (int)(*(double*)args
[8]), (int)*(int *)args
[9],
368 (int)(*(int *)args
[10]), (int)(*(float *)args
[11]),
369 (int)*(int *)args
[12], (int)(*(float *)args
[13]),
370 (int)(*(int *)args
[14]), *(int *)args
[15], (int)(long)userdata
,
374 typedef int (*closure_test_type2
)(double, double, double, double, signed short,
375 double, double, int, double, int, int, float,
376 int, float, int, int);
378 static void closure_test_fn3(ffi_cif
* cif
,void* resp
,void** args
,
382 (int)*(float *)args
[0] +(int)(*(float *)args
[1]) +
383 (int)(*(float *)args
[2]) + (int)*(float *)args
[3] +
384 (int)(*(float *)args
[4]) + (int)(*(float *)args
[5]) +
385 (int)*(float *)args
[6] + (int)(*(float *)args
[7]) +
386 (int)(*(double *)args
[8]) + (int)*(int *)args
[9] +
387 (int)(*(float *)args
[10]) + (int)(*(float *)args
[11]) +
388 (int)*(int *)args
[12] + (int)(*(float *)args
[13]) +
389 (int)(*(float *)args
[14]) + *(int *)args
[15] + (int)(long)userdata
;
391 printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
392 (int)*(float *)args
[0], (int)(*(float *)args
[1]),
393 (int)(*(float *)args
[2]), (int)*(float *)args
[3],
394 (int)(*(float *)args
[4]), (int)(*(float *)args
[5]),
395 (int)*(float *)args
[6], (int)(*(float *)args
[7]),
396 (int)(*(double *)args
[8]), (int)*(int *)args
[9],
397 (int)(*(float *)args
[10]), (int)(*(float *)args
[11]),
398 (int)*(int *)args
[12], (int)(*(float *)args
[13]),
399 (int)(*(float *)args
[14]), *(int *)args
[15], (int)(long)userdata
,
403 typedef int (*closure_test_type3
)(float, float, float, float, float, float,
404 float, float, double, int, float, float, int,
408 int main(/*@unused@*/ int argc
, /*@unused@*/ char *argv
[])
411 ffi_type
*args
[MAX_ARGS
];
412 void *values
[MAX_ARGS
];
430 /* The closure must not be an automatic variable on
431 platforms (Solaris) that forbid stack execution by default. */
432 static ffi_closure cl
;
435 ffi_type
* cl_arg_types
[17];
446 ffi_type
*ts1_type_elements
[4];
447 ffi_type
*ts2_type_elements
[3];
448 ffi_type
*ts3_type_elements
[2];
449 ffi_type
*ts4_type_elements
[4];
450 ffi_type
*ts5_type_elements
[3];
451 ffi_type
*ts6_type_elements
[3];
452 ffi_type
*ts7_type_elements
[4];
453 ffi_type
*ts8_type_elements
[5];
454 ffi_type
*ts9_type_elements
[3];
457 ts1_type
.alignment
= 0;
458 ts1_type
.type
= FFI_TYPE_STRUCT
;
461 ts2_type
.alignment
= 0;
462 ts2_type
.type
= FFI_TYPE_STRUCT
;
465 ts3_type
.alignment
= 0;
466 ts3_type
.type
= FFI_TYPE_STRUCT
;
469 ts4_type
.alignment
= 0;
470 ts4_type
.type
= FFI_TYPE_STRUCT
;
473 ts5_type
.alignment
= 0;
474 ts5_type
.type
= FFI_TYPE_STRUCT
;
477 ts6_type
.alignment
= 0;
478 ts6_type
.type
= FFI_TYPE_STRUCT
;
481 ts7_type
.alignment
= 0;
482 ts7_type
.type
= FFI_TYPE_STRUCT
;
485 ts8_type
.alignment
= 0;
486 ts8_type
.type
= FFI_TYPE_STRUCT
;
489 ts9_type
.alignment
= 0;
490 ts9_type
.type
= FFI_TYPE_STRUCT
;
492 /*@-immediatetrans@*/
493 ts1_type
.elements
= ts1_type_elements
;
494 ts2_type
.elements
= ts2_type_elements
;
495 ts3_type
.elements
= ts3_type_elements
;
496 ts4_type
.elements
= ts4_type_elements
;
497 ts5_type
.elements
= ts5_type_elements
;
498 ts6_type
.elements
= ts6_type_elements
;
499 ts7_type
.elements
= ts7_type_elements
;
500 ts8_type
.elements
= ts8_type_elements
;
501 ts9_type
.elements
= ts9_type_elements
;
502 /*@=immediatetrans@*/
504 ts1_type_elements
[0] = &ffi_type_uchar
;
505 ts1_type_elements
[1] = &ffi_type_double
;
506 ts1_type_elements
[2] = &ffi_type_uint
;
507 ts1_type_elements
[3] = NULL
;
509 ts2_type_elements
[0] = &ffi_type_double
;
510 ts2_type_elements
[1] = &ffi_type_double
;
511 ts2_type_elements
[2] = NULL
;
513 ts3_type_elements
[0] = &ffi_type_sint
;
514 ts3_type_elements
[1] = NULL
;
516 ts4_type_elements
[0] = &ffi_type_uint
;
517 ts4_type_elements
[1] = &ffi_type_uint
;
518 ts4_type_elements
[2] = &ffi_type_uint
;
519 ts4_type_elements
[3] = NULL
;
521 ts5_type_elements
[0] = &ffi_type_schar
;
522 ts5_type_elements
[1] = &ffi_type_schar
;
523 ts5_type_elements
[2] = NULL
;
525 ts6_type_elements
[0] = &ffi_type_float
;
526 ts6_type_elements
[1] = &ffi_type_double
;
527 ts6_type_elements
[2] = NULL
;
529 ts7_type_elements
[0] = &ffi_type_float
;
530 ts7_type_elements
[1] = &ffi_type_float
;
531 ts7_type_elements
[2] = &ffi_type_double
;
532 ts7_type_elements
[3] = NULL
;
534 ts8_type_elements
[0] = &ffi_type_float
;
535 ts8_type_elements
[1] = &ffi_type_float
;
536 ts8_type_elements
[2] = &ffi_type_float
;
537 ts8_type_elements
[3] = &ffi_type_float
;
538 ts8_type_elements
[4] = NULL
;
540 ts9_type_elements
[0] = &ffi_type_float
;
541 ts9_type_elements
[1] = &ffi_type_sint
;
542 ts9_type_elements
[2] = NULL
;
546 /* return value tests */
548 #if defined(MIPS) /* || defined(ARM) */
549 puts ("long long tests not run. This is a known bug on this architecture.");
551 args
[0] = &ffi_type_sint64
;
554 /* Initialize the cif */
555 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1,
556 &ffi_type_sint64
, args
) == FFI_OK
);
558 for (ll
= 0LL; ll
< 100LL; ll
++)
561 ffi_call(&cif
, FFI_FN(return_ll
), &rlonglong
, values
);
562 CHECK(rlonglong
== ll
);
565 for (ll
= 55555555555000LL; ll
< 55555555555100LL; ll
++)
568 ffi_call(&cif
, FFI_FN(return_ll
), &rlonglong
, values
);
569 CHECK(rlonglong
== ll
);
573 args
[0] = &ffi_type_schar
;
576 /* Initialize the cif */
577 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1,
578 &ffi_type_schar
, args
) == FFI_OK
);
580 for (sc
= (signed char) -127;
581 sc
< (signed char) 127; /*@-type@*/ sc
++ /*@=type@*/)
584 ffi_call(&cif
, FFI_FN(return_sc
), &rint
, values
);
585 CHECK(rint
== (ffi_arg
) sc
);
588 args
[0] = &ffi_type_uchar
;
591 /* Initialize the cif */
592 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1,
593 &ffi_type_uchar
, args
) == FFI_OK
);
595 for (uc
= (unsigned char) '\x00';
596 uc
< (unsigned char) '\xff'; /*@-type@*/ uc
++ /*@=type@*/)
599 ffi_call(&cif
, FFI_FN(return_uc
), &rint
, values
);
600 CHECK(rint
== (signed int) uc
);
603 printf("%lu return value tests run\n", ul
);
606 #ifdef BROKEN_LONG_DOUBLE
607 printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n");
609 /* float arg tests */
611 args
[0] = &ffi_type_float
;
614 /* Initialize the cif */
615 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1,
616 &ffi_type_longdouble
, args
) == FFI_OK
);
621 /* This is ifdef'd out for now. long double support under SunOS/gcc
622 is pretty much non-existent. You'll get the odd bus error in library
623 routines like printf(). */
624 printf ("%Lf\n", ldblit(f
));
627 ffi_call(&cif
, FFI_FN(ldblit
), &ld
, values
);
630 /* This is ifdef'd out for now. long double support under SunOS/gcc
631 is pretty much non-existent. You'll get the odd bus error in library
632 routines like printf(). */
633 printf ("%Lf, %Lf, %Lf, %Lf\n", ld
, ldblit(f
), ld
- ldblit(f
), LDBL_EPSILON
);
636 /* These are not always the same!! Check for a reasonable delta */
638 if (ld
- ldblit(f
) < LDBL_EPSILON
)
640 puts("long double return value tests ok!");
645 /* float arg tests */
647 args
[0] = &ffi_type_sint
;
649 args
[1] = &ffi_type_float
;
651 args
[2] = &ffi_type_double
;
653 args
[3] = &ffi_type_longdouble
;
655 args
[4] = &ffi_type_sint
;
658 /* Initialize the cif */
659 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 5,
660 &ffi_type_sint
, args
) == FFI_OK
);
664 d
= (double)1.0/(double)3.0;
668 floating (si1
, f
, d
, ld
, si2
);
670 ffi_call(&cif
, FFI_FN(floating
), &rint
, values
);
672 printf ("%d vs %d\n", (int)rint
, floating (si1
, f
, d
, ld
, si2
));
674 CHECK(rint
== floating(si1
, f
, d
, ld
, si2
));
676 printf("float arg tests ok!\n");
682 args
[0] = &ffi_type_pointer
;
683 values
[0] = (void*) &s
;
685 /* Initialize the cif */
686 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1,
687 &ffi_type_sint
, args
) == FFI_OK
);
690 ffi_call(&cif
, FFI_FN(my_strlen
), &rint
, values
);
694 ffi_call(&cif
, FFI_FN(my_strlen
), &rint
, values
);
697 s
= "1234567890123456789012345";
698 ffi_call(&cif
, FFI_FN(my_strlen
), &rint
, values
);
701 printf("strlen tests passed\n");
704 /* float arg tests */
706 args
[0] = &ffi_type_float
;
709 /* Initialize the cif */
710 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1,
711 &ffi_type_double
, args
) == FFI_OK
);
715 ffi_call(&cif
, FFI_FN(dblit
), &d
, values
);
717 /* These are not always the same!! Check for a reasonable delta */
719 CHECK(d
- dblit(f
) < DBL_EPSILON
);
722 printf("double return value tests ok!\n");
730 for (ul
= 0; ul
< 13; ul
++)
732 args
[ul
] = &ffi_type_float
;
733 values
[ul
] = &fa
[ul
];
737 /* Initialize the cif */
738 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 13,
739 &ffi_type_float
, args
) == FFI_OK
);
742 ff
= many (fa
[0], fa
[1],
747 fa
[10],fa
[11],fa
[12]);
750 ffi_call(&cif
, FFI_FN(many
), &f
, values
);
753 if (f
- ff
< FLT_EPSILON
)
755 printf("many arg tests ok!\n");
758 printf("many arg tests failed! This is a gcc bug.\n");
764 /* promotion tests */
766 args
[0] = &ffi_type_schar
;
767 args
[1] = &ffi_type_sshort
;
768 args
[2] = &ffi_type_uchar
;
769 args
[3] = &ffi_type_ushort
;
775 /* Initialize the cif */
776 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 4,
777 &ffi_type_sint
, args
) == FFI_OK
);
782 for (sc
= (signed char) -127;
783 sc
<= (signed char) 120; /*@-type@*/ sc
+= 1 /*@=type@*/)
784 for (ss
= -30000; ss
<= 30000; ss
+= 10000)
785 for (uc
= (unsigned char) 0;
786 uc
<= (unsigned char) 200; /*@-type@*/ uc
+= 20 /*@=type@*/)
787 for (us
= 0; us
<= 60000; us
+= 10000)
790 ffi_call(&cif
, FFI_FN(promotion
), &rint
, values
);
791 CHECK((int)rint
== (signed char) sc
+ (signed short) ss
+
792 (unsigned char) uc
+ (unsigned short) us
);
794 printf("%lu promotion tests run\n", ul
);
797 #ifndef X86_WIN32 /* Structures dont work on Win32 */
801 test_structure_1 ts1_arg
;
802 /* This is a hack to get a properly aligned result buffer */
803 test_structure_1
*ts1_result
=
804 (test_structure_1
*) malloc (sizeof(test_structure_1
));
807 values
[0] = &ts1_arg
;
809 /* Initialize the cif */
810 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1,
811 &ts1_type
, args
) == FFI_OK
);
817 ffi_call(&cif
, FFI_FN(struct1
), ts1_result
, values
);
819 CHECK(ts1_result
->ui
== 556);
820 CHECK(ts1_result
->d
== 3.14159 - 1);
822 puts ("structure test 1 ok!\n");
829 test_structure_2 ts2_arg
;
831 /* This is a hack to get a properly aligned result buffer */
832 test_structure_2
*ts2_result
=
833 (test_structure_2
*) malloc (sizeof(test_structure_2
));
836 values
[0] = &ts2_arg
;
838 /* Initialize the cif */
839 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1, &ts2_type
, args
) == FFI_OK
);
844 printf ("%g\n", ts2_result
->d1
);
845 printf ("%g\n", ts2_result
->d2
);
847 ffi_call(&cif
, FFI_FN(struct2
), ts2_result
, values
);
849 printf ("%g\n", ts2_result
->d1
);
850 printf ("%g\n", ts2_result
->d2
);
852 CHECK(ts2_result
->d1
== 5.55 - 1);
853 CHECK(ts2_result
->d2
== 6.66 - 1);
855 printf("structure test 2 ok!\n");
863 test_structure_3 ts3_arg
;
864 test_structure_3
*ts3_result
=
865 (test_structure_3
*) malloc (sizeof(test_structure_3
));
868 values
[0] = &ts3_arg
;
870 /* Initialize the cif */
871 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1,
872 &ts3_type
, args
) == FFI_OK
);
875 compare_value
= ts3_arg
.si
;
877 ffi_call(&cif
, FFI_FN(struct3
), ts3_result
, values
);
879 printf ("%d %d\n", ts3_result
->si
, -(compare_value
*2));
881 if (ts3_result
->si
== -(ts3_arg
.si
*2))
882 puts ("structure test 3 ok!");
885 puts ("Structure test 3 found structure passing bug.");
886 puts (" Current versions of GCC are not 100% compliant with the");
887 puts (" n32 ABI. There is a known problem related to passing");
888 puts (" small structures. Send a bug report to the gcc maintainers.");
896 test_structure_4 ts4_arg
;
898 /* This is a hack to get a properly aligned result buffer */
899 test_structure_4
*ts4_result
=
900 (test_structure_4
*) malloc (sizeof(test_structure_4
));
903 values
[0] = &ts4_arg
;
905 /* Initialize the cif */
906 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1, &ts4_type
, args
) == FFI_OK
);
912 ffi_call (&cif
, FFI_FN(struct4
), ts4_result
, values
);
914 if (ts4_result
->ui3
== 2U * 3U * 4U)
915 puts ("structure test 4 ok!");
917 puts ("Structure test 4 found GCC's structure passing bug.");
924 test_structure_5 ts5_arg1
, ts5_arg2
;
926 /* This is a hack to get a properly aligned result buffer */
927 test_structure_5
*ts5_result
=
928 (test_structure_5
*) malloc (sizeof(test_structure_5
));
932 values
[0] = &ts5_arg1
;
933 values
[1] = &ts5_arg2
;
935 /* Initialize the cif */
936 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 2, &ts5_type
, args
) == FFI_OK
);
943 ffi_call (&cif
, FFI_FN(struct5
), ts5_result
, values
);
945 if (ts5_result
->c1
== 7
946 && ts5_result
->c2
== 3)
947 puts ("structure test 5 ok!");
949 puts ("Structure test 5 found GCC's structure passing bug.");
956 test_structure_6 ts6_arg
;
958 /* This is a hack to get a properly aligned result buffer */
959 test_structure_6
*ts6_result
=
960 (test_structure_6
*) malloc (sizeof(test_structure_6
));
963 values
[0] = &ts6_arg
;
965 /* Initialize the cif */
966 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1, &ts6_type
, args
) == FFI_OK
);
971 printf ("%g\n", ts6_arg
.f
);
972 printf ("%g\n", ts6_arg
.d
);
974 ffi_call(&cif
, FFI_FN(struct6
), ts6_result
, values
);
976 printf ("%g\n", ts6_result
->f
);
977 printf ("%g\n", ts6_result
->d
);
979 CHECK(ts6_result
->f
== 5.55f
+ 1);
980 CHECK(ts6_result
->d
== 6.66 + 1);
982 printf("structure test 6 ok!\n");
989 test_structure_7 ts7_arg
;
991 /* This is a hack to get a properly aligned result buffer */
992 test_structure_7
*ts7_result
=
993 (test_structure_7
*) malloc (sizeof(test_structure_7
));
996 values
[0] = &ts7_arg
;
998 /* Initialize the cif */
999 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1, &ts7_type
, args
) == FFI_OK
);
1005 printf ("%g\n", ts7_arg
.f1
);
1006 printf ("%g\n", ts7_arg
.f2
);
1007 printf ("%g\n", ts7_arg
.d
);
1009 ffi_call(&cif
, FFI_FN(struct7
), ts7_result
, values
);
1011 printf ("%g\n", ts7_result
->f1
);
1012 printf ("%g\n", ts7_result
->f2
);
1013 printf ("%g\n", ts7_result
->d
);
1015 CHECK(ts7_result
->f1
== 5.55f
+ 1);
1016 CHECK(ts7_result
->f2
== 55.5f
+ 1);
1017 CHECK(ts7_result
->d
== 6.66 + 1);
1019 printf("structure test 7 ok!\n");
1026 test_structure_8 ts8_arg
;
1028 /* This is a hack to get a properly aligned result buffer */
1029 test_structure_8
*ts8_result
=
1030 (test_structure_8
*) malloc (sizeof(test_structure_8
));
1032 args
[0] = &ts8_type
;
1033 values
[0] = &ts8_arg
;
1035 /* Initialize the cif */
1036 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1, &ts8_type
, args
) == FFI_OK
);
1040 ts8_arg
.f3
= -5.55f
;
1041 ts8_arg
.f4
= -55.5f
;
1043 printf ("%g\n", ts8_arg
.f1
);
1044 printf ("%g\n", ts8_arg
.f2
);
1045 printf ("%g\n", ts8_arg
.f3
);
1046 printf ("%g\n", ts8_arg
.f4
);
1048 ffi_call(&cif
, FFI_FN(struct8
), ts8_result
, values
);
1050 printf ("%g\n", ts8_result
->f1
);
1051 printf ("%g\n", ts8_result
->f2
);
1052 printf ("%g\n", ts8_result
->f3
);
1053 printf ("%g\n", ts8_result
->f4
);
1055 CHECK(ts8_result
->f1
== 5.55f
+ 1);
1056 CHECK(ts8_result
->f2
== 55.5f
+ 1);
1057 CHECK(ts8_result
->f3
== -5.55f
+ 1);
1058 CHECK(ts8_result
->f4
== -55.5f
+ 1);
1060 printf("structure test 8 ok!\n");
1067 test_structure_9 ts9_arg
;
1069 /* This is a hack to get a properly aligned result buffer */
1070 test_structure_9
*ts9_result
=
1071 (test_structure_9
*) malloc (sizeof(test_structure_9
));
1073 args
[0] = &ts9_type
;
1074 values
[0] = &ts9_arg
;
1076 /* Initialize the cif */
1077 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1, &ts9_type
, args
) == FFI_OK
);
1082 printf ("%g\n", ts9_arg
.f
);
1083 printf ("%d\n", ts9_arg
.i
);
1085 ffi_call(&cif
, FFI_FN(struct9
), ts9_result
, values
);
1087 printf ("%g\n", ts9_result
->f
);
1088 printf ("%d\n", ts9_result
->i
);
1090 CHECK(ts9_result
->f
== 5.55f
+ 1);
1091 CHECK(ts9_result
->i
== 5 + 1);
1093 printf("structure test 9 ok!\n");
1099 printf("Structure passing doesn't work on Win32.\n");
1100 #endif /* X86_WIN32 */
1103 /* stdcall strlen tests */
1105 args
[0] = &ffi_type_pointer
;
1106 values
[0] = (void*) &s
;
1108 /* Initialize the cif */
1109 CHECK(ffi_prep_cif(&cif
, FFI_STDCALL
, 1,
1110 &ffi_type_sint
, args
) == FFI_OK
);
1113 ffi_call(&cif
, FFI_FN(my_stdcall_strlen
), &rint
, values
);
1117 ffi_call(&cif
, FFI_FN(my_stdcall_strlen
), &rint
, values
);
1120 s
= "1234567890123456789012345";
1121 ffi_call(&cif
, FFI_FN(my_stdcall_strlen
), &rint
, values
);
1124 printf("stdcall strlen tests passed\n");
1127 /* stdcall many arg tests */
1132 for (ul
= 0; ul
< 13; ul
++)
1134 args
[ul
] = &ffi_type_float
;
1135 values
[ul
] = &fa
[ul
];
1136 fa
[ul
] = (float) ul
;
1139 /* Initialize the cif */
1140 CHECK(ffi_prep_cif(&cif
, FFI_STDCALL
, 13,
1141 &ffi_type_float
, args
) == FFI_OK
);
1144 ff
= stdcall_many(fa
[0], fa
[1],
1149 fa
[10],fa
[11],fa
[12]);
1152 ffi_call(&cif
, FFI_FN(stdcall_many
), &f
, values
);
1155 if (f
- ff
< FLT_EPSILON
)
1157 printf("stdcall many arg tests ok!\n");
1161 #endif /* X86_WIN32 */
1164 /* A simple closure test */
1166 (void) puts("\nEnter FFI_CLOSURES\n");
1168 cl_arg_types
[0] = &ffi_type_uint64
;
1169 cl_arg_types
[1] = &ffi_type_uint
;
1170 cl_arg_types
[2] = &ffi_type_uint64
;
1171 cl_arg_types
[3] = &ffi_type_uint
;
1172 cl_arg_types
[4] = &ffi_type_sshort
;
1173 cl_arg_types
[5] = &ffi_type_uint64
;
1174 cl_arg_types
[6] = &ffi_type_uint
;
1175 cl_arg_types
[7] = &ffi_type_uint
;
1176 cl_arg_types
[8] = &ffi_type_double
;
1177 cl_arg_types
[9] = &ffi_type_uint
;
1178 cl_arg_types
[10] = &ffi_type_uint
;
1179 cl_arg_types
[11] = &ffi_type_float
;
1180 cl_arg_types
[12] = &ffi_type_uint
;
1181 cl_arg_types
[13] = &ffi_type_uint
;
1182 cl_arg_types
[14] = &ffi_type_uint
;
1183 cl_arg_types
[15] = &ffi_type_uint
;
1184 cl_arg_types
[16] = NULL
;
1186 /* Initialize the cif */
1187 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 16,
1188 &ffi_type_sint
, cl_arg_types
) == FFI_OK
);
1190 CHECK(ffi_prep_closure(&cl
, &cif
, closure_test_fn
,
1191 (void *) 3 /* userdata */) == FFI_OK
);
1193 CHECK((*((closure_test_type
)(&cl
)))
1194 (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
1200 cl_arg_types
[0] = &ffi_type_float
;
1201 cl_arg_types
[1] = &ffi_type_float
;
1202 cl_arg_types
[2] = &ffi_type_float
;
1203 cl_arg_types
[3] = &ffi_type_float
;
1204 cl_arg_types
[4] = &ffi_type_sshort
;
1205 cl_arg_types
[5] = &ffi_type_float
;
1206 cl_arg_types
[6] = &ffi_type_float
;
1207 cl_arg_types
[7] = &ffi_type_uint
;
1208 cl_arg_types
[8] = &ffi_type_double
;
1209 cl_arg_types
[9] = &ffi_type_uint
;
1210 cl_arg_types
[10] = &ffi_type_uint
;
1211 cl_arg_types
[11] = &ffi_type_float
;
1212 cl_arg_types
[12] = &ffi_type_uint
;
1213 cl_arg_types
[13] = &ffi_type_uint
;
1214 cl_arg_types
[14] = &ffi_type_uint
;
1215 cl_arg_types
[15] = &ffi_type_uint
;
1216 cl_arg_types
[16] = NULL
;
1218 /* Initialize the cif */
1219 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 16,
1220 &ffi_type_sint
, cl_arg_types
) == FFI_OK
);
1222 CHECK(ffi_prep_closure(&cl
, &cif
, closure_test_fn1
,
1223 (void *) 3 /* userdata */) == FFI_OK
);
1225 CHECK((*((closure_test_type1
)(&cl
)))
1226 (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
1232 cl_arg_types
[0] = &ffi_type_double
;
1233 cl_arg_types
[1] = &ffi_type_double
;
1234 cl_arg_types
[2] = &ffi_type_double
;
1235 cl_arg_types
[3] = &ffi_type_double
;
1236 cl_arg_types
[4] = &ffi_type_sshort
;
1237 cl_arg_types
[5] = &ffi_type_double
;
1238 cl_arg_types
[6] = &ffi_type_double
;
1239 cl_arg_types
[7] = &ffi_type_uint
;
1240 cl_arg_types
[8] = &ffi_type_double
;
1241 cl_arg_types
[9] = &ffi_type_uint
;
1242 cl_arg_types
[10] = &ffi_type_uint
;
1243 cl_arg_types
[11] = &ffi_type_float
;
1244 cl_arg_types
[12] = &ffi_type_uint
;
1245 cl_arg_types
[13] = &ffi_type_float
;
1246 cl_arg_types
[14] = &ffi_type_uint
;
1247 cl_arg_types
[15] = &ffi_type_uint
;
1248 cl_arg_types
[16] = NULL
;
1250 /* Initialize the cif */
1251 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 16,
1252 &ffi_type_sint
, cl_arg_types
) == FFI_OK
);
1254 CHECK(ffi_prep_closure(&cl
, &cif
, closure_test_fn2
,
1255 (void *) 3 /* userdata */) == FFI_OK
);
1257 CHECK((*((closure_test_type2
)(&cl
)))
1258 (1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
1259 19.0, 21, 1) == 255);
1265 cl_arg_types
[0] = &ffi_type_float
;
1266 cl_arg_types
[1] = &ffi_type_float
;
1267 cl_arg_types
[2] = &ffi_type_float
;
1268 cl_arg_types
[3] = &ffi_type_float
;
1269 cl_arg_types
[4] = &ffi_type_float
;
1270 cl_arg_types
[5] = &ffi_type_float
;
1271 cl_arg_types
[6] = &ffi_type_float
;
1272 cl_arg_types
[7] = &ffi_type_float
;
1273 cl_arg_types
[8] = &ffi_type_double
;
1274 cl_arg_types
[9] = &ffi_type_uint
;
1275 cl_arg_types
[10] = &ffi_type_float
;
1276 cl_arg_types
[11] = &ffi_type_float
;
1277 cl_arg_types
[12] = &ffi_type_uint
;
1278 cl_arg_types
[13] = &ffi_type_float
;
1279 cl_arg_types
[14] = &ffi_type_float
;
1280 cl_arg_types
[15] = &ffi_type_uint
;
1281 cl_arg_types
[16] = NULL
;
1283 /* Initialize the cif */
1284 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 16,
1285 &ffi_type_sint
, cl_arg_types
) == FFI_OK
);
1287 CHECK(ffi_prep_closure(&cl
, &cif
, closure_test_fn3
,
1288 (void *) 3 /* userdata */) == FFI_OK
);
1290 CHECK((*((closure_test_type3
)(&cl
)))
1291 (1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
1292 19.19, 21.21, 1) == 135);
1295 (void) puts("\nFinished FFI_CLOSURES\n");
1299 /* If we arrived here, all is good */
1300 (void) puts("\nLooks good. No surprises.\n");