Home | History | Annotate | Download | only in libffi.call
      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   void *code;
     49   ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
     50   void* args[4];
     51   ffi_type* arg_types[3];
     52 
     53   struct my_ffi_struct g = { 1.0, 2.0, 3.0 };
     54   struct my_ffi_struct f = { 1.0, 2.0, 3.0 };
     55   struct my_ffi_struct res;
     56 
     57   my_ffi_struct_type.size = 0;
     58   my_ffi_struct_type.alignment = 0;
     59   my_ffi_struct_type.type = FFI_TYPE_STRUCT;
     60   my_ffi_struct_type.elements = my_ffi_struct_fields;
     61 
     62   my_ffi_struct_fields[0] = &ffi_type_double;
     63   my_ffi_struct_fields[1] = &ffi_type_double;
     64   my_ffi_struct_fields[2] = &ffi_type_double;
     65   my_ffi_struct_fields[3] = NULL;
     66 
     67   arg_types[0] = &my_ffi_struct_type;
     68   arg_types[1] = &my_ffi_struct_type;
     69   arg_types[2] = NULL;
     70 
     71   CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &my_ffi_struct_type,
     72 		     arg_types) == FFI_OK);
     73 
     74   args[0] = &g;
     75   args[1] = &f;
     76   args[2] = NULL;
     77   ffi_call(&cif, FFI_FN(callee), &res, args);
     78   /* { dg-output "1 2 3 1 2 3: 2 4 6" } */
     79   printf("res: %g %g %g\n", res.a, res.b, res.c);
     80   /* { dg-output "\nres: 2 4 6" } */
     81 
     82   CHECK(ffi_prep_closure_loc(pcl, &cif, stub, NULL, code) == FFI_OK);
     83 
     84   res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(code))(g, f);
     85   /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */
     86   printf("res: %g %g %g\n", res.a, res.b, res.c);
     87   /* { dg-output "\nres: 2 4 6" } */
     88 
     89   exit(0);;
     90 }
     91