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 #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