This is the mail archive of the
libffi-discuss@sources.redhat.com
mailing list for the libffi project.
closure tests
- From: andreas tobler <toa at pop dot agri dot ch>
- To: Anthony Green <green at redhat dot com>, libffi-discuss<libffi-discuss at sources dot redhat dot com>
- Date: Thu, 7 Mar 2002 22:49:48 +0100
- Subject: closure tests
Hi all,
during implementing the closures for darwin I had to extend the closure
test in ffitest.c. I'd like to share my test case.
The reason for this cases is that we have 8 GPRs and 13 FPRs on darwin/
AIX and that I had to test the boundaries.
I think it could be worth to integrate them into ffi.
Without these test cases I had the impression that my completely wrong
first approach is working. Only with these cases I got the point that I
was wrong.
Also another, already existing test case is not clean. The floating one
gets 5 arguments, four of them are used, the fifth is not. And this one
is exactly the one which failed on darwin/AIX.
Attached a sample case with 15 arguments for closure. I have different
ones of this with different arguments. I know very hard coding, but it helped.
Regards,
Andreas
---
floating: here the parameter e is never used if #ifed 0
#if 1
/* This is ifdef'd out for now. long double support under SunOS/gcc
is pretty much non-existent. You'll get the odd bus error in library
routines like printf(). */
printf("%d %f %f %Lf %d\n", a, (double)b, c, d, e);
#endif
i = (int) ((float)a/b + ((float)c/(float)d)); <------ no use of e!!!!
return i;
}
---
closure:
static void closure_test_fn(ffi_cif* cif,void* resp,void** args, void*
userdata)
{
*(int*)resp =
(int)*(unsigned long long *)args[0] +(int)(*(int *)args[1]) +
(int)(*(unsigned long long *)args[2]) +
(int)*(int *)args[3] +(int)(*(signed short *)args[4]) +
(int)(*(unsigned long long*)args[5]) +
(int)*(int *)args[6] +(int)(*(int*)args[7]) +
(int)(*(double*)args[8]) +
(int)*(int *)args[9] +(int)(*(int*)args[10]) +
(int)(*(float*)args[11])
+ (int)*(int *)args[12] + (int)(*(int*)args[13]) +
(int)(*(int*)args[14]) + *(int *)args[15] + (int)(long)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
(int)(*(unsigned long long *)args[2]),
(int)*(int *)args[3], (int)(*(signed short *)args[4]),
(int)(*(unsigned long long *)args[5]),
(int)*(int *)args[6], (int)(*(int*)args[7]), (int)(*(double*)args[8]),
(int)*(int *)args[9], (int)(*(int*)args[10]),
(int)(*(float*)args[11]),
(int)*(int *)args[12], (int)(*(int*)args[13]), (int)(*(int*)args[14]),
*(int *)args[15], (int)(long)userdata, *(int*)resp);
}
typedef int (*closure_test_type)(unsigned long long, int, unsigned long
long, int, signed short, unsigned long long, int, int, double, int, int,
float, int,
int, int, int);
# if FFI_CLOSURES
/* A simple closure test */
{
(void) puts("\nEnter FFI_CLOSURES\n");
ffi_closure cl;
ffi_type * cl_arg_types[17];
cl_arg_types[0] = &ffi_type_uint64;
cl_arg_types[1] = &ffi_type_uint;
cl_arg_types[2] = &ffi_type_uint64;
cl_arg_types[3] = &ffi_type_uint;
cl_arg_types[4] = &ffi_type_sshort;
cl_arg_types[5] = &ffi_type_uint64;
cl_arg_types[6] = &ffi_type_uint;
cl_arg_types[7] = &ffi_type_uint;
cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_uint;
cl_arg_types[10] = &ffi_type_uint;
cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_uint;
cl_arg_types[13] = &ffi_type_uint;
cl_arg_types[14] = &ffi_type_uint;
cl_arg_types[15] = &ffi_type_uint;
cl_arg_types[16] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn,
(void *) 3 /* userdata */)
== FFI_OK);
CHECK((*((closure_test_type)(&cl)))
(1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
19, 21, 1) == 680);
}
(void) puts("\nFinished FFI_CLOSURES\n");