source: trunk/gcc/libffi/src/ffitest.c@ 2551

Last change on this file since 2551 was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 33.2 KB
Line 
1/* -----------------------------------------------------------------------
2 ffitest.c - Copyright (c) 1996, 1997, 1998, 2002, 2003 Red Hat, Inc.
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
37static 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
47static size_t my_strlen(char *s)
48{
49 return (strlen(s));
50}
51
52#ifdef X86_WIN32
53static size_t __attribute__((stdcall)) my_stdcall_strlen(char *s)
54{
55 return (strlen(s));
56}
57#endif /* X86_WIN32 */
58
59static int promotion(signed char sc, signed short ss,
60 unsigned char uc, unsigned short us)
61{
62 int r = (int) sc + (int) ss + (int) uc + (int) us;
63
64 return r;
65}
66
67static signed char return_sc(signed char sc)
68{
69 return sc;
70}
71
72static unsigned char return_uc(unsigned char uc)
73{
74 return uc;
75}
76
77static long long return_ll(long long ll)
78{
79 return ll;
80}
81
82static int floating(int a, float b, double c, long double d, int e)
83{
84 int i;
85
86#if 0
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);
91#endif
92
93 i = (int) ((float)a/b + ((float)c/(float)d));
94
95 return i;
96}
97
98static float many(float f1,
99 float f2,
100 float f3,
101 float f4,
102 float f5,
103 float f6,
104 float f7,
105 float f8,
106 float f9,
107 float f10,
108 float f11,
109 float f12,
110 float f13)
111{
112#if 0
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);
117#endif
118
119 return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
120}
121
122#ifdef X86_WIN32
123static float __attribute__((stdcall)) stdcall_many(float f1,
124 float f2,
125 float f3,
126 float f4,
127 float f5,
128 float f6,
129 float f7,
130 float f8,
131 float f9,
132 float f10,
133 float f11,
134 float f12,
135 float f13)
136{
137 return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
138}
139#endif /* X86_WIN32 */
140
141static double dblit(float f)
142{
143 return f/3.0;
144}
145
146static long double ldblit(float f)
147{
148 return (long double) (((long double) f)/ (long double) 3.0);
149}
150
151typedef struct
152{
153 unsigned char uc;
154 double d;
155 unsigned int ui;
156} test_structure_1;
157
158typedef struct
159{
160 double d1;
161 double d2;
162} test_structure_2;
163
164typedef struct
165{
166 int si;
167} test_structure_3;
168
169typedef struct
170{
171 unsigned ui1;
172 unsigned ui2;
173 unsigned ui3;
174} test_structure_4;
175
176typedef struct
177{
178 char c1;
179 char c2;
180} test_structure_5;
181
182typedef struct
183{
184 float f;
185 double d;
186} test_structure_6;
187
188typedef struct
189{
190 float f1;
191 float f2;
192 double d;
193} test_structure_7;
194
195typedef struct
196{
197 float f1;
198 float f2;
199 float f3;
200 float f4;
201} test_structure_8;
202
203typedef struct
204{
205 float f;
206 int i;
207} test_structure_9;
208
209static test_structure_1 struct1(test_structure_1 ts)
210{
211 /*@-type@*/
212 ts.uc++;
213 /*@=type@*/
214 ts.d--;
215 ts.ui++;
216
217 return ts;
218}
219
220static test_structure_2 struct2(test_structure_2 ts)
221{
222 ts.d1--;
223 ts.d2--;
224
225 return ts;
226}
227
228static test_structure_3 struct3(test_structure_3 ts)
229{
230 ts.si = -(ts.si*2);
231
232 return ts;
233}
234
235static test_structure_4 struct4(test_structure_4 ts)
236{
237 ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
238
239 return ts;
240}
241
242static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
243{
244 ts1.c1 += ts2.c1;
245 ts1.c2 -= ts2.c2;
246
247 return ts1;
248}
249
250static test_structure_6 struct6 (test_structure_6 ts)
251{
252 ts.f += 1;
253 ts.d += 1;
254
255 return ts;
256}
257
258static test_structure_7 struct7 (test_structure_7 ts)
259{
260 ts.f1 += 1;
261 ts.f2 += 1;
262 ts.d += 1;
263
264 return ts;
265}
266
267static test_structure_8 struct8 (test_structure_8 ts)
268{
269 ts.f1 += 1;
270 ts.f2 += 1;
271 ts.f3 += 1;
272 ts.f4 += 1;
273
274 return ts;
275}
276
277static test_structure_9 struct9 (test_structure_9 ts)
278{
279 ts.f += 1;
280 ts.i += 1;
281
282 return ts;
283}
284
285/* Take an int and a float argument, together with int userdata, and */
286/* return the sum. */
287#if FFI_CLOSURES
288static void
289closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata)
290{
291 *(ffi_arg*)resp =
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;
301
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);
313}
314
315typedef 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,
318 int, int);
319
320static void closure_test_fn1(ffi_cif* cif,void* resp,void** args,
321 void* userdata)
322 {
323 *(ffi_arg*)resp =
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;
332
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);
343}
344
345typedef int (*closure_test_type1)(float, float, float, float, signed short,
346 float, float, int, double, int, int, float,
347 int, int, int, int);
348
349static void closure_test_fn2(ffi_cif* cif,void* resp,void** args,
350 void* userdata)
351 {
352 *(ffi_arg*)resp =
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;
361
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,
371 *(int*)resp);
372 }
373
374typedef int (*closure_test_type2)(double, double, double, double, signed short,
375 double, double, int, double, int, int, float,
376 int, float, int, int);
377
378static void closure_test_fn3(ffi_cif* cif,void* resp,void** args,
379 void* userdata)
380 {
381 *(ffi_arg*)resp =
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;
390
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,
400 *(int*)resp);
401 }
402
403typedef int (*closure_test_type3)(float, float, float, float, float, float,
404 float, float, double, int, float, float, int,
405 float, float, int);
406#endif
407
408int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
409{
410 ffi_cif cif;
411 ffi_type *args[MAX_ARGS];
412 void *values[MAX_ARGS];
413 char *s;
414 signed char sc;
415 unsigned char uc;
416 signed short ss;
417 unsigned short us;
418 unsigned long ul;
419 long long ll;
420 float f;
421 double d;
422 long double ld;
423 signed int si1;
424 signed int si2;
425
426 ffi_arg rint;
427 long long rlonglong;
428
429# if FFI_CLOSURES
430 /* The closure must not be an automatic variable on
431 platforms (Solaris) that forbid stack execution by default. */
432 static ffi_closure cl;
433#endif
434
435 ffi_type * cl_arg_types[17];
436
437 ffi_type ts1_type;
438 ffi_type ts2_type;
439 ffi_type ts3_type;
440 ffi_type ts4_type;
441 ffi_type ts5_type;
442 ffi_type ts6_type;
443 ffi_type ts7_type;
444 ffi_type ts8_type;
445 ffi_type ts9_type;
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];
455
456 ts1_type.size = 0;
457 ts1_type.alignment = 0;
458 ts1_type.type = FFI_TYPE_STRUCT;
459
460 ts2_type.size = 0;
461 ts2_type.alignment = 0;
462 ts2_type.type = FFI_TYPE_STRUCT;
463
464 ts3_type.size = 0;
465 ts3_type.alignment = 0;
466 ts3_type.type = FFI_TYPE_STRUCT;
467
468 ts4_type.size = 0;
469 ts4_type.alignment = 0;
470 ts4_type.type = FFI_TYPE_STRUCT;
471
472 ts5_type.size = 0;
473 ts5_type.alignment = 0;
474 ts5_type.type = FFI_TYPE_STRUCT;
475
476 ts6_type.size = 0;
477 ts6_type.alignment = 0;
478 ts6_type.type = FFI_TYPE_STRUCT;
479
480 ts7_type.size = 0;
481 ts7_type.alignment = 0;
482 ts7_type.type = FFI_TYPE_STRUCT;
483
484 ts8_type.size = 0;
485 ts8_type.alignment = 0;
486 ts8_type.type = FFI_TYPE_STRUCT;
487
488 ts9_type.size = 0;
489 ts9_type.alignment = 0;
490 ts9_type.type = FFI_TYPE_STRUCT;
491
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@*/
503
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;
508
509 ts2_type_elements[0] = &ffi_type_double;
510 ts2_type_elements[1] = &ffi_type_double;
511 ts2_type_elements[2] = NULL;
512
513 ts3_type_elements[0] = &ffi_type_sint;
514 ts3_type_elements[1] = NULL;
515
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;
520
521 ts5_type_elements[0] = &ffi_type_schar;
522 ts5_type_elements[1] = &ffi_type_schar;
523 ts5_type_elements[2] = NULL;
524
525 ts6_type_elements[0] = &ffi_type_float;
526 ts6_type_elements[1] = &ffi_type_double;
527 ts6_type_elements[2] = NULL;
528
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;
533
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;
539
540 ts9_type_elements[0] = &ffi_type_float;
541 ts9_type_elements[1] = &ffi_type_sint;
542 ts9_type_elements[2] = NULL;
543
544 ul = 0;
545
546 /* return value tests */
547 {
548#if defined(MIPS) /* || defined(ARM) */
549 puts ("long long tests not run. This is a known bug on this architecture.");
550#else
551 args[0] = &ffi_type_sint64;
552 values[0] = &ll;
553
554 /* Initialize the cif */
555 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
556 &ffi_type_sint64, args) == FFI_OK);
557
558 for (ll = 0LL; ll < 100LL; ll++)
559 {
560 ul++;
561 ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
562 CHECK(rlonglong == ll);
563 }
564
565 for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
566 {
567 ul++;
568 ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
569 CHECK(rlonglong == ll);
570 }
571#endif
572
573 args[0] = &ffi_type_schar;
574 values[0] = &sc;
575
576 /* Initialize the cif */
577 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
578 &ffi_type_schar, args) == FFI_OK);
579
580 for (sc = (signed char) -127;
581 sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/)
582 {
583 ul++;
584 ffi_call(&cif, FFI_FN(return_sc), &rint, values);
585 CHECK(rint == (ffi_arg) sc);
586 }
587
588 args[0] = &ffi_type_uchar;
589 values[0] = &uc;
590
591 /* Initialize the cif */
592 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
593 &ffi_type_uchar, args) == FFI_OK);
594
595 for (uc = (unsigned char) '\x00';
596 uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/)
597 {
598 ul++;
599 ffi_call(&cif, FFI_FN(return_uc), &rint, values);
600 CHECK(rint == (signed int) uc);
601 }
602
603 printf("%lu return value tests run\n", ul);
604 }
605
606#ifdef BROKEN_LONG_DOUBLE
607 printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n");
608#else
609 /* float arg tests */
610 {
611 args[0] = &ffi_type_float;
612 values[0] = &f;
613
614 /* Initialize the cif */
615 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
616 &ffi_type_longdouble, args) == FFI_OK);
617
618 f = 3.14159;
619
620#if 0
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));
625#endif
626 ld = 666;
627 ffi_call(&cif, FFI_FN(ldblit), &ld, values);
628
629#if 0
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);
634#endif
635
636 /* These are not always the same!! Check for a reasonable delta */
637 /*@-realcompare@*/
638 if (ld - ldblit(f) < LDBL_EPSILON)
639 /*@=realcompare@*/
640 puts("long double return value tests ok!");
641 else
642 CHECK(0);
643 }
644
645 /* float arg tests */
646 {
647 args[0] = &ffi_type_sint;
648 values[0] = &si1;
649 args[1] = &ffi_type_float;
650 values[1] = &f;
651 args[2] = &ffi_type_double;
652 values[2] = &d;
653 args[3] = &ffi_type_longdouble;
654 values[3] = &ld;
655 args[4] = &ffi_type_sint;
656 values[4] = &si2;
657
658 /* Initialize the cif */
659 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
660 &ffi_type_sint, args) == FFI_OK);
661
662 si1 = 6;
663 f = 3.14159;
664 d = (double)1.0/(double)3.0;
665 ld = 2.71828182846L;
666 si2 = 10;
667
668 floating (si1, f, d, ld, si2);
669
670 ffi_call(&cif, FFI_FN(floating), &rint, values);
671
672 printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));
673
674 CHECK(rint == floating(si1, f, d, ld, si2));
675
676 printf("float arg tests ok!\n");
677 }
678#endif
679
680 /* strlen tests */
681 {
682 args[0] = &ffi_type_pointer;
683 values[0] = (void*) &s;
684
685 /* Initialize the cif */
686 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
687 &ffi_type_sint, args) == FFI_OK);
688
689 s = "a";
690 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
691 CHECK(rint == 1);
692
693 s = "1234567";
694 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
695 CHECK(rint == 7);
696
697 s = "1234567890123456789012345";
698 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
699 CHECK(rint == 25);
700
701 printf("strlen tests passed\n");
702 }
703
704 /* float arg tests */
705 {
706 args[0] = &ffi_type_float;
707 values[0] = &f;
708
709 /* Initialize the cif */
710 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
711 &ffi_type_double, args) == FFI_OK);
712
713 f = 3.14159;
714
715 ffi_call(&cif, FFI_FN(dblit), &d, values);
716
717 /* These are not always the same!! Check for a reasonable delta */
718 /*@-realcompare@*/
719 CHECK(d - dblit(f) < DBL_EPSILON);
720 /*@=realcompare@*/
721
722 printf("double return value tests ok!\n");
723 }
724
725 /* many arg tests */
726 {
727 float ff;
728 float fa[13];
729
730 for (ul = 0; ul < 13; ul++)
731 {
732 args[ul] = &ffi_type_float;
733 values[ul] = &fa[ul];
734 fa[ul] = (float) ul;
735 }
736
737 /* Initialize the cif */
738 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
739 &ffi_type_float, args) == FFI_OK);
740
741 /*@-usedef@*/
742 ff = many (fa[0], fa[1],
743 fa[2], fa[3],
744 fa[4], fa[5],
745 fa[6], fa[7],
746 fa[8], fa[9],
747 fa[10],fa[11],fa[12]);
748 /*@=usedef@*/
749
750 ffi_call(&cif, FFI_FN(many), &f, values);
751
752 /*@-realcompare@*/
753 if (f - ff < FLT_EPSILON)
754 /*@=realcompare@*/
755 printf("many arg tests ok!\n");
756 else
757#ifdef POWERPC
758 printf("many arg tests failed! This is a gcc bug.\n");
759#else
760 CHECK(0);
761#endif
762 }
763
764 /* promotion tests */
765 {
766 args[0] = &ffi_type_schar;
767 args[1] = &ffi_type_sshort;
768 args[2] = &ffi_type_uchar;
769 args[3] = &ffi_type_ushort;
770 values[0] = &sc;
771 values[1] = &ss;
772 values[2] = &uc;
773 values[3] = &us;
774
775 /* Initialize the cif */
776 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
777 &ffi_type_sint, args) == FFI_OK);
778
779 us = 0;
780 ul = 0;
781
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)
788 {
789 ul++;
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);
793 }
794 printf("%lu promotion tests run\n", ul);
795 }
796
797#ifndef X86_WIN32 /* Structures dont work on Win32 */
798
799 /* struct tests */
800 {
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));
805
806 args[0] = &ts1_type;
807 values[0] = &ts1_arg;
808
809 /* Initialize the cif */
810 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
811 &ts1_type, args) == FFI_OK);
812
813 ts1_arg.uc = '\x01';
814 ts1_arg.d = 3.14159;
815 ts1_arg.ui = 555;
816
817 ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
818
819 CHECK(ts1_result->ui == 556);
820 CHECK(ts1_result->d == 3.14159 - 1);
821
822 puts ("structure test 1 ok!\n");
823
824 free (ts1_result);
825 }
826
827 /* struct tests */
828 {
829 test_structure_2 ts2_arg;
830
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));
834
835 args[0] = &ts2_type;
836 values[0] = &ts2_arg;
837
838 /* Initialize the cif */
839 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
840
841 ts2_arg.d1 = 5.55;
842 ts2_arg.d2 = 6.66;
843
844 printf ("%g\n", ts2_result->d1);
845 printf ("%g\n", ts2_result->d2);
846
847 ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
848
849 printf ("%g\n", ts2_result->d1);
850 printf ("%g\n", ts2_result->d2);
851
852 CHECK(ts2_result->d1 == 5.55 - 1);
853 CHECK(ts2_result->d2 == 6.66 - 1);
854
855 printf("structure test 2 ok!\n");
856
857 free (ts2_result);
858 }
859
860 /* struct tests */
861 {
862 int compare_value;
863 test_structure_3 ts3_arg;
864 test_structure_3 *ts3_result =
865 (test_structure_3 *) malloc (sizeof(test_structure_3));
866
867 args[0] = &ts3_type;
868 values[0] = &ts3_arg;
869
870 /* Initialize the cif */
871 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
872 &ts3_type, args) == FFI_OK);
873
874 ts3_arg.si = -123;
875 compare_value = ts3_arg.si;
876
877 ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
878
879 printf ("%d %d\n", ts3_result->si, -(compare_value*2));
880
881 if (ts3_result->si == -(ts3_arg.si*2))
882 puts ("structure test 3 ok!");
883 else
884 {
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.");
889 }
890
891 free (ts3_result);
892 }
893
894 /* struct tests */
895 {
896 test_structure_4 ts4_arg;
897
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));
901
902 args[0] = &ts4_type;
903 values[0] = &ts4_arg;
904
905 /* Initialize the cif */
906 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
907
908 ts4_arg.ui1 = 2;
909 ts4_arg.ui2 = 3;
910 ts4_arg.ui3 = 4;
911
912 ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
913
914 if (ts4_result->ui3 == 2U * 3U * 4U)
915 puts ("structure test 4 ok!");
916 else
917 puts ("Structure test 4 found GCC's structure passing bug.");
918
919 free (ts4_result);
920 }
921
922 /* struct tests */
923 {
924 test_structure_5 ts5_arg1, ts5_arg2;
925
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));
929
930 args[0] = &ts5_type;
931 args[1] = &ts5_type;
932 values[0] = &ts5_arg1;
933 values[1] = &ts5_arg2;
934
935 /* Initialize the cif */
936 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
937
938 ts5_arg1.c1 = 2;
939 ts5_arg1.c2 = 6;
940 ts5_arg2.c1 = 5;
941 ts5_arg2.c2 = 3;
942
943 ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
944
945 if (ts5_result->c1 == 7
946 && ts5_result->c2 == 3)
947 puts ("structure test 5 ok!");
948 else
949 puts ("Structure test 5 found GCC's structure passing bug.");
950
951 free (ts5_result);
952 }
953
954 /* struct tests */
955 {
956 test_structure_6 ts6_arg;
957
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));
961
962 args[0] = &ts6_type;
963 values[0] = &ts6_arg;
964
965 /* Initialize the cif */
966 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
967
968 ts6_arg.f = 5.55f;
969 ts6_arg.d = 6.66;
970
971 printf ("%g\n", ts6_arg.f);
972 printf ("%g\n", ts6_arg.d);
973
974 ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
975
976 printf ("%g\n", ts6_result->f);
977 printf ("%g\n", ts6_result->d);
978
979 CHECK(ts6_result->f == 5.55f + 1);
980 CHECK(ts6_result->d == 6.66 + 1);
981
982 printf("structure test 6 ok!\n");
983
984 free (ts6_result);
985 }
986
987 /* struct tests */
988 {
989 test_structure_7 ts7_arg;
990
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));
994
995 args[0] = &ts7_type;
996 values[0] = &ts7_arg;
997
998 /* Initialize the cif */
999 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
1000
1001 ts7_arg.f1 = 5.55f;
1002 ts7_arg.f2 = 55.5f;
1003 ts7_arg.d = 6.66;
1004
1005 printf ("%g\n", ts7_arg.f1);
1006 printf ("%g\n", ts7_arg.f2);
1007 printf ("%g\n", ts7_arg.d);
1008
1009 ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
1010
1011 printf ("%g\n", ts7_result->f1);
1012 printf ("%g\n", ts7_result->f2);
1013 printf ("%g\n", ts7_result->d);
1014
1015 CHECK(ts7_result->f1 == 5.55f + 1);
1016 CHECK(ts7_result->f2 == 55.5f + 1);
1017 CHECK(ts7_result->d == 6.66 + 1);
1018
1019 printf("structure test 7 ok!\n");
1020
1021 free (ts7_result);
1022 }
1023
1024 /* struct tests */
1025 {
1026 test_structure_8 ts8_arg;
1027
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));
1031
1032 args[0] = &ts8_type;
1033 values[0] = &ts8_arg;
1034
1035 /* Initialize the cif */
1036 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
1037
1038 ts8_arg.f1 = 5.55f;
1039 ts8_arg.f2 = 55.5f;
1040 ts8_arg.f3 = -5.55f;
1041 ts8_arg.f4 = -55.5f;
1042
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);
1047
1048 ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
1049
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);
1054
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);
1059
1060 printf("structure test 8 ok!\n");
1061
1062 free (ts8_result);
1063 }
1064
1065 /* struct tests */
1066 {
1067 test_structure_9 ts9_arg;
1068
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));
1072
1073 args[0] = &ts9_type;
1074 values[0] = &ts9_arg;
1075
1076 /* Initialize the cif */
1077 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
1078
1079 ts9_arg.f = 5.55f;
1080 ts9_arg.i = 5;
1081
1082 printf ("%g\n", ts9_arg.f);
1083 printf ("%d\n", ts9_arg.i);
1084
1085 ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
1086
1087 printf ("%g\n", ts9_result->f);
1088 printf ("%d\n", ts9_result->i);
1089
1090 CHECK(ts9_result->f == 5.55f + 1);
1091 CHECK(ts9_result->i == 5 + 1);
1092
1093 printf("structure test 9 ok!\n");
1094
1095 free (ts9_result);
1096 }
1097
1098#else
1099 printf("Structure passing doesn't work on Win32.\n");
1100#endif /* X86_WIN32 */
1101
1102#ifdef X86_WIN32
1103 /* stdcall strlen tests */
1104 {
1105 args[0] = &ffi_type_pointer;
1106 values[0] = (void*) &s;
1107
1108 /* Initialize the cif */
1109 CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 1,
1110 &ffi_type_sint, args) == FFI_OK);
1111
1112 s = "a";
1113 ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1114 CHECK(rint == 1);
1115
1116 s = "1234567";
1117 ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1118 CHECK(rint == 7);
1119
1120 s = "1234567890123456789012345";
1121 ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1122 CHECK(rint == 25);
1123
1124 printf("stdcall strlen tests passed\n");
1125 }
1126
1127 /* stdcall many arg tests */
1128 {
1129 float ff;
1130 float fa[13];
1131
1132 for (ul = 0; ul < 13; ul++)
1133 {
1134 args[ul] = &ffi_type_float;
1135 values[ul] = &fa[ul];
1136 fa[ul] = (float) ul;
1137 }
1138
1139 /* Initialize the cif */
1140 CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13,
1141 &ffi_type_float, args) == FFI_OK);
1142
1143 /*@-usedef@*/
1144 ff = stdcall_many(fa[0], fa[1],
1145 fa[2], fa[3],
1146 fa[4], fa[5],
1147 fa[6], fa[7],
1148 fa[8], fa[9],
1149 fa[10],fa[11],fa[12]);
1150 /*@=usedef@*/
1151
1152 ffi_call(&cif, FFI_FN(stdcall_many), &f, values);
1153
1154 /*@-realcompare@*/
1155 if (f - ff < FLT_EPSILON)
1156 /*@=realcompare@*/
1157 printf("stdcall many arg tests ok!\n");
1158 else
1159 CHECK(0);
1160 }
1161#endif /* X86_WIN32 */
1162
1163# if FFI_CLOSURES
1164 /* A simple closure test */
1165 {
1166 (void) puts("\nEnter FFI_CLOSURES\n");
1167
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;
1185
1186 /* Initialize the cif */
1187 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1188 &ffi_type_sint, cl_arg_types) == FFI_OK);
1189
1190 CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn,
1191 (void *) 3 /* userdata */) == FFI_OK);
1192
1193 CHECK((*((closure_test_type)(&cl)))
1194 (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
1195 19, 21, 1) == 680);
1196 }
1197
1198 {
1199
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;
1217
1218 /* Initialize the cif */
1219 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1220 &ffi_type_sint, cl_arg_types) == FFI_OK);
1221
1222 CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn1,
1223 (void *) 3 /* userdata */) == FFI_OK);
1224
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,
1227 19, 21, 1) == 255);
1228 }
1229
1230 {
1231
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;
1249
1250 /* Initialize the cif */
1251 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1252 &ffi_type_sint, cl_arg_types) == FFI_OK);
1253
1254 CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn2,
1255 (void *) 3 /* userdata */) == FFI_OK);
1256
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);
1260
1261 }
1262
1263 {
1264
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;
1282
1283 /* Initialize the cif */
1284 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1285 &ffi_type_sint, cl_arg_types) == FFI_OK);
1286
1287 CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn3,
1288 (void *) 3 /* userdata */) == FFI_OK);
1289
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);
1293 }
1294
1295 (void) puts("\nFinished FFI_CLOSURES\n");
1296
1297# endif
1298
1299 /* If we arrived here, all is good */
1300 (void) puts("\nLooks good. No surprises.\n");
1301
1302 /*@-compdestroy@*/
1303
1304 return 0;
1305}
1306
Note: See TracBrowser for help on using the repository browser.