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 |
|
---|
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 | #ifdef X86_WIN32
|
---|
53 | static size_t __attribute__((stdcall)) my_stdcall_strlen(char *s)
|
---|
54 | {
|
---|
55 | return (strlen(s));
|
---|
56 | }
|
---|
57 | #endif /* X86_WIN32 */
|
---|
58 |
|
---|
59 | static 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 |
|
---|
67 | static signed char return_sc(signed char sc)
|
---|
68 | {
|
---|
69 | return sc;
|
---|
70 | }
|
---|
71 |
|
---|
72 | static unsigned char return_uc(unsigned char uc)
|
---|
73 | {
|
---|
74 | return uc;
|
---|
75 | }
|
---|
76 |
|
---|
77 | static long long return_ll(long long ll)
|
---|
78 | {
|
---|
79 | return ll;
|
---|
80 | }
|
---|
81 |
|
---|
82 | static 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 |
|
---|
98 | static 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
|
---|
123 | static 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 |
|
---|
141 | static double dblit(float f)
|
---|
142 | {
|
---|
143 | return f/3.0;
|
---|
144 | }
|
---|
145 |
|
---|
146 | static long double ldblit(float f)
|
---|
147 | {
|
---|
148 | return (long double) (((long double) f)/ (long double) 3.0);
|
---|
149 | }
|
---|
150 |
|
---|
151 | typedef struct
|
---|
152 | {
|
---|
153 | unsigned char uc;
|
---|
154 | double d;
|
---|
155 | unsigned int ui;
|
---|
156 | } test_structure_1;
|
---|
157 |
|
---|
158 | typedef struct
|
---|
159 | {
|
---|
160 | double d1;
|
---|
161 | double d2;
|
---|
162 | } test_structure_2;
|
---|
163 |
|
---|
164 | typedef struct
|
---|
165 | {
|
---|
166 | int si;
|
---|
167 | } test_structure_3;
|
---|
168 |
|
---|
169 | typedef struct
|
---|
170 | {
|
---|
171 | unsigned ui1;
|
---|
172 | unsigned ui2;
|
---|
173 | unsigned ui3;
|
---|
174 | } test_structure_4;
|
---|
175 |
|
---|
176 | typedef struct
|
---|
177 | {
|
---|
178 | char c1;
|
---|
179 | char c2;
|
---|
180 | } test_structure_5;
|
---|
181 |
|
---|
182 | typedef struct
|
---|
183 | {
|
---|
184 | float f;
|
---|
185 | double d;
|
---|
186 | } test_structure_6;
|
---|
187 |
|
---|
188 | typedef struct
|
---|
189 | {
|
---|
190 | float f1;
|
---|
191 | float f2;
|
---|
192 | double d;
|
---|
193 | } test_structure_7;
|
---|
194 |
|
---|
195 | typedef struct
|
---|
196 | {
|
---|
197 | float f1;
|
---|
198 | float f2;
|
---|
199 | float f3;
|
---|
200 | float f4;
|
---|
201 | } test_structure_8;
|
---|
202 |
|
---|
203 | typedef struct
|
---|
204 | {
|
---|
205 | float f;
|
---|
206 | int i;
|
---|
207 | } test_structure_9;
|
---|
208 |
|
---|
209 | static 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 |
|
---|
220 | static test_structure_2 struct2(test_structure_2 ts)
|
---|
221 | {
|
---|
222 | ts.d1--;
|
---|
223 | ts.d2--;
|
---|
224 |
|
---|
225 | return ts;
|
---|
226 | }
|
---|
227 |
|
---|
228 | static test_structure_3 struct3(test_structure_3 ts)
|
---|
229 | {
|
---|
230 | ts.si = -(ts.si*2);
|
---|
231 |
|
---|
232 | return ts;
|
---|
233 | }
|
---|
234 |
|
---|
235 | static test_structure_4 struct4(test_structure_4 ts)
|
---|
236 | {
|
---|
237 | ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
|
---|
238 |
|
---|
239 | return ts;
|
---|
240 | }
|
---|
241 |
|
---|
242 | static 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 |
|
---|
250 | static test_structure_6 struct6 (test_structure_6 ts)
|
---|
251 | {
|
---|
252 | ts.f += 1;
|
---|
253 | ts.d += 1;
|
---|
254 |
|
---|
255 | return ts;
|
---|
256 | }
|
---|
257 |
|
---|
258 | static 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 |
|
---|
267 | static 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 |
|
---|
277 | static 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
|
---|
288 | static void
|
---|
289 | closure_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 |
|
---|
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,
|
---|
318 | int, int);
|
---|
319 |
|
---|
320 | static 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 |
|
---|
345 | typedef int (*closure_test_type1)(float, float, float, float, signed short,
|
---|
346 | float, float, int, double, int, int, float,
|
---|
347 | int, int, int, int);
|
---|
348 |
|
---|
349 | static 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 |
|
---|
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);
|
---|
377 |
|
---|
378 | static 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 |
|
---|
403 | typedef 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 |
|
---|
408 | int 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] = ≪
|
---|
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] = ≻
|
---|
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] = ≻
|
---|
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 |
|
---|