~ubuntu-branches/ubuntu/lucid/gauche-c-wrapper/lucid

« back to all changes in this revision

Viewing changes to libffi/src/ffitest.c

  • Committer: Bazaar Package Importer
  • Author(s): NIIBE Yutaka
  • Date: 2008-04-07 09:15:03 UTC
  • Revision ID: james.westby@ubuntu.com-20080407091503-wu0h414koe95kj4i
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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)*(ffi_arg *)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)*(ffi_arg *)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)*(ffi_arg *)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)*(ffi_arg *)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
  ffi_closure *pcl = &cl;
 
434
#endif
 
435
 
 
436
  ffi_type * cl_arg_types[17];
 
437
 
 
438
  ffi_type ts1_type;
 
439
  ffi_type ts2_type;
 
440
  ffi_type ts3_type;
 
441
  ffi_type ts4_type;  
 
442
  ffi_type ts5_type;
 
443
  ffi_type ts6_type;
 
444
  ffi_type ts7_type;
 
445
  ffi_type ts8_type;
 
446
  ffi_type ts9_type;
 
447
  ffi_type *ts1_type_elements[4];
 
448
  ffi_type *ts2_type_elements[3];
 
449
  ffi_type *ts3_type_elements[2];
 
450
  ffi_type *ts4_type_elements[4];
 
451
  ffi_type *ts5_type_elements[3];
 
452
  ffi_type *ts6_type_elements[3];
 
453
  ffi_type *ts7_type_elements[4];
 
454
  ffi_type *ts8_type_elements[5];
 
455
  ffi_type *ts9_type_elements[3];
 
456
 
 
457
  ts1_type.size = 0;
 
458
  ts1_type.alignment = 0;
 
459
  ts1_type.type = FFI_TYPE_STRUCT;
 
460
 
 
461
  ts2_type.size = 0;
 
462
  ts2_type.alignment = 0;
 
463
  ts2_type.type = FFI_TYPE_STRUCT;
 
464
 
 
465
  ts3_type.size = 0;
 
466
  ts3_type.alignment = 0;
 
467
  ts3_type.type = FFI_TYPE_STRUCT;
 
468
 
 
469
  ts4_type.size = 0;
 
470
  ts4_type.alignment = 0;
 
471
  ts4_type.type = FFI_TYPE_STRUCT;
 
472
 
 
473
  ts5_type.size = 0;
 
474
  ts5_type.alignment = 0;
 
475
  ts5_type.type = FFI_TYPE_STRUCT;
 
476
 
 
477
  ts6_type.size = 0;
 
478
  ts6_type.alignment = 0;
 
479
  ts6_type.type = FFI_TYPE_STRUCT;
 
480
 
 
481
  ts7_type.size = 0;
 
482
  ts7_type.alignment = 0;
 
483
  ts7_type.type = FFI_TYPE_STRUCT;
 
484
 
 
485
  ts8_type.size = 0;
 
486
  ts8_type.alignment = 0;
 
487
  ts8_type.type = FFI_TYPE_STRUCT;
 
488
 
 
489
  ts9_type.size = 0;
 
490
  ts9_type.alignment = 0;
 
491
  ts9_type.type = FFI_TYPE_STRUCT;
 
492
 
 
493
  /*@-immediatetrans@*/
 
494
  ts1_type.elements = ts1_type_elements;
 
495
  ts2_type.elements = ts2_type_elements;
 
496
  ts3_type.elements = ts3_type_elements;
 
497
  ts4_type.elements = ts4_type_elements;
 
498
  ts5_type.elements = ts5_type_elements;
 
499
  ts6_type.elements = ts6_type_elements;
 
500
  ts7_type.elements = ts7_type_elements;
 
501
  ts8_type.elements = ts8_type_elements;
 
502
  ts9_type.elements = ts9_type_elements;
 
503
  /*@=immediatetrans@*/
 
504
  
 
505
  ts1_type_elements[0] = &ffi_type_uchar;
 
506
  ts1_type_elements[1] = &ffi_type_double;
 
507
  ts1_type_elements[2] = &ffi_type_uint;
 
508
  ts1_type_elements[3] = NULL;
 
509
  
 
510
  ts2_type_elements[0] = &ffi_type_double;
 
511
  ts2_type_elements[1] = &ffi_type_double;
 
512
  ts2_type_elements[2] = NULL;
 
513
 
 
514
  ts3_type_elements[0] = &ffi_type_sint;
 
515
  ts3_type_elements[1] = NULL;
 
516
 
 
517
  ts4_type_elements[0] = &ffi_type_uint;
 
518
  ts4_type_elements[1] = &ffi_type_uint;
 
519
  ts4_type_elements[2] = &ffi_type_uint;
 
520
  ts4_type_elements[3] = NULL;
 
521
 
 
522
  ts5_type_elements[0] = &ffi_type_schar;
 
523
  ts5_type_elements[1] = &ffi_type_schar;
 
524
  ts5_type_elements[2] = NULL;
 
525
 
 
526
  ts6_type_elements[0] = &ffi_type_float;
 
527
  ts6_type_elements[1] = &ffi_type_double;
 
528
  ts6_type_elements[2] = NULL;
 
529
 
 
530
  ts7_type_elements[0] = &ffi_type_float;
 
531
  ts7_type_elements[1] = &ffi_type_float;
 
532
  ts7_type_elements[2] = &ffi_type_double;
 
533
  ts7_type_elements[3] = NULL;
 
534
 
 
535
  ts8_type_elements[0] = &ffi_type_float;
 
536
  ts8_type_elements[1] = &ffi_type_float;
 
537
  ts8_type_elements[2] = &ffi_type_float;
 
538
  ts8_type_elements[3] = &ffi_type_float;
 
539
  ts8_type_elements[4] = NULL;
 
540
 
 
541
  ts9_type_elements[0] = &ffi_type_float;
 
542
  ts9_type_elements[1] = &ffi_type_sint;
 
543
  ts9_type_elements[2] = NULL;
 
544
 
 
545
  ul = 0;
 
546
 
 
547
  /* return value tests */
 
548
  {
 
549
#if defined(MIPS) /* || defined(ARM) */
 
550
    puts ("long long tests not run. This is a known bug on this architecture.");
 
551
#else
 
552
    args[0] = &ffi_type_sint64;
 
553
    values[0] = &ll;
 
554
    
 
555
    /* Initialize the cif */
 
556
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
 
557
                       &ffi_type_sint64, args) == FFI_OK);
 
558
 
 
559
    for (ll = 0LL; ll < 100LL; ll++)
 
560
      {
 
561
        ul++;
 
562
        ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
 
563
        CHECK(rlonglong == ll);
 
564
      }
 
565
 
 
566
    for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
 
567
      {
 
568
        ul++;
 
569
        ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
 
570
        CHECK(rlonglong == ll);
 
571
      }
 
572
#endif
 
573
 
 
574
    args[0] = &ffi_type_schar;
 
575
    values[0] = &sc;
 
576
    
 
577
    /* Initialize the cif */
 
578
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
 
579
                       &ffi_type_schar, args) == FFI_OK);
 
580
 
 
581
    for (sc = (signed char) -127; 
 
582
         sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/)
 
583
      {
 
584
        ul++;
 
585
        ffi_call(&cif, FFI_FN(return_sc), &rint, values);
 
586
        CHECK(rint == (ffi_arg) sc);
 
587
      }
 
588
 
 
589
    args[0] = &ffi_type_uchar;
 
590
    values[0] = &uc;
 
591
    
 
592
    /* Initialize the cif */
 
593
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
 
594
                       &ffi_type_uchar, args) == FFI_OK);
 
595
 
 
596
    for (uc = (unsigned char) '\x00'; 
 
597
         uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/)
 
598
      {
 
599
        ul++;
 
600
        ffi_call(&cif, FFI_FN(return_uc), &rint, values);
 
601
        CHECK(rint == (signed int) uc);
 
602
      }
 
603
 
 
604
    printf("%lu return value tests run\n", ul);
 
605
  }
 
606
 
 
607
#ifdef BROKEN_LONG_DOUBLE
 
608
  printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n");
 
609
#else
 
610
  /* float arg tests */
 
611
  {
 
612
    args[0] = &ffi_type_float;
 
613
    values[0] = &f;
 
614
 
 
615
    /* Initialize the cif */
 
616
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
 
617
                       &ffi_type_longdouble, args) == FFI_OK);
 
618
 
 
619
    f = 3.14159;
 
620
 
 
621
#if 0
 
622
  /* This is ifdef'd out for now. long double support under SunOS/gcc
 
623
     is pretty much non-existent.  You'll get the odd bus error in library
 
624
     routines like printf().  */
 
625
    printf ("%Lf\n", ldblit(f));
 
626
#endif
 
627
    ld = 666;
 
628
    ffi_call(&cif, FFI_FN(ldblit), &ld, values);
 
629
 
 
630
#if 0
 
631
  /* This is ifdef'd out for now. long double support under SunOS/gcc
 
632
     is pretty much non-existent.  You'll get the odd bus error in library
 
633
     routines like printf().  */
 
634
    printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
 
635
#endif
 
636
 
 
637
    /* These are not always the same!! Check for a reasonable delta */
 
638
    /*@-realcompare@*/
 
639
    if (ld - ldblit(f) < LDBL_EPSILON)
 
640
    /*@=realcompare@*/
 
641
        puts("long double return value tests ok!");
 
642
    else
 
643
        CHECK(0);
 
644
  }
 
645
 
 
646
  /* float arg tests */
 
647
  {
 
648
    args[0] = &ffi_type_sint;
 
649
    values[0] = &si1;
 
650
    args[1] = &ffi_type_float;
 
651
    values[1] = &f;
 
652
    args[2] = &ffi_type_double;
 
653
    values[2] = &d;
 
654
    args[3] = &ffi_type_longdouble;
 
655
    values[3] = &ld;
 
656
    args[4] = &ffi_type_sint;
 
657
    values[4] = &si2;
 
658
    
 
659
    /* Initialize the cif */
 
660
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
 
661
                       &ffi_type_sint, args) == FFI_OK);
 
662
 
 
663
    si1 = 6;
 
664
    f = 3.14159;
 
665
    d = (double)1.0/(double)3.0;
 
666
    ld = 2.71828182846L;
 
667
    si2 = 10;
 
668
 
 
669
    floating (si1, f, d, ld, si2);
 
670
 
 
671
    ffi_call(&cif, FFI_FN(floating), &rint, values);
 
672
 
 
673
    printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));
 
674
 
 
675
    CHECK(rint == floating(si1, f, d, ld, si2));
 
676
 
 
677
    printf("float arg tests ok!\n");
 
678
  }
 
679
#endif
 
680
 
 
681
  /* strlen tests */
 
682
  {
 
683
    args[0] = &ffi_type_pointer;
 
684
    values[0] = (void*) &s;
 
685
    
 
686
    /* Initialize the cif */
 
687
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
 
688
                       &ffi_type_sint, args) == FFI_OK);
 
689
 
 
690
    s = "a";
 
691
    ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
 
692
    CHECK(rint == 1);
 
693
 
 
694
    s = "1234567";
 
695
    ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
 
696
    CHECK(rint == 7);
 
697
 
 
698
    s = "1234567890123456789012345";
 
699
    ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
 
700
    CHECK(rint == 25);
 
701
 
 
702
    printf("strlen tests passed\n");
 
703
  }
 
704
 
 
705
  /* float arg tests */
 
706
  {
 
707
    args[0] = &ffi_type_float;
 
708
    values[0] = &f;
 
709
    
 
710
    /* Initialize the cif */
 
711
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
 
712
                       &ffi_type_double, args) == FFI_OK);
 
713
 
 
714
    f = 3.14159;
 
715
 
 
716
    ffi_call(&cif, FFI_FN(dblit), &d, values);
 
717
 
 
718
    /* These are not always the same!! Check for a reasonable delta */
 
719
    /*@-realcompare@*/
 
720
    CHECK(d - dblit(f) < DBL_EPSILON);
 
721
    /*@=realcompare@*/
 
722
 
 
723
    printf("double return value tests ok!\n");
 
724
  }
 
725
 
 
726
  /* many arg tests */
 
727
  {
 
728
    float ff;
 
729
    float fa[13];
 
730
    
 
731
    for (ul = 0; ul < 13; ul++)
 
732
      {
 
733
        args[ul] = &ffi_type_float;
 
734
        values[ul] = &fa[ul];
 
735
        fa[ul] = (float) ul;
 
736
      }
 
737
 
 
738
    /* Initialize the cif */
 
739
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, 
 
740
                       &ffi_type_float, args) == FFI_OK);
 
741
 
 
742
    /*@-usedef@*/
 
743
    ff = many (fa[0], fa[1],
 
744
               fa[2], fa[3],
 
745
               fa[4], fa[5],
 
746
               fa[6], fa[7],
 
747
               fa[8], fa[9],
 
748
               fa[10],fa[11],fa[12]);
 
749
    /*@=usedef@*/
 
750
 
 
751
    ffi_call(&cif, FFI_FN(many), &f, values);
 
752
 
 
753
    /*@-realcompare@*/
 
754
    if (f - ff < FLT_EPSILON)
 
755
    /*@=realcompare@*/
 
756
        printf("many arg tests ok!\n");
 
757
    else
 
758
#ifdef POWERPC
 
759
        printf("many arg tests failed!  This is a gcc bug.\n");
 
760
#else
 
761
        CHECK(0);
 
762
#endif
 
763
  }
 
764
 
 
765
  /* promotion tests */
 
766
  {
 
767
    args[0] = &ffi_type_schar;
 
768
    args[1] = &ffi_type_sshort;
 
769
    args[2] = &ffi_type_uchar;
 
770
    args[3] = &ffi_type_ushort;
 
771
    values[0] = &sc;
 
772
    values[1] = &ss;
 
773
    values[2] = &uc;
 
774
    values[3] = &us;
 
775
    
 
776
    /* Initialize the cif */
 
777
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 
 
778
                       &ffi_type_sint, args) == FFI_OK);
 
779
 
 
780
    us = 0;
 
781
    ul = 0;
 
782
 
 
783
    for (sc = (signed char) -127; 
 
784
         sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/)
 
785
      for (ss = -30000; ss <= 30000; ss += 10000)
 
786
        for (uc = (unsigned char) 0; 
 
787
             uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/)
 
788
          for (us = 0; us <= 60000; us += 10000)
 
789
            {
 
790
              ul++;
 
791
              ffi_call(&cif, FFI_FN(promotion), &rint, values);
 
792
              CHECK((int)rint == (signed char) sc + (signed short) ss +
 
793
                    (unsigned char) uc + (unsigned short) us);
 
794
            }
 
795
    printf("%lu promotion tests run\n", ul);
 
796
  }
 
797
 
 
798
#ifndef X86_WIN32 /* Structures dont work on Win32 */
 
799
 
 
800
  /* struct tests */
 
801
  {
 
802
    test_structure_1 ts1_arg;
 
803
    /* This is a hack to get a properly aligned result buffer */
 
804
    test_structure_1 *ts1_result = 
 
805
      (test_structure_1 *) malloc (sizeof(test_structure_1));
 
806
 
 
807
    args[0] = &ts1_type;
 
808
    values[0] = &ts1_arg;
 
809
    
 
810
    /* Initialize the cif */
 
811
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
 
812
                       &ts1_type, args) == FFI_OK);
 
813
 
 
814
    ts1_arg.uc = '\x01';
 
815
    ts1_arg.d = 3.14159;
 
816
    ts1_arg.ui = 555;
 
817
 
 
818
    ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
 
819
 
 
820
    CHECK(ts1_result->ui == 556);
 
821
    CHECK(ts1_result->d == 3.14159 - 1);
 
822
 
 
823
    puts ("structure test 1 ok!\n");
 
824
 
 
825
    free (ts1_result);
 
826
  }
 
827
 
 
828
  /* struct tests */
 
829
  {
 
830
    test_structure_2 ts2_arg;
 
831
 
 
832
    /* This is a hack to get a properly aligned result buffer */
 
833
    test_structure_2 *ts2_result = 
 
834
      (test_structure_2 *) malloc (sizeof(test_structure_2));
 
835
 
 
836
    args[0] = &ts2_type;
 
837
    values[0] = &ts2_arg;
 
838
    
 
839
    /* Initialize the cif */
 
840
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
 
841
 
 
842
    ts2_arg.d1 = 5.55;
 
843
    ts2_arg.d2 = 6.66;
 
844
 
 
845
    printf ("%g\n", ts2_arg.d1);
 
846
    printf ("%g\n", ts2_arg.d2);
 
847
 
 
848
    ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
 
849
 
 
850
    printf ("%g\n", ts2_result->d1);
 
851
    printf ("%g\n", ts2_result->d2);
 
852
    
 
853
    CHECK(ts2_result->d1 == 5.55 - 1);
 
854
    CHECK(ts2_result->d2 == 6.66 - 1);
 
855
 
 
856
    printf("structure test 2 ok!\n");
 
857
 
 
858
    free (ts2_result);
 
859
  }
 
860
 
 
861
  /* struct tests */
 
862
  {
 
863
    int compare_value;
 
864
    test_structure_3 ts3_arg;
 
865
    test_structure_3 *ts3_result = 
 
866
      (test_structure_3 *) malloc (sizeof(test_structure_3));
 
867
 
 
868
    args[0] = &ts3_type;
 
869
    values[0] = &ts3_arg;
 
870
    
 
871
    /* Initialize the cif */
 
872
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
 
873
                       &ts3_type, args) == FFI_OK);
 
874
 
 
875
    ts3_arg.si = -123;
 
876
    compare_value = ts3_arg.si;
 
877
 
 
878
    ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
 
879
 
 
880
    printf ("%d %d\n", ts3_result->si, -(compare_value*2));
 
881
 
 
882
    if (ts3_result->si == -(ts3_arg.si*2))
 
883
        puts ("structure test 3 ok!");
 
884
    else
 
885
      {
 
886
        puts ("Structure test 3 found structure passing bug.");
 
887
        puts ("  Current versions of GCC are not 100% compliant with the");
 
888
        puts ("  n32 ABI.  There is a known problem related to passing");
 
889
        puts ("  small structures.  Send a bug report to the gcc maintainers.");
 
890
      }
 
891
 
 
892
    free (ts3_result);
 
893
  }
 
894
 
 
895
  /* struct tests */
 
896
  {
 
897
    test_structure_4 ts4_arg;
 
898
 
 
899
    /* This is a hack to get a properly aligned result buffer */
 
900
    test_structure_4 *ts4_result = 
 
901
      (test_structure_4 *) malloc (sizeof(test_structure_4));
 
902
 
 
903
    args[0] = &ts4_type;
 
904
    values[0] = &ts4_arg;
 
905
    
 
906
    /* Initialize the cif */
 
907
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
 
908
 
 
909
    ts4_arg.ui1 = 2;
 
910
    ts4_arg.ui2 = 3;
 
911
    ts4_arg.ui3 = 4;
 
912
 
 
913
    ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
 
914
    
 
915
    if (ts4_result->ui3 == 2U * 3U * 4U)
 
916
      puts ("structure test 4 ok!");
 
917
    else
 
918
      puts ("Structure test 4 found GCC's structure passing bug.");
 
919
 
 
920
    free (ts4_result);
 
921
  }
 
922
 
 
923
  /* struct tests */
 
924
  {
 
925
    test_structure_5 ts5_arg1, ts5_arg2;
 
926
 
 
927
    /* This is a hack to get a properly aligned result buffer */
 
928
    test_structure_5 *ts5_result = 
 
929
      (test_structure_5 *) malloc (sizeof(test_structure_5));
 
930
 
 
931
    args[0] = &ts5_type;
 
932
    args[1] = &ts5_type;
 
933
    values[0] = &ts5_arg1;
 
934
    values[1] = &ts5_arg2;
 
935
    
 
936
    /* Initialize the cif */
 
937
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
 
938
 
 
939
    ts5_arg1.c1 = 2;
 
940
    ts5_arg1.c2 = 6;
 
941
    ts5_arg2.c1 = 5;
 
942
    ts5_arg2.c2 = 3;
 
943
 
 
944
    ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
 
945
    
 
946
    if (ts5_result->c1 == 7 
 
947
        && ts5_result->c2 == 3)
 
948
      puts ("structure test 5 ok!");
 
949
    else
 
950
      puts ("Structure test 5 found GCC's structure passing bug.");
 
951
 
 
952
    free (ts5_result);
 
953
  }
 
954
 
 
955
  /* struct tests */
 
956
  {
 
957
    test_structure_6 ts6_arg;
 
958
 
 
959
    /* This is a hack to get a properly aligned result buffer */
 
960
    test_structure_6 *ts6_result = 
 
961
      (test_structure_6 *) malloc (sizeof(test_structure_6));
 
962
 
 
963
    args[0] = &ts6_type;
 
964
    values[0] = &ts6_arg;
 
965
 
 
966
    /* Initialize the cif */
 
967
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
 
968
 
 
969
    ts6_arg.f = 5.55f;
 
970
    ts6_arg.d = 6.66;
 
971
 
 
972
    printf ("%g\n", ts6_arg.f);
 
973
    printf ("%g\n", ts6_arg.d);
 
974
 
 
975
    ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
 
976
 
 
977
    printf ("%g\n", ts6_result->f);
 
978
    printf ("%g\n", ts6_result->d);
 
979
 
 
980
    CHECK(ts6_result->f == 5.55f + 1);
 
981
    CHECK(ts6_result->d == 6.66 + 1);
 
982
 
 
983
    printf("structure test 6 ok!\n");
 
984
 
 
985
    free (ts6_result);
 
986
  }
 
987
 
 
988
  /* struct tests */
 
989
  {
 
990
    test_structure_7 ts7_arg;
 
991
 
 
992
    /* This is a hack to get a properly aligned result buffer */
 
993
    test_structure_7 *ts7_result = 
 
994
      (test_structure_7 *) malloc (sizeof(test_structure_7));
 
995
 
 
996
    args[0] = &ts7_type;
 
997
    values[0] = &ts7_arg;
 
998
 
 
999
    /* Initialize the cif */
 
1000
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
 
1001
 
 
1002
    ts7_arg.f1 = 5.55f;
 
1003
    ts7_arg.f2 = 55.5f;
 
1004
    ts7_arg.d = 6.66;
 
1005
 
 
1006
    printf ("%g\n", ts7_arg.f1);
 
1007
    printf ("%g\n", ts7_arg.f2);
 
1008
    printf ("%g\n", ts7_arg.d);
 
1009
 
 
1010
    ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
 
1011
 
 
1012
    printf ("%g\n", ts7_result->f1);
 
1013
    printf ("%g\n", ts7_result->f2);
 
1014
    printf ("%g\n", ts7_result->d);
 
1015
 
 
1016
    CHECK(ts7_result->f1 == 5.55f + 1);
 
1017
    CHECK(ts7_result->f2 == 55.5f + 1);
 
1018
    CHECK(ts7_result->d == 6.66 + 1);
 
1019
 
 
1020
    printf("structure test 7 ok!\n");
 
1021
 
 
1022
    free (ts7_result);
 
1023
  }
 
1024
 
 
1025
  /* struct tests */
 
1026
  {
 
1027
    test_structure_8 ts8_arg;
 
1028
 
 
1029
    /* This is a hack to get a properly aligned result buffer */
 
1030
    test_structure_8 *ts8_result = 
 
1031
      (test_structure_8 *) malloc (sizeof(test_structure_8));
 
1032
 
 
1033
    args[0] = &ts8_type;
 
1034
    values[0] = &ts8_arg;
 
1035
 
 
1036
    /* Initialize the cif */
 
1037
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
 
1038
 
 
1039
    ts8_arg.f1 = 5.55f;
 
1040
    ts8_arg.f2 = 55.5f;
 
1041
    ts8_arg.f3 = -5.55f;
 
1042
    ts8_arg.f4 = -55.5f;
 
1043
 
 
1044
    printf ("%g\n", ts8_arg.f1);
 
1045
    printf ("%g\n", ts8_arg.f2);
 
1046
    printf ("%g\n", ts8_arg.f3);
 
1047
    printf ("%g\n", ts8_arg.f4);
 
1048
 
 
1049
    ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
 
1050
 
 
1051
    printf ("%g\n", ts8_result->f1);
 
1052
    printf ("%g\n", ts8_result->f2);
 
1053
    printf ("%g\n", ts8_result->f3);
 
1054
    printf ("%g\n", ts8_result->f4);
 
1055
 
 
1056
    CHECK(ts8_result->f1 == 5.55f + 1);
 
1057
    CHECK(ts8_result->f2 == 55.5f + 1);
 
1058
    CHECK(ts8_result->f3 == -5.55f + 1);
 
1059
    CHECK(ts8_result->f4 == -55.5f + 1);
 
1060
 
 
1061
    printf("structure test 8 ok!\n");
 
1062
 
 
1063
    free (ts8_result);
 
1064
  }
 
1065
 
 
1066
  /* struct tests */
 
1067
  {
 
1068
    test_structure_9 ts9_arg;
 
1069
 
 
1070
    /* This is a hack to get a properly aligned result buffer */
 
1071
    test_structure_9 *ts9_result = 
 
1072
      (test_structure_9 *) malloc (sizeof(test_structure_9));
 
1073
 
 
1074
    args[0] = &ts9_type;
 
1075
    values[0] = &ts9_arg;
 
1076
 
 
1077
    /* Initialize the cif */
 
1078
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
 
1079
 
 
1080
    ts9_arg.f = 5.55f;
 
1081
    ts9_arg.i = 5;
 
1082
 
 
1083
    printf ("%g\n", ts9_arg.f);
 
1084
    printf ("%d\n", ts9_arg.i);
 
1085
 
 
1086
    ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
 
1087
 
 
1088
    printf ("%g\n", ts9_result->f);
 
1089
    printf ("%d\n", ts9_result->i);
 
1090
 
 
1091
    CHECK(ts9_result->f == 5.55f + 1);
 
1092
    CHECK(ts9_result->i == 5 + 1);
 
1093
 
 
1094
    printf("structure test 9 ok!\n");
 
1095
 
 
1096
    free (ts9_result);
 
1097
  }
 
1098
 
 
1099
#else
 
1100
  printf("Structure passing doesn't work on Win32.\n");
 
1101
#endif /* X86_WIN32 */
 
1102
 
 
1103
#ifdef X86_WIN32
 
1104
  /* stdcall strlen tests */
 
1105
  {
 
1106
    args[0] = &ffi_type_pointer;
 
1107
    values[0] = (void*) &s;
 
1108
 
 
1109
    /* Initialize the cif */
 
1110
    CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 1,
 
1111
                       &ffi_type_sint, args) == FFI_OK);
 
1112
 
 
1113
    s = "a";
 
1114
    ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
 
1115
    CHECK(rint == 1);
 
1116
 
 
1117
    s = "1234567";
 
1118
    ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
 
1119
    CHECK(rint == 7);
 
1120
 
 
1121
    s = "1234567890123456789012345";
 
1122
    ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
 
1123
    CHECK(rint == 25);
 
1124
 
 
1125
    printf("stdcall strlen tests passed\n");
 
1126
  }
 
1127
 
 
1128
  /* stdcall many arg tests */
 
1129
  {
 
1130
    float ff;
 
1131
    float fa[13];
 
1132
 
 
1133
    for (ul = 0; ul < 13; ul++)
 
1134
      {
 
1135
        args[ul] = &ffi_type_float;
 
1136
        values[ul] = &fa[ul];
 
1137
        fa[ul] = (float) ul;
 
1138
      }
 
1139
 
 
1140
    /* Initialize the cif */
 
1141
    CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13,
 
1142
                       &ffi_type_float, args) == FFI_OK);
 
1143
 
 
1144
    /*@-usedef@*/
 
1145
    ff =  stdcall_many(fa[0], fa[1],
 
1146
               fa[2], fa[3],
 
1147
               fa[4], fa[5],
 
1148
               fa[6], fa[7],
 
1149
               fa[8], fa[9],
 
1150
               fa[10],fa[11],fa[12]);
 
1151
    /*@=usedef@*/
 
1152
 
 
1153
    ffi_call(&cif, FFI_FN(stdcall_many), &f, values);
 
1154
 
 
1155
    /*@-realcompare@*/
 
1156
    if (f - ff < FLT_EPSILON)
 
1157
    /*@=realcompare@*/
 
1158
        printf("stdcall many arg tests ok!\n");
 
1159
    else
 
1160
        CHECK(0);
 
1161
  }
 
1162
#endif /* X86_WIN32 */
 
1163
 
 
1164
# if FFI_CLOSURES
 
1165
#  if __GNUC__ >= 2
 
1166
   /* Hide before the compiler that pcl is &cl, since on
 
1167
      some architectures it is not possible to call a data
 
1168
      object using direct function call.  */
 
1169
   asm ("" : "=g" (pcl) : "0" (pcl));
 
1170
#  endif
 
1171
 
 
1172
  /* A simple closure test */
 
1173
    {
 
1174
      (void) puts("\nEnter FFI_CLOSURES\n");
 
1175
 
 
1176
      cl_arg_types[0] = &ffi_type_uint64;
 
1177
      cl_arg_types[1] = &ffi_type_uint;
 
1178
      cl_arg_types[2] = &ffi_type_uint64;
 
1179
      cl_arg_types[3] = &ffi_type_uint;
 
1180
      cl_arg_types[4] = &ffi_type_sshort;
 
1181
      cl_arg_types[5] = &ffi_type_uint64;
 
1182
      cl_arg_types[6] = &ffi_type_uint;
 
1183
      cl_arg_types[7] = &ffi_type_uint;
 
1184
      cl_arg_types[8] = &ffi_type_double;
 
1185
      cl_arg_types[9] = &ffi_type_uint;
 
1186
      cl_arg_types[10] = &ffi_type_uint;
 
1187
      cl_arg_types[11] = &ffi_type_float;
 
1188
      cl_arg_types[12] = &ffi_type_uint;
 
1189
      cl_arg_types[13] = &ffi_type_uint;
 
1190
      cl_arg_types[14] = &ffi_type_uint;
 
1191
      cl_arg_types[15] = &ffi_type_uint;
 
1192
      cl_arg_types[16] = NULL;   
 
1193
 
 
1194
      /* Initialize the cif */
 
1195
      CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
 
1196
                         &ffi_type_sint, cl_arg_types) == FFI_OK);
 
1197
 
 
1198
      CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn,
 
1199
                             (void *) 3 /* userdata */) == FFI_OK);
 
1200
      
 
1201
      CHECK((*((closure_test_type)pcl))
 
1202
            (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13, 
 
1203
             19, 21, 1) == 680);
 
1204
    }
 
1205
 
 
1206
    {
 
1207
 
 
1208
      cl_arg_types[0] = &ffi_type_float;
 
1209
      cl_arg_types[1] = &ffi_type_float;
 
1210
      cl_arg_types[2] = &ffi_type_float;
 
1211
      cl_arg_types[3] = &ffi_type_float;
 
1212
      cl_arg_types[4] = &ffi_type_sshort;
 
1213
      cl_arg_types[5] = &ffi_type_float;
 
1214
      cl_arg_types[6] = &ffi_type_float;
 
1215
      cl_arg_types[7] = &ffi_type_uint;
 
1216
      cl_arg_types[8] = &ffi_type_double;
 
1217
      cl_arg_types[9] = &ffi_type_uint;
 
1218
      cl_arg_types[10] = &ffi_type_uint;
 
1219
      cl_arg_types[11] = &ffi_type_float;
 
1220
      cl_arg_types[12] = &ffi_type_uint;
 
1221
      cl_arg_types[13] = &ffi_type_uint;
 
1222
      cl_arg_types[14] = &ffi_type_uint;
 
1223
      cl_arg_types[15] = &ffi_type_uint;
 
1224
      cl_arg_types[16] = NULL;
 
1225
      
 
1226
      /* Initialize the cif */
 
1227
      CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
 
1228
                         &ffi_type_sint, cl_arg_types) == FFI_OK);
 
1229
 
 
1230
      CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn1,
 
1231
                             (void *) 3 /* userdata */)  == FFI_OK);
 
1232
      
 
1233
      CHECK((*((closure_test_type1)pcl))
 
1234
            (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
 
1235
             19, 21, 1) == 255);
 
1236
    }
 
1237
 
 
1238
    {
 
1239
 
 
1240
      cl_arg_types[0] = &ffi_type_double;
 
1241
      cl_arg_types[1] = &ffi_type_double;
 
1242
      cl_arg_types[2] = &ffi_type_double;
 
1243
      cl_arg_types[3] = &ffi_type_double;
 
1244
      cl_arg_types[4] = &ffi_type_sshort;
 
1245
      cl_arg_types[5] = &ffi_type_double;
 
1246
      cl_arg_types[6] = &ffi_type_double;
 
1247
      cl_arg_types[7] = &ffi_type_uint;
 
1248
      cl_arg_types[8] = &ffi_type_double;
 
1249
      cl_arg_types[9] = &ffi_type_uint;
 
1250
      cl_arg_types[10] = &ffi_type_uint;
 
1251
      cl_arg_types[11] = &ffi_type_float;
 
1252
      cl_arg_types[12] = &ffi_type_uint;
 
1253
      cl_arg_types[13] = &ffi_type_float;
 
1254
      cl_arg_types[14] = &ffi_type_uint;
 
1255
      cl_arg_types[15] = &ffi_type_uint;
 
1256
      cl_arg_types[16] = NULL;
 
1257
      
 
1258
      /* Initialize the cif */
 
1259
      CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
 
1260
                         &ffi_type_sint, cl_arg_types) == FFI_OK);
 
1261
 
 
1262
      CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn2,
 
1263
                             (void *) 3 /* userdata */) == FFI_OK);
 
1264
 
 
1265
      CHECK((*((closure_test_type2)pcl))
 
1266
            (1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
 
1267
             19.0, 21, 1) == 255);
 
1268
 
 
1269
    }
 
1270
 
 
1271
    {
 
1272
 
 
1273
      cl_arg_types[0] = &ffi_type_float;
 
1274
      cl_arg_types[1] = &ffi_type_float;
 
1275
      cl_arg_types[2] = &ffi_type_float;
 
1276
      cl_arg_types[3] = &ffi_type_float;
 
1277
      cl_arg_types[4] = &ffi_type_float;
 
1278
      cl_arg_types[5] = &ffi_type_float;
 
1279
      cl_arg_types[6] = &ffi_type_float;
 
1280
      cl_arg_types[7] = &ffi_type_float;
 
1281
      cl_arg_types[8] = &ffi_type_double;
 
1282
      cl_arg_types[9] = &ffi_type_uint;
 
1283
      cl_arg_types[10] = &ffi_type_float;
 
1284
      cl_arg_types[11] = &ffi_type_float;
 
1285
      cl_arg_types[12] = &ffi_type_uint;
 
1286
      cl_arg_types[13] = &ffi_type_float;
 
1287
      cl_arg_types[14] = &ffi_type_float;
 
1288
      cl_arg_types[15] = &ffi_type_uint;
 
1289
      cl_arg_types[16] = NULL;
 
1290
      
 
1291
      /* Initialize the cif */
 
1292
      CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
 
1293
                         &ffi_type_sint, cl_arg_types) == FFI_OK);
 
1294
 
 
1295
      CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn3,
 
1296
                             (void *) 3 /* userdata */)  == FFI_OK);
 
1297
      
 
1298
      CHECK((*((closure_test_type3)pcl))
 
1299
            (1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
 
1300
             19.19, 21.21, 1) == 135);
 
1301
    }
 
1302
 
 
1303
    (void) puts("\nFinished FFI_CLOSURES\n");
 
1304
 
 
1305
# endif
 
1306
 
 
1307
  /* If we arrived here, all is good */
 
1308
  (void) puts("\nLooks good. No surprises.\n");
 
1309
 
 
1310
  /*@-compdestroy@*/
 
1311
 
 
1312
  return 0;
 
1313
}
 
1314