java_raw_api.c (ffi_java_raw_to_ptrarray): Interpret raw data as _Jv_word values...
[gcc.git] / libffi / src / ffitest.c
1 /* -----------------------------------------------------------------------
2 ffitest.c - Copyright (c) 1996, 1997, 1998 Cygnus Solutions
3
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:
11
12 The above copyright notice and this permission notice shall be included
13 in all copies or substantial portions of the Software.
14
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 ----------------------------------------------------------------------- */
23
24 #include <ffi.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <float.h>
29
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
33 #endif
34
35 #define CHECK(x) !(x) ? fail(__FILE__, __LINE__) : 0
36
37 static int fail(char *file, int line)
38 {
39 fprintf(stderr, "Test failure: %s line %d\n", file, line);
40 exit(EXIT_FAILURE);
41 /*@notreached@*/
42 return 0;
43 }
44
45 #define MAX_ARGS 256
46
47 static size_t my_strlen(char *s)
48 {
49 return (strlen(s));
50 }
51
52 static int promotion(signed char sc, signed short ss,
53 unsigned char uc, unsigned short us)
54 {
55 int r = (int) sc + (int) ss + (int) uc + (int) us;
56
57 return r;
58 }
59
60 static signed char return_sc(signed char sc)
61 {
62 return sc;
63 }
64
65 static unsigned char return_uc(unsigned char uc)
66 {
67 return uc;
68 }
69
70 static long long return_ll(long long ll)
71 {
72 return ll;
73 }
74
75 static int floating(int a, float b, double c, long double d, int e)
76 {
77 int i;
78
79 #if 0
80 /* This is ifdef'd out for now. long double support under SunOS/gcc
81 is pretty much non-existent. You'll get the odd bus error in library
82 routines like printf(). */
83 printf("%d %f %f %Lf %d\n", a, (double)b, c, d, e);
84 #endif
85
86 i = (int) ((float)a/b + ((float)c/(float)d));
87
88 return i;
89 }
90
91 static float many(float f1,
92 float f2,
93 float f3,
94 float f4,
95 float f5,
96 float f6,
97 float f7,
98 float f8,
99 float f9,
100 float f10,
101 float f11,
102 float f12,
103 float f13)
104 {
105 #if 0
106 printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
107 (double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
108 (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
109 (double) f11, (double) f12, (double) f13);
110 #endif
111
112 return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
113 }
114
115 static double dblit(float f)
116 {
117 return f/3.0;
118 }
119
120 static long double ldblit(float f)
121 {
122 return (long double) (((long double) f)/ (long double) 3.0);
123 }
124
125 typedef struct
126 {
127 unsigned char uc;
128 double d;
129 unsigned int ui;
130 } test_structure_1;
131
132 typedef struct
133 {
134 double d1;
135 double d2;
136 } test_structure_2;
137
138 typedef struct
139 {
140 int si;
141 } test_structure_3;
142
143 typedef struct
144 {
145 unsigned ui1;
146 unsigned ui2;
147 unsigned ui3;
148 } test_structure_4;
149
150 typedef struct
151 {
152 char c1;
153 char c2;
154 } test_structure_5;
155
156 typedef struct
157 {
158 float f;
159 double d;
160 } test_structure_6;
161
162 typedef struct
163 {
164 float f1;
165 float f2;
166 double d;
167 } test_structure_7;
168
169 typedef struct
170 {
171 float f1;
172 float f2;
173 float f3;
174 float f4;
175 } test_structure_8;
176
177 typedef struct
178 {
179 float f;
180 int i;
181 } test_structure_9;
182
183 static test_structure_1 struct1(test_structure_1 ts)
184 {
185 /*@-type@*/
186 ts.uc++;
187 /*@=type@*/
188 ts.d--;
189 ts.ui++;
190
191 return ts;
192 }
193
194 static test_structure_2 struct2(test_structure_2 ts)
195 {
196 ts.d1--;
197 ts.d2--;
198
199 return ts;
200 }
201
202 static test_structure_3 struct3(test_structure_3 ts)
203 {
204 ts.si = -(ts.si*2);
205
206 return ts;
207 }
208
209 static test_structure_4 struct4(test_structure_4 ts)
210 {
211 ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
212
213 return ts;
214 }
215
216 static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
217 {
218 ts1.c1 += ts2.c1;
219 ts1.c2 -= ts2.c2;
220
221 return ts1;
222 }
223
224 static test_structure_6 struct6 (test_structure_6 ts)
225 {
226 ts.f += 1;
227 ts.d += 1;
228
229 return ts;
230 }
231
232 static test_structure_7 struct7 (test_structure_7 ts)
233 {
234 ts.f1 += 1;
235 ts.f2 += 1;
236 ts.d += 1;
237
238 return ts;
239 }
240
241 static test_structure_8 struct8 (test_structure_8 ts)
242 {
243 ts.f1 += 1;
244 ts.f2 += 1;
245 ts.f3 += 1;
246 ts.f4 += 1;
247
248 return ts;
249 }
250
251 static test_structure_9 struct9 (test_structure_9 ts)
252 {
253 ts.f += 1;
254 ts.i += 1;
255
256 return ts;
257 }
258
259 /* Take an int and a float argument, together with int userdata, and */
260 /* return the sum. */
261 #if FFI_CLOSURES
262 static void
263 closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata)
264 {
265 *(ffi_arg*)resp = *(int*)args[0] + (int)(*(float*)args[1]) + (int)(long)userdata;
266 }
267
268 typedef int (*closure_test_type)(int, float);
269 #endif
270
271 int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
272 {
273 ffi_cif cif;
274 ffi_type *args[MAX_ARGS];
275 void *values[MAX_ARGS];
276 char *s;
277 signed char sc;
278 unsigned char uc;
279 signed short ss;
280 unsigned short us;
281 unsigned long ul;
282 long long ll;
283 float f;
284 double d;
285 long double ld;
286 signed int si1;
287 signed int si2;
288
289 ffi_arg rint;
290 long long rlonglong;
291
292 ffi_type ts1_type;
293 ffi_type ts2_type;
294 ffi_type ts3_type;
295 ffi_type ts4_type;
296 ffi_type ts5_type;
297 ffi_type ts6_type;
298 ffi_type ts7_type;
299 ffi_type ts8_type;
300 ffi_type ts9_type;
301 ffi_type *ts1_type_elements[4];
302 ffi_type *ts2_type_elements[3];
303 ffi_type *ts3_type_elements[2];
304 ffi_type *ts4_type_elements[4];
305 ffi_type *ts5_type_elements[3];
306 ffi_type *ts6_type_elements[3];
307 ffi_type *ts7_type_elements[4];
308 ffi_type *ts8_type_elements[5];
309 ffi_type *ts9_type_elements[3];
310
311 ts1_type.size = 0;
312 ts1_type.alignment = 0;
313 ts1_type.type = FFI_TYPE_STRUCT;
314
315 ts2_type.size = 0;
316 ts2_type.alignment = 0;
317 ts2_type.type = FFI_TYPE_STRUCT;
318
319 ts3_type.size = 0;
320 ts3_type.alignment = 0;
321 ts3_type.type = FFI_TYPE_STRUCT;
322
323 ts4_type.size = 0;
324 ts4_type.alignment = 0;
325 ts4_type.type = FFI_TYPE_STRUCT;
326
327 ts5_type.size = 0;
328 ts5_type.alignment = 0;
329 ts5_type.type = FFI_TYPE_STRUCT;
330
331 ts6_type.size = 0;
332 ts6_type.alignment = 0;
333 ts6_type.type = FFI_TYPE_STRUCT;
334
335 ts7_type.size = 0;
336 ts7_type.alignment = 0;
337 ts7_type.type = FFI_TYPE_STRUCT;
338
339 ts8_type.size = 0;
340 ts8_type.alignment = 0;
341 ts8_type.type = FFI_TYPE_STRUCT;
342
343 ts9_type.size = 0;
344 ts9_type.alignment = 0;
345 ts9_type.type = FFI_TYPE_STRUCT;
346
347 /*@-immediatetrans@*/
348 ts1_type.elements = ts1_type_elements;
349 ts2_type.elements = ts2_type_elements;
350 ts3_type.elements = ts3_type_elements;
351 ts4_type.elements = ts4_type_elements;
352 ts5_type.elements = ts5_type_elements;
353 ts6_type.elements = ts6_type_elements;
354 ts7_type.elements = ts7_type_elements;
355 ts8_type.elements = ts8_type_elements;
356 ts9_type.elements = ts9_type_elements;
357 /*@=immediatetrans@*/
358
359 ts1_type_elements[0] = &ffi_type_uchar;
360 ts1_type_elements[1] = &ffi_type_double;
361 ts1_type_elements[2] = &ffi_type_uint;
362 ts1_type_elements[3] = NULL;
363
364 ts2_type_elements[0] = &ffi_type_double;
365 ts2_type_elements[1] = &ffi_type_double;
366 ts2_type_elements[2] = NULL;
367
368 ts3_type_elements[0] = &ffi_type_sint;
369 ts3_type_elements[1] = NULL;
370
371 ts4_type_elements[0] = &ffi_type_uint;
372 ts4_type_elements[1] = &ffi_type_uint;
373 ts4_type_elements[2] = &ffi_type_uint;
374 ts4_type_elements[3] = NULL;
375
376 ts5_type_elements[0] = &ffi_type_schar;
377 ts5_type_elements[1] = &ffi_type_schar;
378 ts5_type_elements[2] = NULL;
379
380 ts6_type_elements[0] = &ffi_type_float;
381 ts6_type_elements[1] = &ffi_type_double;
382 ts6_type_elements[2] = NULL;
383
384 ts7_type_elements[0] = &ffi_type_float;
385 ts7_type_elements[1] = &ffi_type_float;
386 ts7_type_elements[2] = &ffi_type_double;
387 ts7_type_elements[3] = NULL;
388
389 ts8_type_elements[0] = &ffi_type_float;
390 ts8_type_elements[1] = &ffi_type_float;
391 ts8_type_elements[2] = &ffi_type_float;
392 ts8_type_elements[3] = &ffi_type_float;
393 ts8_type_elements[4] = NULL;
394
395 ts9_type_elements[0] = &ffi_type_float;
396 ts9_type_elements[1] = &ffi_type_sint;
397 ts9_type_elements[2] = NULL;
398
399 ul = 0;
400
401 /* return value tests */
402 {
403 #if defined(MIPS) /* || defined(ARM) */
404 puts ("long long tests not run. This is a known bug on this architecture.");
405 #else
406 args[0] = &ffi_type_sint64;
407 values[0] = &ll;
408
409 /* Initialize the cif */
410 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
411 &ffi_type_sint64, args) == FFI_OK);
412
413 for (ll = 0LL; ll < 100LL; ll++)
414 {
415 ul++;
416 ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
417 CHECK(rlonglong == ll);
418 }
419
420 for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
421 {
422 ul++;
423 ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
424 CHECK(rlonglong == ll);
425 }
426 #endif
427
428 args[0] = &ffi_type_schar;
429 values[0] = &sc;
430
431 /* Initialize the cif */
432 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
433 &ffi_type_schar, args) == FFI_OK);
434
435 for (sc = (signed char) -127;
436 sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/)
437 {
438 ul++;
439 ffi_call(&cif, FFI_FN(return_sc), &rint, values);
440 CHECK(rint == (ffi_arg) sc);
441 }
442
443 args[0] = &ffi_type_uchar;
444 values[0] = &uc;
445
446 /* Initialize the cif */
447 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
448 &ffi_type_uchar, args) == FFI_OK);
449
450 for (uc = (unsigned char) '\x00';
451 uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/)
452 {
453 ul++;
454 ffi_call(&cif, FFI_FN(return_uc), &rint, values);
455 CHECK(rint == (signed int) uc);
456 }
457
458 printf("%lu return value tests run\n", ul);
459 }
460
461 #ifdef BROKEN_LONG_DOUBLE
462 printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n");
463 #else
464 /* float arg tests */
465 {
466 args[0] = &ffi_type_float;
467 values[0] = &f;
468
469 /* Initialize the cif */
470 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
471 &ffi_type_longdouble, args) == FFI_OK);
472
473 f = 3.14159;
474
475 #if 0
476 /* This is ifdef'd out for now. long double support under SunOS/gcc
477 is pretty much non-existent. You'll get the odd bus error in library
478 routines like printf(). */
479 printf ("%Lf\n", ldblit(f));
480 #endif
481 ld = 666;
482 ffi_call(&cif, FFI_FN(ldblit), &ld, values);
483
484 #if 0
485 /* This is ifdef'd out for now. long double support under SunOS/gcc
486 is pretty much non-existent. You'll get the odd bus error in library
487 routines like printf(). */
488 printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
489 #endif
490
491 /* These are not always the same!! Check for a reasonable delta */
492 /*@-realcompare@*/
493 if (ld - ldblit(f) < LDBL_EPSILON)
494 /*@=realcompare@*/
495 puts("long double return value tests ok!");
496 else
497 CHECK(0);
498 }
499
500 /* float arg tests */
501 {
502 args[0] = &ffi_type_sint;
503 values[0] = &si1;
504 args[1] = &ffi_type_float;
505 values[1] = &f;
506 args[2] = &ffi_type_double;
507 values[2] = &d;
508 args[3] = &ffi_type_longdouble;
509 values[3] = &ld;
510 args[4] = &ffi_type_sint;
511 values[4] = &si2;
512
513 /* Initialize the cif */
514 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
515 &ffi_type_sint, args) == FFI_OK);
516
517 si1 = 6;
518 f = 3.14159;
519 d = (double)1.0/(double)3.0;
520 ld = 2.71828182846L;
521 si2 = 10;
522
523 floating (si1, f, d, ld, si2);
524
525 ffi_call(&cif, FFI_FN(floating), &rint, values);
526
527 printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));
528
529 CHECK(rint == floating(si1, f, d, ld, si2));
530
531 printf("float arg tests ok!\n");
532 }
533 #endif
534
535 /* strlen tests */
536 {
537 args[0] = &ffi_type_pointer;
538 values[0] = (void*) &s;
539
540 /* Initialize the cif */
541 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
542 &ffi_type_sint, args) == FFI_OK);
543
544 s = "a";
545 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
546 CHECK(rint == 1);
547
548 s = "1234567";
549 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
550 CHECK(rint == 7);
551
552 s = "1234567890123456789012345";
553 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
554 CHECK(rint == 25);
555
556 printf("strlen tests passed\n");
557 }
558
559 /* float arg tests */
560 {
561 args[0] = &ffi_type_float;
562 values[0] = &f;
563
564 /* Initialize the cif */
565 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
566 &ffi_type_double, args) == FFI_OK);
567
568 f = 3.14159;
569
570 ffi_call(&cif, FFI_FN(dblit), &d, values);
571
572 /* These are not always the same!! Check for a reasonable delta */
573 /*@-realcompare@*/
574 CHECK(d - dblit(f) < DBL_EPSILON);
575 /*@=realcompare@*/
576
577 printf("double return value tests ok!\n");
578 }
579
580 /* many arg tests */
581 {
582 float ff;
583 float fa[13];
584
585 for (ul = 0; ul < 13; ul++)
586 {
587 args[ul] = &ffi_type_float;
588 values[ul] = &fa[ul];
589 fa[ul] = (float) ul;
590 }
591
592 /* Initialize the cif */
593 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
594 &ffi_type_float, args) == FFI_OK);
595
596 /*@-usedef@*/
597 ff = many (fa[0], fa[1],
598 fa[2], fa[3],
599 fa[4], fa[5],
600 fa[6], fa[7],
601 fa[8], fa[9],
602 fa[10],fa[11],fa[12]);
603 /*@=usedef@*/
604
605 ffi_call(&cif, FFI_FN(many), &f, values);
606
607 /*@-realcompare@*/
608 if (f - ff < FLT_EPSILON)
609 /*@=realcompare@*/
610 printf("many arg tests ok!\n");
611 else
612 #ifdef POWERPC
613 printf("many arg tests failed! This is a gcc bug.\n");
614 #else
615 CHECK(0);
616 #endif
617 }
618
619 /* promotion tests */
620 {
621 args[0] = &ffi_type_schar;
622 args[1] = &ffi_type_sshort;
623 args[2] = &ffi_type_uchar;
624 args[3] = &ffi_type_ushort;
625 values[0] = &sc;
626 values[1] = &ss;
627 values[2] = &uc;
628 values[3] = &us;
629
630 /* Initialize the cif */
631 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
632 &ffi_type_sint, args) == FFI_OK);
633
634 us = 0;
635 ul = 0;
636
637 for (sc = (signed char) -127;
638 sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/)
639 for (ss = -30000; ss <= 30000; ss += 10000)
640 for (uc = (unsigned char) 0;
641 uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/)
642 for (us = 0; us <= 60000; us += 10000)
643 {
644 ul++;
645 ffi_call(&cif, FFI_FN(promotion), &rint, values);
646 CHECK((int)rint == (signed char) sc + (signed short) ss +
647 (unsigned char) uc + (unsigned short) us);
648 }
649 printf("%lu promotion tests run\n", ul);
650 }
651
652 #ifndef X86_WIN32 /* Structures dont work on Win32 */
653
654 /* struct tests */
655 {
656 test_structure_1 ts1_arg;
657 /* This is a hack to get a properly aligned result buffer */
658 test_structure_1 *ts1_result =
659 (test_structure_1 *) malloc (sizeof(test_structure_1));
660
661 args[0] = &ts1_type;
662 values[0] = &ts1_arg;
663
664 /* Initialize the cif */
665 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
666 &ts1_type, args) == FFI_OK);
667
668 ts1_arg.uc = '\x01';
669 ts1_arg.d = 3.14159;
670 ts1_arg.ui = 555;
671
672 ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
673
674 CHECK(ts1_result->ui == 556);
675 CHECK(ts1_result->d == 3.14159 - 1);
676
677 puts ("structure test 1 ok!\n");
678
679 free (ts1_result);
680 }
681
682 /* struct tests */
683 {
684 test_structure_2 ts2_arg;
685
686 /* This is a hack to get a properly aligned result buffer */
687 test_structure_2 *ts2_result =
688 (test_structure_2 *) malloc (sizeof(test_structure_2));
689
690 args[0] = &ts2_type;
691 values[0] = &ts2_arg;
692
693 /* Initialize the cif */
694 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
695
696 ts2_arg.d1 = 5.55;
697 ts2_arg.d2 = 6.66;
698
699 printf ("%g\n", ts2_result->d1);
700 printf ("%g\n", ts2_result->d2);
701
702 ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
703
704 printf ("%g\n", ts2_result->d1);
705 printf ("%g\n", ts2_result->d2);
706
707 CHECK(ts2_result->d1 == 5.55 - 1);
708 CHECK(ts2_result->d2 == 6.66 - 1);
709
710 printf("structure test 2 ok!\n");
711
712 free (ts2_result);
713 }
714
715 /* struct tests */
716 {
717 int compare_value;
718 test_structure_3 ts3_arg;
719 test_structure_3 *ts3_result =
720 (test_structure_3 *) malloc (sizeof(test_structure_3));
721
722 args[0] = &ts3_type;
723 values[0] = &ts3_arg;
724
725 /* Initialize the cif */
726 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
727 &ts3_type, args) == FFI_OK);
728
729 ts3_arg.si = -123;
730 compare_value = ts3_arg.si;
731
732 ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
733
734 printf ("%d %d\n", ts3_result->si, -(compare_value*2));
735
736 if (ts3_result->si == -(ts3_arg.si*2))
737 puts ("structure test 3 ok!");
738 else
739 {
740 puts ("Structure test 3 found structure passing bug.");
741 puts (" Current versions of GCC are not 100% compliant with the");
742 puts (" n32 ABI. There is a known problem related to passing");
743 puts (" small structures. Send a bug report to the gcc maintainers.");
744 }
745
746 free (ts3_result);
747 }
748
749 /* struct tests */
750 {
751 test_structure_4 ts4_arg;
752
753 /* This is a hack to get a properly aligned result buffer */
754 test_structure_4 *ts4_result =
755 (test_structure_4 *) malloc (sizeof(test_structure_4));
756
757 args[0] = &ts4_type;
758 values[0] = &ts4_arg;
759
760 /* Initialize the cif */
761 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
762
763 ts4_arg.ui1 = 2;
764 ts4_arg.ui2 = 3;
765 ts4_arg.ui3 = 4;
766
767 ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
768
769 if (ts4_result->ui3 == 2U * 3U * 4U)
770 puts ("structure test 4 ok!");
771 else
772 puts ("Structure test 4 found GCC's structure passing bug.");
773
774 free (ts4_result);
775 }
776
777 /* struct tests */
778 {
779 test_structure_5 ts5_arg1, ts5_arg2;
780
781 /* This is a hack to get a properly aligned result buffer */
782 test_structure_5 *ts5_result =
783 (test_structure_5 *) malloc (sizeof(test_structure_5));
784
785 args[0] = &ts5_type;
786 args[1] = &ts5_type;
787 values[0] = &ts5_arg1;
788 values[1] = &ts5_arg2;
789
790 /* Initialize the cif */
791 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
792
793 ts5_arg1.c1 = 2;
794 ts5_arg1.c2 = 6;
795 ts5_arg2.c1 = 5;
796 ts5_arg2.c2 = 3;
797
798 ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
799
800 if (ts5_result->c1 == 7
801 && ts5_result->c2 == 3)
802 puts ("structure test 5 ok!");
803 else
804 puts ("Structure test 5 found GCC's structure passing bug.");
805
806 free (ts5_result);
807 }
808
809 /* struct tests */
810 {
811 test_structure_6 ts6_arg;
812
813 /* This is a hack to get a properly aligned result buffer */
814 test_structure_6 *ts6_result =
815 (test_structure_6 *) malloc (sizeof(test_structure_6));
816
817 args[0] = &ts6_type;
818 values[0] = &ts6_arg;
819
820 /* Initialize the cif */
821 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
822
823 ts6_arg.f = 5.55f;
824 ts6_arg.d = 6.66;
825
826 printf ("%g\n", ts6_arg.f);
827 printf ("%g\n", ts6_arg.d);
828
829 ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
830
831 printf ("%g\n", ts6_result->f);
832 printf ("%g\n", ts6_result->d);
833
834 CHECK(ts6_result->f == 5.55f + 1);
835 CHECK(ts6_result->d == 6.66 + 1);
836
837 printf("structure test 6 ok!\n");
838
839 free (ts6_result);
840 }
841
842 /* struct tests */
843 {
844 test_structure_7 ts7_arg;
845
846 /* This is a hack to get a properly aligned result buffer */
847 test_structure_7 *ts7_result =
848 (test_structure_7 *) malloc (sizeof(test_structure_7));
849
850 args[0] = &ts7_type;
851 values[0] = &ts7_arg;
852
853 /* Initialize the cif */
854 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
855
856 ts7_arg.f1 = 5.55f;
857 ts7_arg.f2 = 55.5f;
858 ts7_arg.d = 6.66;
859
860 printf ("%g\n", ts7_arg.f1);
861 printf ("%g\n", ts7_arg.f2);
862 printf ("%g\n", ts7_arg.d);
863
864 ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
865
866 printf ("%g\n", ts7_result->f1);
867 printf ("%g\n", ts7_result->f2);
868 printf ("%g\n", ts7_result->d);
869
870 CHECK(ts7_result->f1 == 5.55f + 1);
871 CHECK(ts7_result->f2 == 55.5f + 1);
872 CHECK(ts7_result->d == 6.66 + 1);
873
874 printf("structure test 7 ok!\n");
875
876 free (ts7_result);
877 }
878
879 /* struct tests */
880 {
881 test_structure_8 ts8_arg;
882
883 /* This is a hack to get a properly aligned result buffer */
884 test_structure_8 *ts8_result =
885 (test_structure_8 *) malloc (sizeof(test_structure_8));
886
887 args[0] = &ts8_type;
888 values[0] = &ts8_arg;
889
890 /* Initialize the cif */
891 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
892
893 ts8_arg.f1 = 5.55f;
894 ts8_arg.f2 = 55.5f;
895 ts8_arg.f3 = -5.55f;
896 ts8_arg.f4 = -55.5f;
897
898 printf ("%g\n", ts8_arg.f1);
899 printf ("%g\n", ts8_arg.f2);
900 printf ("%g\n", ts8_arg.f3);
901 printf ("%g\n", ts8_arg.f4);
902
903 ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
904
905 printf ("%g\n", ts8_result->f1);
906 printf ("%g\n", ts8_result->f2);
907 printf ("%g\n", ts8_result->f3);
908 printf ("%g\n", ts8_result->f4);
909
910 CHECK(ts8_result->f1 == 5.55f + 1);
911 CHECK(ts8_result->f2 == 55.5f + 1);
912 CHECK(ts8_result->f3 == -5.55f + 1);
913 CHECK(ts8_result->f4 == -55.5f + 1);
914
915 printf("structure test 8 ok!\n");
916
917 free (ts8_result);
918 }
919
920 /* struct tests */
921 {
922 test_structure_9 ts9_arg;
923
924 /* This is a hack to get a properly aligned result buffer */
925 test_structure_9 *ts9_result =
926 (test_structure_9 *) malloc (sizeof(test_structure_9));
927
928 args[0] = &ts9_type;
929 values[0] = &ts9_arg;
930
931 /* Initialize the cif */
932 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
933
934 ts9_arg.f = 5.55f;
935 ts9_arg.i = 5;
936
937 printf ("%g\n", ts9_arg.f);
938 printf ("%d\n", ts9_arg.i);
939
940 ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
941
942 printf ("%g\n", ts9_result->f);
943 printf ("%d\n", ts9_result->i);
944
945 CHECK(ts9_result->f == 5.55f + 1);
946 CHECK(ts9_result->i == 5 + 1);
947
948 printf("structure test 9 ok!\n");
949
950 free (ts9_result);
951 }
952
953 #else
954 printf("Structure passing doesn't work on Win32.\n");
955 #endif /* X86_WIN32 */
956
957 # if FFI_CLOSURES
958 /* A simple closure test */
959 {
960 ffi_closure cl;
961 ffi_type * cl_arg_types[3];
962
963 cl_arg_types[0] = &ffi_type_sint;
964 cl_arg_types[1] = &ffi_type_float;
965 cl_arg_types[2] = NULL;
966
967 /* Initialize the cif */
968 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
969 &ffi_type_sint, cl_arg_types) == FFI_OK);
970
971 CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn,
972 (void *) 3 /* userdata */)
973 == FFI_OK);
974 CHECK((*((closure_test_type)(&cl)))(1, 2.0) == 6);
975 }
976 # endif
977
978 /* If we arrived here, all is good */
979 (void) puts("\nLooks good. No surprises.\n");
980
981 /*@-compdestroy@*/
982
983 return 0;
984 }
985