Home | History | Annotate | Download | only in libffi.call
      1 /* Area:		ffi_call, closure_call
      2    Purpose:		Test doubles passed in variable argument lists.
      3    Limitations:	none.
      4    PR:			none.
      5    Originator:	Blake Chaffin 6/6/2007	 */
      6 
      7 /* { dg-do run } */
      8 /* { dg-output "" { xfail avr32*-*-* } } */
      9 #include "ffitest.h"
     10 
     11 struct small_tag
     12 {
     13   unsigned char a;
     14   unsigned char b;
     15 };
     16 
     17 struct large_tag
     18 {
     19   unsigned a;
     20   unsigned b;
     21   unsigned c;
     22   unsigned d;
     23   unsigned e;
     24 };
     25 
     26 static void
     27 test_fn (ffi_cif* cif __UNUSED__, void* resp,
     28 	 void** args, void* userdata __UNUSED__)
     29 {
     30   int n = *(int*)args[0];
     31   struct small_tag s1 = * (struct small_tag *) args[1];
     32   struct large_tag l1 = * (struct large_tag *) args[2];
     33   struct small_tag s2 = * (struct small_tag *) args[3];
     34 
     35   printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b,
     36 	  l1.a, l1.b, l1.c, l1.d, l1.e,
     37 	  s2.a, s2.b);
     38   * (ffi_arg*) resp = 42;
     39 }
     40 
     41 int
     42 main (void)
     43 {
     44   ffi_cif cif;
     45   void *code;
     46   ffi_closure *pcl = ffi_closure_alloc (sizeof (ffi_closure), &code);
     47   ffi_type* arg_types[5];
     48 
     49   ffi_arg res = 0;
     50 
     51   ffi_type s_type;
     52   ffi_type *s_type_elements[3];
     53 
     54   ffi_type l_type;
     55   ffi_type *l_type_elements[6];
     56 
     57   struct small_tag s1;
     58   struct small_tag s2;
     59   struct large_tag l1;
     60 
     61   int si;
     62 
     63   s_type.size = 0;
     64   s_type.alignment = 0;
     65   s_type.type = FFI_TYPE_STRUCT;
     66   s_type.elements = s_type_elements;
     67 
     68   s_type_elements[0] = &ffi_type_uchar;
     69   s_type_elements[1] = &ffi_type_uchar;
     70   s_type_elements[2] = NULL;
     71 
     72   l_type.size = 0;
     73   l_type.alignment = 0;
     74   l_type.type = FFI_TYPE_STRUCT;
     75   l_type.elements = l_type_elements;
     76 
     77   l_type_elements[0] = &ffi_type_uint;
     78   l_type_elements[1] = &ffi_type_uint;
     79   l_type_elements[2] = &ffi_type_uint;
     80   l_type_elements[3] = &ffi_type_uint;
     81   l_type_elements[4] = &ffi_type_uint;
     82   l_type_elements[5] = NULL;
     83 
     84   arg_types[0] = &ffi_type_sint;
     85   arg_types[1] = &s_type;
     86   arg_types[2] = &l_type;
     87   arg_types[3] = &s_type;
     88   arg_types[4] = NULL;
     89 
     90   CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint,
     91 			 arg_types) == FFI_OK);
     92 
     93   si = 4;
     94   s1.a = 5;
     95   s1.b = 6;
     96 
     97   s2.a = 20;
     98   s2.b = 21;
     99 
    100   l1.a = 10;
    101   l1.b = 11;
    102   l1.c = 12;
    103   l1.d = 13;
    104   l1.e = 14;
    105 
    106   CHECK(ffi_prep_closure_loc(pcl, &cif, test_fn, NULL, code) == FFI_OK);
    107 
    108   res = ((int (*)(int, ...))(code))(si, s1, l1, s2);
    109   /* { dg-output "4 5 6 10 11 12 13 14 20 21" } */
    110   printf("res: %d\n", (int) res);
    111   /* { dg-output "\nres: 42" } */
    112 
    113   exit(0);
    114 }
    115