1 /* Area: ffi_call, closure_call 2 Purpose: Check structure passing with different structure size. 3 Limitations: none. 4 PR: none. 5 Originator: <andreast (at) gcc.gnu.org> 20030828 */ 6 7 /* { dg-do run } */ 8 #include "ffitest.h" 9 10 typedef struct my_ffi_struct { 11 double a; 12 double b; 13 double c; 14 } my_ffi_struct; 15 16 my_ffi_struct callee(struct my_ffi_struct a1, struct my_ffi_struct a2) 17 { 18 struct my_ffi_struct result; 19 result.a = a1.a + a2.a; 20 result.b = a1.b + a2.b; 21 result.c = a1.c + a2.c; 22 23 24 printf("%g %g %g %g %g %g: %g %g %g\n", a1.a, a1.b, a1.c, 25 a2.a, a2.b, a2.c, result.a, result.b, result.c); 26 27 return result; 28 } 29 30 void stub(ffi_cif* cif __UNUSED__, void* resp, void** args, 31 void* userdata __UNUSED__) 32 { 33 struct my_ffi_struct a1; 34 struct my_ffi_struct a2; 35 36 a1 = *(struct my_ffi_struct*)(args[0]); 37 a2 = *(struct my_ffi_struct*)(args[1]); 38 39 *(my_ffi_struct *)resp = callee(a1, a2); 40 } 41 42 43 int main(void) 44 { 45 ffi_type* my_ffi_struct_fields[4]; 46 ffi_type my_ffi_struct_type; 47 ffi_cif cif; 48 #ifndef USING_MMAP 49 static ffi_closure cl; 50 #endif 51 ffi_closure *pcl; 52 void* args[4]; 53 ffi_type* arg_types[3]; 54 55 #ifdef USING_MMAP 56 pcl = allocate_mmap (sizeof(ffi_closure)); 57 #else 58 pcl = &cl; 59 #endif 60 61 struct my_ffi_struct g = { 1.0, 2.0, 3.0 }; 62 struct my_ffi_struct f = { 1.0, 2.0, 3.0 }; 63 struct my_ffi_struct res; 64 65 my_ffi_struct_type.size = 0; 66 my_ffi_struct_type.alignment = 0; 67 my_ffi_struct_type.type = FFI_TYPE_STRUCT; 68 my_ffi_struct_type.elements = my_ffi_struct_fields; 69 70 my_ffi_struct_fields[0] = &ffi_type_double; 71 my_ffi_struct_fields[1] = &ffi_type_double; 72 my_ffi_struct_fields[2] = &ffi_type_double; 73 my_ffi_struct_fields[3] = NULL; 74 75 arg_types[0] = &my_ffi_struct_type; 76 arg_types[1] = &my_ffi_struct_type; 77 arg_types[2] = NULL; 78 79 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &my_ffi_struct_type, 80 arg_types) == FFI_OK); 81 82 args[0] = &g; 83 args[1] = &f; 84 args[2] = NULL; 85 ffi_call(&cif, FFI_FN(callee), &res, args); 86 /* { dg-output "1 2 3 1 2 3: 2 4 6" } */ 87 printf("res: %g %g %g\n", res.a, res.b, res.c); 88 /* { dg-output "\nres: 2 4 6" } */ 89 90 CHECK(ffi_prep_closure(pcl, &cif, stub, NULL) == FFI_OK); 91 92 res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(pcl))(g, f); 93 /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */ 94 printf("res: %g %g %g\n", res.a, res.b, res.c); 95 /* { dg-output "\nres: 2 4 6" } */ 96 97 exit(0);; 98 } 99