]> git.ipfire.org Git - thirdparty/gcc.git/blob - libffi/testsuite/libffi.closures/single_entry_structs1.c
libffi: Sync with libffi 3.4.2
[thirdparty/gcc.git] / libffi / testsuite / libffi.closures / single_entry_structs1.c
1 /* Area: ffi_call, closure_call
2 Purpose: Single argument structs have a different ABI in emscripten.
3 Limitations: none.
4 PR: none.
5 Originator: <hood@mit.edu> */
6
7 /* { dg-do run } */
8 #include "ffitest.h"
9
10 typedef struct A {
11 int a;
12 } A;
13
14 static struct A A_fn(int b0, struct A b1)
15 {
16 b1.a += b0;
17 return b1;
18 }
19
20 static void
21 A_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
22 void* userdata __UNUSED__)
23 {
24 int b0;
25 struct A b1;
26
27 b0 = *(int*)(args[0]);
28 b1 = *(struct A*)(args[1]);
29
30 *(A*)resp = A_fn(b0, b1);
31 }
32
33 int main (void)
34 {
35 printf("123\n");
36 ffi_cif cif;
37 void *code;
38 ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
39 void* args_dbl[3];
40 ffi_type* cls_struct_fields[2];
41 ffi_type cls_struct_type;
42 ffi_type* dbl_arg_types[3];
43
44 int e_dbl = 12125;
45 struct A f_dbl = { 31625 };
46
47 struct A res_dbl;
48
49 cls_struct_type.size = 0;
50 cls_struct_type.alignment = 0;
51 cls_struct_type.type = FFI_TYPE_STRUCT;
52 cls_struct_type.elements = cls_struct_fields;
53
54 cls_struct_fields[0] = &ffi_type_sint;
55 cls_struct_fields[1] = NULL;
56
57 dbl_arg_types[0] = &ffi_type_sint;
58 dbl_arg_types[1] = &cls_struct_type;
59 dbl_arg_types[2] = NULL;
60
61 res_dbl = A_fn(e_dbl, f_dbl);
62 printf("0 res: %d\n", res_dbl.a);
63 /* { dg-output "0 res: 43750" } */
64
65 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
66 dbl_arg_types) == FFI_OK);
67
68 args_dbl[0] = &e_dbl;
69 args_dbl[1] = &f_dbl;
70 args_dbl[2] = NULL;
71
72
73 ffi_call(&cif, FFI_FN(A_fn), &res_dbl, args_dbl);
74 printf("1 res: %d\n", res_dbl.a);
75 /* { dg-output "\n1 res: 43750" } */
76 CHECK( res_dbl.a == (e_dbl + f_dbl.a));
77
78 CHECK(ffi_prep_closure_loc(pcl, &cif, A_gn, NULL, code) == FFI_OK);
79
80 res_dbl = ((A(*)(int, A))(code))(e_dbl, f_dbl);
81 printf("2 res: %d\n", res_dbl.a);
82 /* { dg-output "\n2 res: 43750" } */
83 CHECK( res_dbl.a == (e_dbl + f_dbl.a));
84
85 exit(0);
86 }