summaryrefslogtreecommitdiffstats
path: root/js/src/ctypes/libffi/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/ctypes/libffi/testsuite')
-rw-r--r--js/src/ctypes/libffi/testsuite/Makefile.am122
-rw-r--r--js/src/ctypes/libffi/testsuite/Makefile.in647
-rw-r--r--js/src/ctypes/libffi/testsuite/config/default.exp1
-rw-r--r--js/src/ctypes/libffi/testsuite/lib/libffi.exp640
-rw-r--r--js/src/ctypes/libffi/testsuite/lib/target-libpath.exp283
-rw-r--r--js/src/ctypes/libffi/testsuite/lib/wrapper.exp45
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.bhaible/Makefile28
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.bhaible/README78
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.bhaible/alignof.h50
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.bhaible/bhaible.exp63
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.bhaible/test-call.c1745
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.bhaible/test-callback.c2885
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.bhaible/testcases.c743
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/align_mixed.c46
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/align_stdcall.c46
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/call.exp54
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/err_bad_typedef.c26
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/ffitest.h138
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/float.c59
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/float1.c60
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/float2.c61
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/float3.c74
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/float4.c62
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/float_va.c107
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/many.c59
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/many2.c57
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/many_double.c70
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/many_mixed.c78
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/negint.c52
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/offsets.c46
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/pr1172638.c127
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/promotion.c59
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/pyobjc-tc.c114
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_dbl.c36
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_dbl1.c43
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_dbl2.c42
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_fl.c35
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_fl1.c36
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_fl2.c49
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_fl3.c42
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_ldl.c34
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_ll.c41
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_ll1.c43
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_sc.c36
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_sl.c38
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_uc.c38
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/return_ul.c38
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/strlen.c44
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/strlen2.c49
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/strlen3.c49
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/strlen4.c55
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/struct1.c67
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/struct10.c57
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/struct2.c67
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/struct3.c60
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/struct4.c64
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/struct5.c66
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/struct6.c64
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/struct7.c74
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/struct8.c81
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/struct9.c68
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/uninitialized.c61
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/va_1.c196
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/va_struct1.c121
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/va_struct2.c123
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/va_struct3.c125
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/closure.exp67
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn0.c89
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn1.c81
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn2.c81
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn3.c82
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn4.c89
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn5.c92
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn6.c90
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/closure_loc_fn0.c95
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/closure_simple.c55
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_12byte.c94
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_16byte.c95
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_18byte.c96
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_19byte.c102
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_1_1byte.c89
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_20byte.c91
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_20byte1.c93
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_24byte.c113
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_2byte.c90
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_3_1byte.c95
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_3byte1.c90
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_3byte2.c90
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_3float.c95
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_4_1byte.c98
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_4byte.c90
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_5_1_byte.c109
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_5byte.c98
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_64byte.c124
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_6_1_byte.c113
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_6byte.c99
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_7_1_byte.c117
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_7byte.c97
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_8byte.c88
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_9byte1.c90
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_9byte2.c91
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_double.c93
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_float.c91
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble.c92
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble_split.c132
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble_split2.c115
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_pointer.c95
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint16.c91
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint32.c91
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint64.c92
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint16.c91
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint32.c91
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint64.c93
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_dbls_struct.c66
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_double.c43
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_double_va.c61
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_float.c42
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_longdouble.c105
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_longdouble_va.c61
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_many_mixed_args.c70
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_many_mixed_float_double.c55
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_schar.c74
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_sshort.c74
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c86
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_uchar.c91
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_ushort.c74
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c86
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_pointer.c74
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_pointer_stack.c142
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_schar.c44
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_sint.c42
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_sshort.c42
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_struct_va1.c114
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_uchar.c42
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_uchar_va.c44
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_uint.c43
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_uint_va.c45
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_ulong_va.c45
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_ulonglong.c47
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_ushort.c43
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/cls_ushort_va.c44
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/err_bad_abi.c36
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/ffitest.h138
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/huge_struct.c341
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct.c152
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct1.c161
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct10.c134
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct11.c121
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct2.c110
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct3.c111
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct4.c111
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct5.c112
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct6.c131
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct7.c111
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct8.c131
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct9.c131
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/problem1.c90
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/stret_large.c145
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/stret_large2.c148
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/stret_medium.c124
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/stret_medium2.c125
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/testclosure.c70
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/unwindtest.cc117
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc54
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex.inc91
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_double.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_float.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex.inc42
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_double.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_float.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_longdouble.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct.inc71
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_double.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_float.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va.inc80
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_double.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_float.c16
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/complex.exp36
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/complex.inc51
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_double.inc7
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_float.inc7
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc7
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/complex_double.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/complex_float.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/complex_int.c86
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/complex_longdouble.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/ffitest.h1
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/many_complex.inc78
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_double.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_float.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_longdouble.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex.inc37
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1.inc41
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_double.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_float.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_longdouble.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2.inc44
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_double.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_float.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_longdouble.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_double.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_float.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_longdouble.c10
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.go/aa-direct.c34
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.go/closure1.c28
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.go/ffitest.h1
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.go/go.exp36
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.go/static-chain.h19
211 files changed, 20978 insertions, 0 deletions
diff --git a/js/src/ctypes/libffi/testsuite/Makefile.am b/js/src/ctypes/libffi/testsuite/Makefile.am
new file mode 100644
index 0000000000..bcfea57705
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/Makefile.am
@@ -0,0 +1,122 @@
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = foreign dejagnu
+
+EXTRA_DEJAGNU_SITE_CONFIG=../local.exp
+
+CLEANFILES = *.exe core* *.log *.sum
+
+EXTRA_DIST = lib/target-libpath.exp lib/libffi.exp lib/wrapper.exp \
+libffi.call/strlen4.c libffi.call/struct10.c libffi.call/many_mixed.c \
+libffi.call/float.c libffi.call/struct5.c libffi.call/return_fl3.c \
+libffi.call/return_fl1.c libffi.call/call.exp libffi.call/pyobjc-tc.c \
+libffi.call/float_va.c libffi.call/struct8.c libffi.call/pr1172638.c \
+libffi.call/return_sc.c libffi.call/va_struct1.c \
+libffi.call/align_stdcall.c libffi.call/struct9.c libffi.call/va_1.c \
+libffi.call/va_struct2.c libffi.call/return_fl2.c \
+libffi.call/align_mixed.c libffi.call/ffitest.h libffi.call/struct4.c \
+libffi.call/return_ldl.c libffi.call/float3.c libffi.call/return_sl.c \
+libffi.call/return_dbl1.c libffi.call/err_bad_typedef.c \
+libffi.call/return_ll1.c libffi.call/return_dbl2.c \
+libffi.call/negint.c libffi.closures/nested_struct3.c \
+libffi.call/struct2.c libffi.call/struct3.c libffi.call/return_fl.c \
+libffi.call/offsets.c libffi.call/struct7.c libffi.call/va_struct3.c \
+libffi.call/float1.c libffi.call/uninitialized.c libffi.call/many2.c \
+libffi.call/struct6.c libffi.call/strlen2.c libffi.call/float2.c \
+libffi.call/return_ul.c libffi.call/struct1.c libffi.call/strlen3.c \
+libffi.call/return_dbl.c libffi.call/float4.c libffi.call/many.c \
+libffi.call/strlen.c libffi.call/return_uc.c libffi.call/many_double.c \
+libffi.call/return_ll.c libffi.call/promotion.c \
+libffi.complex/complex_defs_longdouble.inc \
+libffi.complex/cls_align_complex_float.c \
+libffi.complex/cls_complex_va_float.c \
+libffi.complex/cls_complex_struct_float.c \
+libffi.complex/return_complex2_longdouble.c \
+libffi.complex/cls_complex_float.c \
+libffi.complex/return_complex_longdouble.c \
+libffi.complex/return_complex2_float.c libffi.complex/cls_complex.inc \
+libffi.complex/cls_complex_va_longdouble.c \
+libffi.complex/return_complex_double.c \
+libffi.complex/return_complex.inc libffi.complex/many_complex.inc \
+libffi.complex/complex_float.c libffi.complex/cls_align_complex.inc \
+libffi.complex/return_complex2_double.c \
+libffi.complex/many_complex_float.c libffi.complex/ffitest.h \
+libffi.complex/return_complex1_double.c \
+libffi.complex/cls_complex_struct_longdouble.c \
+libffi.complex/complex_defs_double.inc \
+libffi.complex/cls_complex_va_double.c \
+libffi.complex/many_complex_double.c \
+libffi.complex/return_complex2.inc \
+libffi.complex/return_complex1_float.c \
+libffi.complex/complex_longdouble.c \
+libffi.complex/complex_defs_float.inc \
+libffi.complex/cls_complex_double.c \
+libffi.complex/cls_align_complex_double.c \
+libffi.complex/cls_align_complex_longdouble.c \
+libffi.complex/complex_double.c libffi.complex/cls_complex_va.inc \
+libffi.complex/many_complex_longdouble.c libffi.complex/complex.inc \
+libffi.complex/return_complex1_longdouble.c \
+libffi.complex/complex_int.c libffi.complex/cls_complex_longdouble.c \
+libffi.complex/cls_complex_struct_double.c \
+libffi.complex/return_complex1.inc libffi.complex/complex.exp \
+libffi.complex/cls_complex_struct.inc \
+libffi.complex/return_complex_float.c libffi.go/closure1.c \
+libffi.go/aa-direct.c libffi.go/ffitest.h libffi.go/go.exp \
+libffi.go/static-chain.h libffi.bhaible/bhaible.exp \
+libffi.bhaible/test-call.c libffi.bhaible/alignof.h \
+libffi.bhaible/testcases.c libffi.bhaible/test-callback.c \
+libffi.bhaible/Makefile libffi.bhaible/README config/default.exp \
+libffi.closures/cls_multi_sshort.c \
+libffi.closures/cls_align_longdouble_split2.c \
+libffi.closures/cls_1_1byte.c libffi.closures/cls_uint_va.c \
+libffi.closures/cls_3_1byte.c libffi.closures/cls_many_mixed_args.c \
+libffi.closures/cls_20byte1.c libffi.closures/cls_pointer_stack.c \
+libffi.closures/cls_align_float.c libffi.closures/cls_5_1_byte.c \
+libffi.closures/cls_9byte1.c libffi.closures/cls_align_uint32.c \
+libffi.closures/stret_medium.c libffi.closures/cls_3byte1.c \
+libffi.closures/cls_align_uint64.c libffi.closures/cls_longdouble_va.c \
+libffi.closures/cls_align_pointer.c libffi.closures/cls_19byte.c \
+libffi.closures/cls_ushort.c libffi.closures/cls_align_sint32.c \
+libffi.closures/cls_ulonglong.c libffi.closures/cls_struct_va1.c \
+libffi.closures/cls_9byte2.c libffi.closures/closure_fn5.c \
+libffi.closures/cls_5byte.c libffi.closures/cls_3float.c \
+libffi.closures/closure.exp libffi.closures/cls_schar.c \
+libffi.closures/closure_fn4.c libffi.closures/cls_uchar_va.c \
+libffi.closures/closure_fn0.c libffi.closures/huge_struct.c \
+libffi.closures/cls_ushort_va.c \
+libffi.closures/cls_64byte.c libffi.closures/cls_longdouble.c \
+libffi.closures/cls_ulong_va.c libffi.closures/cls_6_1_byte.c \
+libffi.closures/cls_align_uint16.c libffi.closures/closure_fn2.c \
+libffi.closures/unwindtest_ffi_call.cc \
+libffi.closures/cls_multi_ushortchar.c libffi.closures/cls_8byte.c \
+libffi.closures/ffitest.h libffi.closures/nested_struct8.c \
+libffi.closures/cls_pointer.c libffi.closures/nested_struct2.c \
+libffi.closures/nested_struct.c libffi.closures/cls_multi_schar.c \
+libffi.closures/cls_align_longdouble_split.c \
+libffi.closures/cls_uchar.c libffi.closures/nested_struct9.c \
+libffi.closures/cls_float.c libffi.closures/stret_medium2.c \
+libffi.closures/closure_loc_fn0.c libffi.closures/cls_6byte.c \
+libffi.closures/closure_simple.c libffi.closures/cls_align_double.c \
+libffi.closures/cls_multi_uchar.c libffi.closures/cls_4_1byte.c \
+libffi.closures/closure_fn3.c libffi.closures/cls_align_sint64.c \
+libffi.closures/nested_struct1.c libffi.closures/unwindtest.cc \
+libffi.closures/nested_struct5.c libffi.closures/cls_multi_ushort.c \
+libffi.closures/nested_struct11.c \
+libffi.closures/cls_multi_sshortchar.c \
+libffi.closures/cls_align_longdouble.c \
+libffi.closures/cls_dbls_struct.c \
+libffi.closures/cls_many_mixed_float_double.c \
+libffi.closures/stret_large.c libffi.closures/stret_large2.c \
+libffi.closures/cls_align_sint16.c libffi.closures/cls_2byte.c \
+libffi.closures/nested_struct4.c libffi.closures/problem1.c \
+libffi.closures/testclosure.c libffi.closures/nested_struct6.c \
+libffi.closures/cls_4byte.c libffi.closures/cls_24byte.c \
+libffi.closures/nested_struct10.c libffi.closures/cls_uint.c \
+libffi.closures/cls_12byte.c libffi.closures/cls_sint.c \
+libffi.closures/cls_7_1_byte.c libffi.closures/cls_sshort.c \
+libffi.closures/cls_16byte.c libffi.closures/nested_struct7.c \
+libffi.closures/cls_double_va.c libffi.closures/cls_3byte2.c \
+libffi.closures/cls_double.c libffi.closures/cls_7byte.c \
+libffi.closures/closure_fn6.c libffi.closures/closure_fn1.c \
+libffi.closures/cls_20byte.c libffi.closures/cls_18byte.c \
+libffi.closures/err_bad_abi.c
diff --git a/js/src/ctypes/libffi/testsuite/Makefile.in b/js/src/ctypes/libffi/testsuite/Makefile.in
new file mode 100644
index 0000000000..36465e9fab
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/Makefile.in
@@ -0,0 +1,647 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = testsuite
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \
+ $(top_srcdir)/m4/ax_append_flag.m4 \
+ $(top_srcdir)/m4/ax_cc_maxopt.m4 \
+ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
+ $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+ $(top_srcdir)/m4/ax_compiler_vendor.m4 \
+ $(top_srcdir)/m4/ax_configure_args.m4 \
+ $(top_srcdir)/m4/ax_enable_builddir.m4 \
+ $(top_srcdir)/m4/ax_gcc_archflag.m4 \
+ $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
+ $(top_srcdir)/m4/ax_require_defined.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/fficonfig.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DEJATOOL = $(PACKAGE)
+RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
+EXPECT = expect
+RUNTEST = runtest
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AM_LTLDFLAGS = @AM_LTLDFLAGS@
+AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
+HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPT_LDFLAGS = @OPT_LDFLAGS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PRTDIAG = @PRTDIAG@
+RANLIB = @RANLIB@
+SECTION_LDFLAGS = @SECTION_LDFLAGS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TARGET = @TARGET@
+TARGETDIR = @TARGETDIR@
+TARGET_OBJ = @TARGET_OBJ@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_enable_builddir_sed = @ax_enable_builddir_sed@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sys_symbol_underscore = @sys_symbol_underscore@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign dejagnu
+EXTRA_DEJAGNU_SITE_CONFIG = ../local.exp
+CLEANFILES = *.exe core* *.log *.sum
+EXTRA_DIST = lib/target-libpath.exp lib/libffi.exp lib/wrapper.exp \
+libffi.call/strlen4.c libffi.call/struct10.c libffi.call/many_mixed.c \
+libffi.call/float.c libffi.call/struct5.c libffi.call/return_fl3.c \
+libffi.call/return_fl1.c libffi.call/call.exp libffi.call/pyobjc-tc.c \
+libffi.call/float_va.c libffi.call/struct8.c libffi.call/pr1172638.c \
+libffi.call/return_sc.c libffi.call/va_struct1.c \
+libffi.call/align_stdcall.c libffi.call/struct9.c libffi.call/va_1.c \
+libffi.call/va_struct2.c libffi.call/return_fl2.c \
+libffi.call/align_mixed.c libffi.call/ffitest.h libffi.call/struct4.c \
+libffi.call/return_ldl.c libffi.call/float3.c libffi.call/return_sl.c \
+libffi.call/return_dbl1.c libffi.call/err_bad_typedef.c \
+libffi.call/return_ll1.c libffi.call/return_dbl2.c \
+libffi.call/negint.c libffi.closures/nested_struct3.c \
+libffi.call/struct2.c libffi.call/struct3.c libffi.call/return_fl.c \
+libffi.call/offsets.c libffi.call/struct7.c libffi.call/va_struct3.c \
+libffi.call/float1.c libffi.call/uninitialized.c libffi.call/many2.c \
+libffi.call/struct6.c libffi.call/strlen2.c libffi.call/float2.c \
+libffi.call/return_ul.c libffi.call/struct1.c libffi.call/strlen3.c \
+libffi.call/return_dbl.c libffi.call/float4.c libffi.call/many.c \
+libffi.call/strlen.c libffi.call/return_uc.c libffi.call/many_double.c \
+libffi.call/return_ll.c libffi.call/promotion.c \
+libffi.complex/complex_defs_longdouble.inc \
+libffi.complex/cls_align_complex_float.c \
+libffi.complex/cls_complex_va_float.c \
+libffi.complex/cls_complex_struct_float.c \
+libffi.complex/return_complex2_longdouble.c \
+libffi.complex/cls_complex_float.c \
+libffi.complex/return_complex_longdouble.c \
+libffi.complex/return_complex2_float.c libffi.complex/cls_complex.inc \
+libffi.complex/cls_complex_va_longdouble.c \
+libffi.complex/return_complex_double.c \
+libffi.complex/return_complex.inc libffi.complex/many_complex.inc \
+libffi.complex/complex_float.c libffi.complex/cls_align_complex.inc \
+libffi.complex/return_complex2_double.c \
+libffi.complex/many_complex_float.c libffi.complex/ffitest.h \
+libffi.complex/return_complex1_double.c \
+libffi.complex/cls_complex_struct_longdouble.c \
+libffi.complex/complex_defs_double.inc \
+libffi.complex/cls_complex_va_double.c \
+libffi.complex/many_complex_double.c \
+libffi.complex/return_complex2.inc \
+libffi.complex/return_complex1_float.c \
+libffi.complex/complex_longdouble.c \
+libffi.complex/complex_defs_float.inc \
+libffi.complex/cls_complex_double.c \
+libffi.complex/cls_align_complex_double.c \
+libffi.complex/cls_align_complex_longdouble.c \
+libffi.complex/complex_double.c libffi.complex/cls_complex_va.inc \
+libffi.complex/many_complex_longdouble.c libffi.complex/complex.inc \
+libffi.complex/return_complex1_longdouble.c \
+libffi.complex/complex_int.c libffi.complex/cls_complex_longdouble.c \
+libffi.complex/cls_complex_struct_double.c \
+libffi.complex/return_complex1.inc libffi.complex/complex.exp \
+libffi.complex/cls_complex_struct.inc \
+libffi.complex/return_complex_float.c libffi.go/closure1.c \
+libffi.go/aa-direct.c libffi.go/ffitest.h libffi.go/go.exp \
+libffi.go/static-chain.h libffi.bhaible/bhaible.exp \
+libffi.bhaible/test-call.c libffi.bhaible/alignof.h \
+libffi.bhaible/testcases.c libffi.bhaible/test-callback.c \
+libffi.bhaible/Makefile libffi.bhaible/README config/default.exp \
+libffi.closures/cls_multi_sshort.c \
+libffi.closures/cls_align_longdouble_split2.c \
+libffi.closures/cls_1_1byte.c libffi.closures/cls_uint_va.c \
+libffi.closures/cls_3_1byte.c libffi.closures/cls_many_mixed_args.c \
+libffi.closures/cls_20byte1.c libffi.closures/cls_pointer_stack.c \
+libffi.closures/cls_align_float.c libffi.closures/cls_5_1_byte.c \
+libffi.closures/cls_9byte1.c libffi.closures/cls_align_uint32.c \
+libffi.closures/stret_medium.c libffi.closures/cls_3byte1.c \
+libffi.closures/cls_align_uint64.c libffi.closures/cls_longdouble_va.c \
+libffi.closures/cls_align_pointer.c libffi.closures/cls_19byte.c \
+libffi.closures/cls_ushort.c libffi.closures/cls_align_sint32.c \
+libffi.closures/cls_ulonglong.c libffi.closures/cls_struct_va1.c \
+libffi.closures/cls_9byte2.c libffi.closures/closure_fn5.c \
+libffi.closures/cls_5byte.c libffi.closures/cls_3float.c \
+libffi.closures/closure.exp libffi.closures/cls_schar.c \
+libffi.closures/closure_fn4.c libffi.closures/cls_uchar_va.c \
+libffi.closures/closure_fn0.c libffi.closures/huge_struct.c \
+libffi.closures/cls_ushort_va.c \
+libffi.closures/cls_64byte.c libffi.closures/cls_longdouble.c \
+libffi.closures/cls_ulong_va.c libffi.closures/cls_6_1_byte.c \
+libffi.closures/cls_align_uint16.c libffi.closures/closure_fn2.c \
+libffi.closures/unwindtest_ffi_call.cc \
+libffi.closures/cls_multi_ushortchar.c libffi.closures/cls_8byte.c \
+libffi.closures/ffitest.h libffi.closures/nested_struct8.c \
+libffi.closures/cls_pointer.c libffi.closures/nested_struct2.c \
+libffi.closures/nested_struct.c libffi.closures/cls_multi_schar.c \
+libffi.closures/cls_align_longdouble_split.c \
+libffi.closures/cls_uchar.c libffi.closures/nested_struct9.c \
+libffi.closures/cls_float.c libffi.closures/stret_medium2.c \
+libffi.closures/closure_loc_fn0.c libffi.closures/cls_6byte.c \
+libffi.closures/closure_simple.c libffi.closures/cls_align_double.c \
+libffi.closures/cls_multi_uchar.c libffi.closures/cls_4_1byte.c \
+libffi.closures/closure_fn3.c libffi.closures/cls_align_sint64.c \
+libffi.closures/nested_struct1.c libffi.closures/unwindtest.cc \
+libffi.closures/nested_struct5.c libffi.closures/cls_multi_ushort.c \
+libffi.closures/nested_struct11.c \
+libffi.closures/cls_multi_sshortchar.c \
+libffi.closures/cls_align_longdouble.c \
+libffi.closures/cls_dbls_struct.c \
+libffi.closures/cls_many_mixed_float_double.c \
+libffi.closures/stret_large.c libffi.closures/stret_large2.c \
+libffi.closures/cls_align_sint16.c libffi.closures/cls_2byte.c \
+libffi.closures/nested_struct4.c libffi.closures/problem1.c \
+libffi.closures/testclosure.c libffi.closures/nested_struct6.c \
+libffi.closures/cls_4byte.c libffi.closures/cls_24byte.c \
+libffi.closures/nested_struct10.c libffi.closures/cls_uint.c \
+libffi.closures/cls_12byte.c libffi.closures/cls_sint.c \
+libffi.closures/cls_7_1_byte.c libffi.closures/cls_sshort.c \
+libffi.closures/cls_16byte.c libffi.closures/nested_struct7.c \
+libffi.closures/cls_double_va.c libffi.closures/cls_3byte2.c \
+libffi.closures/cls_double.c libffi.closures/cls_7byte.c \
+libffi.closures/closure_fn6.c libffi.closures/closure_fn1.c \
+libffi.closures/cls_20byte.c libffi.closures/cls_18byte.c \
+libffi.closures/err_bad_abi.c
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign testsuite/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+check-DEJAGNU: site.exp
+ srcdir='$(srcdir)'; export srcdir; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ if $(SHELL) -c "$(RUNTEST) --version" > /dev/null 2>&1; then \
+ exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \
+ if $(RUNTEST) $(RUNTESTDEFAULTFLAGS) $(AM_RUNTESTFLAGS) $(RUNTESTFLAGS); \
+ then :; else exit_status=1; fi; \
+ done; \
+ else echo "WARNING: could not find '$(RUNTEST)'" 1>&2; :;\
+ fi; \
+ exit $$exit_status
+site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG)
+ @echo 'Making a new site.exp file ...'
+ @echo '## these variables are automatically generated by make ##' >site.tmp
+ @echo '# Do not edit here. If you wish to override these values' >>site.tmp
+ @echo '# edit the last section' >>site.tmp
+ @echo 'set srcdir "$(srcdir)"' >>site.tmp
+ @echo "set objdir `pwd`" >>site.tmp
+ @echo 'set build_alias "$(build_alias)"' >>site.tmp
+ @echo 'set build_triplet $(build_triplet)' >>site.tmp
+ @echo 'set host_alias "$(host_alias)"' >>site.tmp
+ @echo 'set host_triplet $(host_triplet)' >>site.tmp
+ @echo 'set target_alias "$(target_alias)"' >>site.tmp
+ @echo 'set target_triplet $(target_triplet)' >>site.tmp
+ @list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \
+ echo "## Begin content included from file $$f. Do not modify. ##" \
+ && cat `test -f "$$f" || echo '$(srcdir)/'`$$f \
+ && echo "## End content included from file $$f. ##" \
+ || exit 1; \
+ done >> site.tmp
+ @echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp
+ @if test -f site.exp; then \
+ sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \
+ fi
+ @-rm -f site.bak
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv site.tmp site.exp
+
+distclean-DEJAGNU:
+ -rm -f site.exp site.bak
+ -l='$(DEJATOOL)'; for tool in $$l; do \
+ rm -f $$tool.sum $$tool.log; \
+ done
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-DEJAGNU distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags-am distclean \
+ distclean-DEJAGNU distclean-generic distclean-libtool distdir \
+ dvi dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/js/src/ctypes/libffi/testsuite/config/default.exp b/js/src/ctypes/libffi/testsuite/config/default.exp
new file mode 100644
index 0000000000..90967cccc1
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/config/default.exp
@@ -0,0 +1 @@
+load_lib "standard.exp"
diff --git a/js/src/ctypes/libffi/testsuite/lib/libffi.exp b/js/src/ctypes/libffi/testsuite/lib/libffi.exp
new file mode 100644
index 0000000000..c02adf9534
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/lib/libffi.exp
@@ -0,0 +1,640 @@
+# Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011, 2014, 2019 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+proc load_gcc_lib { filename } {
+ global srcdir
+ load_file $srcdir/lib/$filename
+}
+
+load_lib dg.exp
+load_lib libgloss.exp
+load_gcc_lib target-libpath.exp
+load_gcc_lib wrapper.exp
+
+# Return 1 if the target matches the effective target 'arg', 0 otherwise.
+# This can be used with any check_* proc that takes no argument and
+# returns only 1 or 0. It could be used with check_* procs that take
+# arguments with keywords that pass particular arguments.
+
+proc is-effective-target { arg } {
+ global et_index
+ set selected 0
+ if { ![info exists et_index] } {
+ # Initialize the effective target index that is used in some
+ # check_effective_target_* procs.
+ set et_index 0
+ }
+ if { [info procs check_effective_target_${arg}] != [list] } {
+ set selected [check_effective_target_${arg}]
+ } else {
+ error "unknown effective target keyword `$arg'"
+ }
+ verbose "is-effective-target: $arg $selected" 2
+ return $selected
+}
+
+proc is-effective-target-keyword { arg } {
+ if { [info procs check_effective_target_${arg}] != [list] } {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+# Intercept the call to the DejaGnu version of dg-process-target to
+# support use of an effective-target keyword in place of a list of
+# target triplets to xfail or skip a test.
+#
+# The argument to dg-process-target is the keyword "target" or "xfail"
+# followed by a selector:
+# target-triplet-1 ...
+# effective-target-keyword
+# selector-expression
+#
+# For a target list the result is "S" if the target is selected, "N" otherwise.
+# For an xfail list the result is "F" if the target is affected, "P" otherwise.
+
+# In contexts that allow either "target" or "xfail" the argument can be
+# target selector1 xfail selector2
+# which returns "N" if selector1 is not selected, otherwise the result of
+# "xfail selector2".
+#
+# A selector expression appears within curly braces and uses a single logical
+# operator: !, &&, or ||. An operand is another selector expression, an
+# effective-target keyword, or a list of target triplets within quotes or
+# curly braces.
+
+if { [info procs saved-dg-process-target] == [list] } {
+ rename dg-process-target saved-dg-process-target
+
+ # Evaluate an operand within a selector expression.
+ proc selector_opd { op } {
+ set selector "target"
+ lappend selector $op
+ set answer [ expr { [dg-process-target $selector] == "S" } ]
+ verbose "selector_opd: `$op' $answer" 2
+ return $answer
+ }
+
+ # Evaluate a target triplet list within a selector expression.
+ # Unlike other operands, this needs to be expanded from a list to
+ # the same string as "target".
+ proc selector_list { op } {
+ set selector "target [join $op]"
+ set answer [ expr { [dg-process-target $selector] == "S" } ]
+ verbose "selector_list: `$op' $answer" 2
+ return $answer
+ }
+
+ # Evaluate a selector expression.
+ proc selector_expression { exp } {
+ if { [llength $exp] == 2 } {
+ if [string match "!" [lindex $exp 0]] {
+ set op1 [lindex $exp 1]
+ set answer [expr { ! [selector_opd $op1] }]
+ } else {
+ # Assume it's a list of target triplets.
+ set answer [selector_list $exp]
+ }
+ } elseif { [llength $exp] == 3 } {
+ set op1 [lindex $exp 0]
+ set opr [lindex $exp 1]
+ set op2 [lindex $exp 2]
+ if [string match "&&" $opr] {
+ set answer [expr { [selector_opd $op1] && [selector_opd $op2] }]
+ } elseif [string match "||" $opr] {
+ set answer [expr { [selector_opd $op1] || [selector_opd $op2] }]
+ } else {
+ # Assume it's a list of target triplets.
+ set answer [selector_list $exp]
+ }
+ } else {
+ # Assume it's a list of target triplets.
+ set answer [selector_list $exp]
+ }
+
+ verbose "selector_expression: `$exp' $answer" 2
+ return $answer
+ }
+
+ # Evaluate "target selector" or "xfail selector".
+
+ proc dg-process-target-1 { args } {
+ verbose "dg-process-target-1: `$args'" 2
+
+ # Extract the 'what' keyword from the argument list.
+ set selector [string trim [lindex $args 0]]
+ if [regexp "^xfail " $selector] {
+ set what "xfail"
+ } elseif [regexp "^target " $selector] {
+ set what "target"
+ } else {
+ error "syntax error in target selector \"$selector\""
+ }
+
+ # Extract the rest of the list, which might be a keyword.
+ regsub "^${what}" $selector "" rest
+ set rest [string trim $rest]
+
+ if [is-effective-target-keyword $rest] {
+ # The selector is an effective target keyword.
+ if [is-effective-target $rest] {
+ return [expr { $what == "xfail" ? "F" : "S" }]
+ } else {
+ return [expr { $what == "xfail" ? "P" : "N" }]
+ }
+ }
+
+ if [string match "{*}" $rest] {
+ if [selector_expression [lindex $rest 0]] {
+ return [expr { $what == "xfail" ? "F" : "S" }]
+ } else {
+ return [expr { $what == "xfail" ? "P" : "N" }]
+ }
+ }
+
+ # The selector is not an effective-target keyword, so process
+ # the list of target triplets.
+ return [saved-dg-process-target $selector]
+ }
+
+ # Intercept calls to the DejaGnu function. In addition to
+ # processing "target selector" or "xfail selector", handle
+ # "target selector1 xfail selector2".
+
+ proc dg-process-target { args } {
+ verbose "replacement dg-process-target: `$args'" 2
+
+ set selector [string trim [lindex $args 0]]
+
+ # If the argument list contains both 'target' and 'xfail',
+ # process 'target' and, if that succeeds, process 'xfail'.
+ if [regexp "^target .* xfail .*" $selector] {
+ set xfail_index [string first "xfail" $selector]
+ set xfail_selector [string range $selector $xfail_index end]
+ set target_selector [string range $selector 0 [expr $xfail_index-1]]
+ set target_selector [string trim $target_selector]
+ if { [dg-process-target-1 $target_selector] == "N" } {
+ return "N"
+ }
+ return [dg-process-target-1 $xfail_selector]
+
+ }
+ return [dg-process-target-1 $selector]
+ }
+}
+
+# Define libffi callbacks for dg.exp.
+
+proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } {
+
+ # To get all \n in dg-output test strings to match printf output
+ # in a system that outputs it as \015\012 (i.e. not just \012), we
+ # need to change all \n into \r?\n. As there is no dejagnu flag
+ # or hook to do that, we simply change the text being tested.
+ # Unfortunately, we have to know that the variable is called
+ # dg-output-text and lives in the caller of libffi-dg-test, which
+ # is two calls up. Overriding proc dg-output would be longer and
+ # would necessarily have the same assumption.
+ upvar 2 dg-output-text output_match
+
+ if { [llength $output_match] > 1 } {
+ regsub -all "\n" [lindex $output_match 1] "\r?\n" x
+ set output_match [lreplace $output_match 1 1 $x]
+ }
+
+ # Set up the compiler flags, based on what we're going to do.
+
+ set options [list]
+ switch $do_what {
+ "compile" {
+ set compile_type "assembly"
+ set output_file "[file rootname [file tail $prog]].s"
+ }
+ "link" {
+ set compile_type "executable"
+ set output_file "[file rootname [file tail $prog]].exe"
+ # The following line is needed for targets like the i960 where
+ # the default output file is b.out. Sigh.
+ }
+ "run" {
+ set compile_type "executable"
+ # FIXME: "./" is to cope with "." not being in $PATH.
+ # Should this be handled elsewhere?
+ # YES.
+ set output_file "./[file rootname [file tail $prog]].exe"
+ # This is the only place where we care if an executable was
+ # created or not. If it was, dg.exp will try to run it.
+ remote_file build delete $output_file;
+ }
+ default {
+ perror "$do_what: not a valid dg-do keyword"
+ return ""
+ }
+ }
+
+ if { $extra_tool_flags != "" } {
+ lappend options "additional_flags=$extra_tool_flags"
+ }
+
+ set comp_output [libffi_target_compile "$prog" "$output_file" "$compile_type" $options];
+
+
+ return [list $comp_output $output_file]
+}
+
+
+proc libffi-dg-test { prog do_what extra_tool_flags } {
+ return [libffi-dg-test-1 target_compile $prog $do_what $extra_tool_flags]
+}
+
+proc libffi-dg-prune { target_triplet text } {
+ # We get this with some qemu emulated systems (eg. ppc64le-linux-gnu)
+ regsub -all "(^|\n)\[^\n\]*unable to perform all requested operations" $text "" text
+ return $text
+}
+
+proc libffi-init { args } {
+ global gluefile wrap_flags;
+ global srcdir
+ global blddirffi
+ global objdir
+ global TOOL_OPTIONS
+ global tool
+ global libffi_include
+ global libffi_link_flags
+ global tool_root_dir
+ global ld_library_path
+ global compiler_vendor
+
+ if ![info exists blddirffi] {
+ set blddirffi [pwd]/..
+ }
+
+ verbose "libffi $blddirffi"
+
+ # Which compiler are we building with?
+ set tmp [grep "$blddirffi/config.log" "^ax_cv_c_compiler_vendor.*$"]
+ regexp -- {^[^=]*=(.*)$} $tmp nil compiler_vendor
+
+ if { [string match $compiler_vendor "gnu"] } {
+ set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
+ if {$gccdir != ""} {
+ set gccdir [file dirname $gccdir]
+ }
+ verbose "gccdir $gccdir"
+
+ set ld_library_path "."
+ append ld_library_path ":${gccdir}"
+
+ set compiler "${gccdir}/xgcc"
+ if { [is_remote host] == 0 && [which $compiler] != 0 } {
+ foreach i "[exec $compiler --print-multi-lib]" {
+ set mldir ""
+ regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
+ set mldir [string trimright $mldir "\;@"]
+ if { "$mldir" == "." } {
+ continue
+ }
+ if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
+ append ld_library_path ":${gccdir}/${mldir}"
+ }
+ }
+ }
+ }
+
+ # add the library path for libffi.
+ append ld_library_path ":${blddirffi}/.libs"
+
+ verbose "ld_library_path: $ld_library_path"
+
+ # Point to the Libffi headers in libffi.
+ set libffi_include "${blddirffi}/include"
+ verbose "libffi_include $libffi_include"
+
+ set libffi_dir "${blddirffi}/.libs"
+ verbose "libffi_dir $libffi_dir"
+ if { $libffi_dir != "" } {
+ set libffi_dir [file dirname ${libffi_dir}]
+ set libffi_link_flags "-L${libffi_dir}/.libs"
+ }
+
+ set_ld_library_path_env_vars
+ libffi_maybe_build_wrapper "${objdir}/testglue.o"
+}
+
+proc libffi_exit { } {
+ global gluefile;
+
+ if [info exists gluefile] {
+ file_on_build delete $gluefile;
+ unset gluefile;
+ }
+}
+
+proc libffi_target_compile { source dest type options } {
+ global gluefile wrap_flags;
+ global srcdir
+ global blddirffi
+ global TOOL_OPTIONS
+ global libffi_link_flags
+ global libffi_include
+ global target_triplet
+ global compiler_vendor
+
+ if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } {
+ lappend options "libs=${gluefile}"
+ lappend options "ldflags=$wrap_flags"
+ }
+
+ # TOOL_OPTIONS must come first, so that it doesn't override testcase
+ # specific options.
+ if [info exists TOOL_OPTIONS] {
+ lappend options "additional_flags=$TOOL_OPTIONS"
+ }
+
+ # search for ffi_mips.h in srcdir, too
+ lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include -I${libffi_include}/.."
+ lappend options "additional_flags=${libffi_link_flags}"
+
+ # Darwin needs a stack execution allowed flag.
+
+ if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"]
+ || [istarget "*-*-darwin2*"] } {
+ lappend options "additional_flags=-Wl,-allow_stack_execute"
+ }
+
+ # If you're building the compiler with --prefix set to a place
+ # where it's not yet installed, then the linker won't be able to
+ # find the libgcc used by libffi.dylib. We could pass the
+ # -dylib_file option, but that's complicated, and it's much easier
+ # to just make the linker find libgcc using -L options.
+ if { [string match "*-*-darwin*" $target_triplet] } {
+ lappend options "libs= -shared-libgcc"
+ }
+
+ if { [string match "*-*-openbsd*" $target_triplet] } {
+ lappend options "libs= -lpthread"
+ }
+
+ lappend options "libs= -lffi"
+
+ if { [string match "aarch64*-*-linux*" $target_triplet] } {
+ lappend options "libs= -lpthread"
+ }
+
+ # this may be required for g++, but just confused clang.
+ if { [string match "*.cc" $source] } {
+ lappend options "c++"
+ }
+
+ if { [string match "arc*-*-linux*" $target_triplet] } {
+ lappend options "libs= -lpthread"
+ }
+
+ verbose "options: $options"
+ return [target_compile $source $dest $type $options]
+}
+
+# TEST should be a preprocessor condition. Returns true if it holds.
+proc libffi_feature_test { test } {
+ set src "ffitest[pid].c"
+
+ set f [open $src "w"]
+ puts $f "#include <ffi.h>"
+ puts $f $test
+ puts $f "/* OK */"
+ puts $f "#else"
+ puts $f "# error Failed $test"
+ puts $f "#endif"
+ close $f
+
+ set lines [libffi_target_compile $src /dev/null assembly ""]
+ file delete $src
+
+ return [string match "" $lines]
+}
+
+# Utility routines.
+
+#
+# search_for -- looks for a string match in a file
+#
+proc search_for { file pattern } {
+ set fd [open $file r]
+ while { [gets $fd cur_line]>=0 } {
+ if [string match "*$pattern*" $cur_line] then {
+ close $fd
+ return 1
+ }
+ }
+ close $fd
+ return 0
+}
+
+# Modified dg-runtest that can cycle through a list of optimization options
+# as c-torture does.
+proc libffi-dg-runtest { testcases default-extra-flags } {
+ global runtests
+
+ foreach test $testcases {
+ # If we're only testing specific files and this isn't one of
+ # them, skip it.
+ if ![runtest_file_p $runtests $test] {
+ continue
+ }
+
+ # Look for a loop within the source code - if we don't find one,
+ # don't pass -funroll[-all]-loops.
+ global torture_with_loops torture_without_loops
+ if [expr [search_for $test "for*("]+[search_for $test "while*("]] {
+ set option_list $torture_with_loops
+ } else {
+ set option_list $torture_without_loops
+ }
+
+ set nshort [file tail [file dirname $test]]/[file tail $test]
+
+ foreach flags $option_list {
+ verbose "Testing $nshort, $flags" 1
+ dg-test $test $flags ${default-extra-flags}
+ }
+ }
+}
+
+proc run-many-tests { testcases extra_flags } {
+ global compiler_vendor
+ global env
+ switch $compiler_vendor {
+ "clang" {
+ set common "-W -Wall"
+ if [info exists env(LIBFFI_TEST_OPTIMIZATION)] {
+ set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ]
+ } else {
+ set optimizations { "-O0" "-O2" }
+ }
+ }
+ "gnu" {
+ set common "-W -Wall -Wno-psabi"
+ if [info exists env(LIBFFI_TEST_OPTIMIZATION)] {
+ set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ]
+ } else {
+ set optimizations { "-O0" "-O2" }
+ }
+ }
+ default {
+ # Assume we are using the vendor compiler.
+ set common ""
+ if [info exists env(LIBFFI_TEST_OPTIMIZATION)] {
+ set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ]
+ } else {
+ set optimizations { "" }
+ }
+ }
+ }
+
+ info exists env(LD_LIBRARY_PATH)
+
+ set targetabis { "" }
+ if [string match $compiler_vendor "gnu"] {
+ if [libffi_feature_test "#ifdef __i386__"] {
+ set targetabis {
+ ""
+ "-DABI_NUM=FFI_STDCALL -DABI_ATTR=__STDCALL__"
+ "-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__"
+ "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__"
+ }
+ } elseif { [istarget "x86_64-*-*"] \
+ && [libffi_feature_test "#if !defined __ILP32__ \
+ && !defined __i386__"] } {
+ set targetabis {
+ ""
+ "-DABI_NUM=FFI_GNUW64 -DABI_ATTR=__MSABI__"
+ }
+ }
+ }
+
+ set common [ concat $common $extra_flags ]
+ foreach test $testcases {
+ set testname [file tail $test]
+ if [search_for $test "ABI_NUM"] {
+ set abis $targetabis
+ } else {
+ set abis { "" }
+ }
+ foreach opt $optimizations {
+ foreach abi $abis {
+ set options [concat $common $opt $abi]
+ verbose "Testing $testname, $options" 1
+ dg-test $test $options ""
+ }
+ }
+ }
+}
+
+# Like check_conditional_xfail, but callable from a dg test.
+
+proc dg-xfail-if { args } {
+ set args [lreplace $args 0 0]
+ set selector "target [join [lindex $args 1]]"
+ if { [dg-process-target $selector] == "S" } {
+ global compiler_conditional_xfail_data
+ set compiler_conditional_xfail_data $args
+ }
+}
+
+proc check-flags { args } {
+
+ # The args are within another list; pull them out.
+ set args [lindex $args 0]
+
+ # The next two arguments are optional. If they were not specified,
+ # use the defaults.
+ if { [llength $args] == 2 } {
+ lappend $args [list "*"]
+ }
+ if { [llength $args] == 3 } {
+ lappend $args [list ""]
+ }
+
+ # If the option strings are the defaults, or the same as the
+ # defaults, there is no need to call check_conditional_xfail to
+ # compare them to the actual options.
+ if { [string compare [lindex $args 2] "*"] == 0
+ && [string compare [lindex $args 3] "" ] == 0 } {
+ set result 1
+ } else {
+ # The target list might be an effective-target keyword, so replace
+ # the original list with "*-*-*", since we already know it matches.
+ set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]]
+ }
+
+ return $result
+}
+
+proc dg-skip-if { args } {
+ # Verify the number of arguments. The last two are optional.
+ set args [lreplace $args 0 0]
+ if { [llength $args] < 2 || [llength $args] > 4 } {
+ error "dg-skip-if 2: need 2, 3, or 4 arguments"
+ }
+
+ # Don't bother if we're already skipping the test.
+ upvar dg-do-what dg-do-what
+ if { [lindex ${dg-do-what} 1] == "N" } {
+ return
+ }
+
+ set selector [list target [lindex $args 1]]
+ if { [dg-process-target $selector] == "S" } {
+ if [check-flags $args] {
+ upvar dg-do-what dg-do-what
+ set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+ }
+ }
+}
+
+# We need to make sure that additional_files and additional_sources
+# are both cleared out after every test. It is not enough to clear
+# them out *before* the next test run because gcc-target-compile gets
+# run directly from some .exp files (outside of any test). (Those
+# uses should eventually be eliminated.)
+
+# Because the DG framework doesn't provide a hook that is run at the
+# end of a test, we must replace dg-test with a wrapper.
+
+if { [info procs saved-dg-test] == [list] } {
+ rename dg-test saved-dg-test
+
+ proc dg-test { args } {
+ global additional_files
+ global additional_sources
+ global errorInfo
+
+ if { [ catch { eval saved-dg-test $args } errmsg ] } {
+ set saved_info $errorInfo
+ set additional_files ""
+ set additional_sources ""
+ error $errmsg $saved_info
+ }
+ set additional_files ""
+ set additional_sources ""
+ }
+}
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/js/src/ctypes/libffi/testsuite/lib/target-libpath.exp b/js/src/ctypes/libffi/testsuite/lib/target-libpath.exp
new file mode 100644
index 0000000000..6b7beba935
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/lib/target-libpath.exp
@@ -0,0 +1,283 @@
+# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# This file was contributed by John David Anglin (dave.anglin@nrc-cnrc.gc.ca)
+
+set orig_environment_saved 0
+set orig_ld_library_path_saved 0
+set orig_ld_run_path_saved 0
+set orig_shlib_path_saved 0
+set orig_ld_libraryn32_path_saved 0
+set orig_ld_library64_path_saved 0
+set orig_ld_library_path_32_saved 0
+set orig_ld_library_path_64_saved 0
+set orig_dyld_library_path_saved 0
+set orig_path_saved 0
+
+#######################################
+# proc set_ld_library_path_env_vars { }
+#######################################
+
+proc set_ld_library_path_env_vars { } {
+ global ld_library_path
+ global orig_environment_saved
+ global orig_ld_library_path_saved
+ global orig_ld_run_path_saved
+ global orig_shlib_path_saved
+ global orig_ld_libraryn32_path_saved
+ global orig_ld_library64_path_saved
+ global orig_ld_library_path_32_saved
+ global orig_ld_library_path_64_saved
+ global orig_dyld_library_path_saved
+ global orig_path_saved
+ global orig_ld_library_path
+ global orig_ld_run_path
+ global orig_shlib_path
+ global orig_ld_libraryn32_path
+ global orig_ld_library64_path
+ global orig_ld_library_path_32
+ global orig_ld_library_path_64
+ global orig_dyld_library_path
+ global orig_path
+ global GCC_EXEC_PREFIX
+
+ # Set the relocated compiler prefix, but only if the user hasn't specified one.
+ if { [info exists GCC_EXEC_PREFIX] && ![info exists env(GCC_EXEC_PREFIX)] } {
+ setenv GCC_EXEC_PREFIX "$GCC_EXEC_PREFIX"
+ }
+
+ # Setting the ld library path causes trouble when testing cross-compilers.
+ if { [is_remote target] } {
+ return
+ }
+
+ if { $orig_environment_saved == 0 } {
+ global env
+
+ set orig_environment_saved 1
+
+ # Save the original environment.
+ if [info exists env(LD_LIBRARY_PATH)] {
+ set orig_ld_library_path "$env(LD_LIBRARY_PATH)"
+ set orig_ld_library_path_saved 1
+ }
+ if [info exists env(LD_RUN_PATH)] {
+ set orig_ld_run_path "$env(LD_RUN_PATH)"
+ set orig_ld_run_path_saved 1
+ }
+ if [info exists env(SHLIB_PATH)] {
+ set orig_shlib_path "$env(SHLIB_PATH)"
+ set orig_shlib_path_saved 1
+ }
+ if [info exists env(LD_LIBRARYN32_PATH)] {
+ set orig_ld_libraryn32_path "$env(LD_LIBRARYN32_PATH)"
+ set orig_ld_libraryn32_path_saved 1
+ }
+ if [info exists env(LD_LIBRARY64_PATH)] {
+ set orig_ld_library64_path "$env(LD_LIBRARY64_PATH)"
+ set orig_ld_library64_path_saved 1
+ }
+ if [info exists env(LD_LIBRARY_PATH_32)] {
+ set orig_ld_library_path_32 "$env(LD_LIBRARY_PATH_32)"
+ set orig_ld_library_path_32_saved 1
+ }
+ if [info exists env(LD_LIBRARY_PATH_64)] {
+ set orig_ld_library_path_64 "$env(LD_LIBRARY_PATH_64)"
+ set orig_ld_library_path_64_saved 1
+ }
+ if [info exists env(DYLD_LIBRARY_PATH)] {
+ set orig_dyld_library_path "$env(DYLD_LIBRARY_PATH)"
+ set orig_dyld_library_path_saved 1
+ }
+ if [info exists env(PATH)] {
+ set orig_path "$env(PATH)"
+ set orig_path_saved 1
+ }
+ }
+
+ # We need to set ld library path in the environment. Currently,
+ # unix.exp doesn't set the environment correctly for all systems.
+ # It only sets SHLIB_PATH and LD_LIBRARY_PATH when it executes a
+ # program. We also need the environment set for compilations, etc.
+ #
+ # On IRIX 6, we have to set variables akin to LD_LIBRARY_PATH, but
+ # called LD_LIBRARYN32_PATH (for the N32 ABI) and LD_LIBRARY64_PATH
+ # (for the 64-bit ABI). The same applies to Darwin (DYLD_LIBRARY_PATH),
+ # Solaris 32 bit (LD_LIBRARY_PATH_32), Solaris 64 bit (LD_LIBRARY_PATH_64),
+ # and HP-UX (SHLIB_PATH). In some cases, the variables are independent
+ # of LD_LIBRARY_PATH, and in other cases LD_LIBRARY_PATH is used if the
+ # variable is not defined.
+ #
+ # Doing this is somewhat of a hack as ld_library_path gets repeated in
+ # SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables.
+ if { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path"
+ } else {
+ setenv LD_LIBRARY_PATH "$ld_library_path"
+ }
+ if { $orig_ld_run_path_saved } {
+ setenv LD_RUN_PATH "$ld_library_path:$orig_ld_run_path"
+ } else {
+ setenv LD_RUN_PATH "$ld_library_path"
+ }
+ # The default shared library dynamic path search for 64-bit
+ # HP-UX executables searches LD_LIBRARY_PATH before SHLIB_PATH.
+ # LD_LIBRARY_PATH isn't used for 32-bit executables. Thus, we
+ # set LD_LIBRARY_PATH and SHLIB_PATH as if they were independent.
+ if { $orig_shlib_path_saved } {
+ setenv SHLIB_PATH "$ld_library_path:$orig_shlib_path"
+ } else {
+ setenv SHLIB_PATH "$ld_library_path"
+ }
+ if { $orig_ld_libraryn32_path_saved } {
+ setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_libraryn32_path"
+ } elseif { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_library_path"
+ } else {
+ setenv LD_LIBRARYN32_PATH "$ld_library_path"
+ }
+ if { $orig_ld_library64_path_saved } {
+ setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library64_path"
+ } elseif { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library_path"
+ } else {
+ setenv LD_LIBRARY64_PATH "$ld_library_path"
+ }
+ if { $orig_ld_library_path_32_saved } {
+ setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path_32"
+ } elseif { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path"
+ } else {
+ setenv LD_LIBRARY_PATH_32 "$ld_library_path"
+ }
+ if { $orig_ld_library_path_64_saved } {
+ setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path_64"
+ } elseif { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path"
+ } else {
+ setenv LD_LIBRARY_PATH_64 "$ld_library_path"
+ }
+ if { $orig_dyld_library_path_saved } {
+ setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path"
+ } else {
+ setenv DYLD_LIBRARY_PATH "$ld_library_path"
+ }
+ if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
+ if { $orig_path_saved } {
+ setenv PATH "$ld_library_path:$orig_path"
+ } else {
+ setenv PATH "$ld_library_path"
+ }
+ }
+
+ verbose -log "set_ld_library_path_env_vars: ld_library_path=$ld_library_path"
+}
+
+#######################################
+# proc restore_ld_library_path_env_vars { }
+#######################################
+
+proc restore_ld_library_path_env_vars { } {
+ global orig_environment_saved
+ global orig_ld_library_path_saved
+ global orig_ld_run_path_saved
+ global orig_shlib_path_saved
+ global orig_ld_libraryn32_path_saved
+ global orig_ld_library64_path_saved
+ global orig_ld_library_path_32_saved
+ global orig_ld_library_path_64_saved
+ global orig_dyld_library_path_saved
+ global orig_path_saved
+ global orig_ld_library_path
+ global orig_ld_run_path
+ global orig_shlib_path
+ global orig_ld_libraryn32_path
+ global orig_ld_library64_path
+ global orig_ld_library_path_32
+ global orig_ld_library_path_64
+ global orig_dyld_library_path
+ global orig_path
+
+ if { $orig_environment_saved == 0 } {
+ return
+ }
+
+ if { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARY_PATH "$orig_ld_library_path"
+ } elseif [info exists env(LD_LIBRARY_PATH)] {
+ unsetenv LD_LIBRARY_PATH
+ }
+ if { $orig_ld_run_path_saved } {
+ setenv LD_RUN_PATH "$orig_ld_run_path"
+ } elseif [info exists env(LD_RUN_PATH)] {
+ unsetenv LD_RUN_PATH
+ }
+ if { $orig_shlib_path_saved } {
+ setenv SHLIB_PATH "$orig_shlib_path"
+ } elseif [info exists env(SHLIB_PATH)] {
+ unsetenv SHLIB_PATH
+ }
+ if { $orig_ld_libraryn32_path_saved } {
+ setenv LD_LIBRARYN32_PATH "$orig_ld_libraryn32_path"
+ } elseif [info exists env(LD_LIBRARYN32_PATH)] {
+ unsetenv LD_LIBRARYN32_PATH
+ }
+ if { $orig_ld_library64_path_saved } {
+ setenv LD_LIBRARY64_PATH "$orig_ld_library64_path"
+ } elseif [info exists env(LD_LIBRARY64_PATH)] {
+ unsetenv LD_LIBRARY64_PATH
+ }
+ if { $orig_ld_library_path_32_saved } {
+ setenv LD_LIBRARY_PATH_32 "$orig_ld_library_path_32"
+ } elseif [info exists env(LD_LIBRARY_PATH_32)] {
+ unsetenv LD_LIBRARY_PATH_32
+ }
+ if { $orig_ld_library_path_64_saved } {
+ setenv LD_LIBRARY_PATH_64 "$orig_ld_library_path_64"
+ } elseif [info exists env(LD_LIBRARY_PATH_64)] {
+ unsetenv LD_LIBRARY_PATH_64
+ }
+ if { $orig_dyld_library_path_saved } {
+ setenv DYLD_LIBRARY_PATH "$orig_dyld_library_path"
+ } elseif [info exists env(DYLD_LIBRARY_PATH)] {
+ unsetenv DYLD_LIBRARY_PATH
+ }
+ if { $orig_path_saved } {
+ setenv PATH "$orig_path"
+ } elseif [info exists env(PATH)] {
+ unsetenv PATH
+ }
+}
+
+#######################################
+# proc get_shlib_extension { }
+#######################################
+
+proc get_shlib_extension { } {
+ global shlib_ext
+
+ if { [ istarget *-*-darwin* ] } {
+ set shlib_ext "dylib"
+ } elseif { [ istarget *-*-cygwin* ] || [ istarget *-*-mingw* ] } {
+ set shlib_ext "dll"
+ } elseif { [ istarget hppa*-*-hpux* ] } {
+ set shlib_ext "sl"
+ } else {
+ set shlib_ext "so"
+ }
+ return $shlib_ext
+}
+
diff --git a/js/src/ctypes/libffi/testsuite/lib/wrapper.exp b/js/src/ctypes/libffi/testsuite/lib/wrapper.exp
new file mode 100644
index 0000000000..4e5ae435a1
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/lib/wrapper.exp
@@ -0,0 +1,45 @@
+# Copyright (C) 2004, 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# This file contains GCC-specifics for status wrappers for test programs.
+
+# ${tool}_maybe_build_wrapper -- Build wrapper object if the target
+# needs it. FILENAME is the path to the wrapper file. If there are
+# additional arguments, they are command-line options to provide to
+# the compiler when compiling FILENAME.
+
+proc ${tool}_maybe_build_wrapper { filename args } {
+ global gluefile wrap_flags
+
+ if { [target_info needs_status_wrapper] != "" \
+ && [target_info needs_status_wrapper] != "0" \
+ && ![info exists gluefile] } {
+ set saved_wrap_compile_flags [target_info wrap_compile_flags]
+ set flags [join $args " "]
+ # The wrapper code may contain code that gcc objects on. This
+ # became true for dejagnu-1.4.4. The set of warnings and code
+ # that gcc objects on may change, so just make sure -w is always
+ # passed to turn off all warnings.
+ set_currtarget_info wrap_compile_flags \
+ "$saved_wrap_compile_flags -w $flags"
+ set result [build_wrapper $filename]
+ set_currtarget_info wrap_compile_flags "$saved_wrap_compile_flags"
+ if { $result != "" } {
+ set gluefile [lindex $result 0]
+ set wrap_flags [lindex $result 1]
+ }
+ }
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.bhaible/Makefile b/js/src/ctypes/libffi/testsuite/libffi.bhaible/Makefile
new file mode 100644
index 0000000000..3322de94f7
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.bhaible/Makefile
@@ -0,0 +1,28 @@
+CC = gcc
+CFLAGS = -O2 -Wall
+prefix =
+includedir = $(prefix)/include
+libdir = $(prefix)/lib
+CPPFLAGS = -I$(includedir)
+LDFLAGS = -L$(libdir) -Wl,-rpath,$(libdir)
+
+all: check-call check-callback
+
+test-call: test-call.c testcases.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o test-call test-call.c -lffi
+
+test-callback: test-callback.c testcases.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o test-callback test-callback.c -lffi
+
+check-call: test-call
+ ./test-call > test-call.out
+ LC_ALL=C uniq -u < test-call.out > failed-call
+ test '!' -s failed-call
+
+check-callback: test-callback
+ ./test-callback > test-callback.out
+ LC_ALL=C uniq -u < test-callback.out > failed-callback
+ test '!' -s failed-callback
+
+clean:
+ rm -f test-call test-callback test-call.out test-callback.out failed-call failed-callback
diff --git a/js/src/ctypes/libffi/testsuite/libffi.bhaible/README b/js/src/ctypes/libffi/testsuite/libffi.bhaible/README
new file mode 100644
index 0000000000..be8540b64f
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.bhaible/README
@@ -0,0 +1,78 @@
+This package contains a test suite for libffi.
+
+This test suite can be compiled with a C compiler. No need for 'expect'
+or some other package that is often not installed.
+
+The test suite consists of 81 C functions, each with a different signature.
+* test-call verifies that calling each function directly produces the same
+ results as calling the function indirectly through 'ffi_call'.
+* test-callback verifies that calling each function directly produces the same
+ results as calling a function that is a callback (object build by
+ 'ffi_prep_closure_loc') and simulates the original function.
+
+Each direct or indirect invocation should produce one line of output to
+stdout. A correct output consists of paired lines, such as
+
+void f(void):
+void f(void):
+int f(void):->99
+int f(void):->99
+int f(int):(1)->2
+int f(int):(1)->2
+int f(2*int):(1,2)->3
+int f(2*int):(1,2)->3
+...
+
+The Makefile then creates two files:
+* failed-call, which consists of the non-paired lines of output of
+ 'test-call',
+* failed-callback, which consists of the non-paired lines of output of
+ 'test-callback'.
+
+The test suite passes if both failed-call and failed-callback come out
+as empty.
+
+
+How to use the test suite
+-------------------------
+
+1. Modify the Makefile's variables
+ prefix = the directory in which libffi was installed
+ CC = the C compiler, often with options such as "-m32" or "-m64"
+ that enforce a certain ABI,
+ CFLAGS = optimization options (need to change them only for non-GCC
+ compilers)
+2. Run "make". If it fails already in "test-call", run also
+ "make check-callback".
+3. If this failed, inspect the output files.
+
+
+How to interpret the results
+----------------------------
+
+The failed-call and failed-callback files consist of paired lines:
+The first line is the result of the direct invocation.
+The second line is the result of invocation through libffi.
+
+For example, this output
+
+uchar f(uchar,ushort,uint,ulong):(97,2,3,4)->255
+uchar f(uchar,ushort,uint,ulong):(97,2,3,4)->0
+
+indicates that the arguments were passed correctly, but the return
+value came out wrong.
+
+And this output
+
+float f(17*float,3*int,L):(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,6,7,8,561,1105,1729,2465,2821,6601)->15319.1
+float f(17*float,3*int,L):(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,-140443648,10,268042216,-72537980,-140443648,-140443648,-140443648,-140443648,-140443648)->-6.47158e+08
+
+indicates that integer arguments that come after 17 floating-point arguments
+were not passed correctly.
+
+
+Credits
+-------
+
+The test suite is based on the one of GNU libffcall-2.0.
+Authors: Bill Triggs, Bruno Haible
diff --git a/js/src/ctypes/libffi/testsuite/libffi.bhaible/alignof.h b/js/src/ctypes/libffi/testsuite/libffi.bhaible/alignof.h
new file mode 100644
index 0000000000..00604a513a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.bhaible/alignof.h
@@ -0,0 +1,50 @@
+/* Determine alignment of types.
+ Copyright (C) 2003-2004, 2006, 2009-2017 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _ALIGNOF_H
+#define _ALIGNOF_H
+
+#include <stddef.h>
+
+/* alignof_slot (TYPE)
+ Determine the alignment of a structure slot (field) of a given type,
+ at compile time. Note that the result depends on the ABI.
+ This is the same as alignof (TYPE) and _Alignof (TYPE), defined in
+ <stdalign.h> if __alignof_is_defined is 1.
+ Note: The result cannot be used as a value for an 'enum' constant,
+ due to bugs in HP-UX 10.20 cc and AIX 3.2.5 xlc. */
+#if defined __cplusplus
+ template <class type> struct alignof_helper { char __slot1; type __slot2; };
+# define alignof_slot(type) offsetof (alignof_helper<type>, __slot2)
+#else
+# define alignof_slot(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
+#endif
+
+/* alignof_type (TYPE)
+ Determine the good alignment of an object of the given type at compile time.
+ Note that this is not necessarily the same as alignof_slot(type).
+ For example, with GNU C on x86 platforms: alignof_type(double) = 8, but
+ - when -malign-double is not specified: alignof_slot(double) = 4,
+ - when -malign-double is specified: alignof_slot(double) = 8.
+ Note: The result cannot be used as a value for an 'enum' constant,
+ due to bugs in HP-UX 10.20 cc and AIX 3.2.5 xlc. */
+#if defined __GNUC__ || defined __IBM__ALIGNOF__
+# define alignof_type __alignof__
+#else
+# define alignof_type alignof_slot
+#endif
+
+#endif /* _ALIGNOF_H */
diff --git a/js/src/ctypes/libffi/testsuite/libffi.bhaible/bhaible.exp b/js/src/ctypes/libffi/testsuite/libffi.bhaible/bhaible.exp
new file mode 100644
index 0000000000..44aebc5e06
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.bhaible/bhaible.exp
@@ -0,0 +1,63 @@
+# Copyright (C) 2003, 2006, 2009, 2010, 2014, 2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+dg-init
+libffi-init
+
+global srcdir subdir
+global compiler_vendor
+
+# The conversion of this testsuite into a dejagnu compatible testsuite
+# was done in a pretty lazy fashion, and requires the use of compiler
+# flags to disable warnings for now.
+if { [string match $compiler_vendor "gnu"] } {
+ set warning_options "-Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized";
+}
+if { [string match $compiler_vendor "microsoft"] } {
+ # -wd4996 suggest use of vsprintf_s instead of vsprintf
+ # -wd4116 unnamed type definition
+ # -wd4101 unreferenced local variable
+ # -wd4244 warning about implicit double to float conversion
+ set warning_options "-wd4996 -wd4116 -wd4101 -wd4244";
+}
+if { ![string match $compiler_vendor "microsoft"] && ![string match $compiler_vendor "gnu"] } {
+ set warning_options "-Wno-unused-variable -Wno-unused-parameter -Wno-uninitialized";
+}
+
+
+set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/test-call.c]]
+
+for {set i 1} {$i < 82} {incr i} {
+ run-many-tests $tlist [format "-DDGTEST=%d %s" $i $warning_options]
+}
+
+set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/test-callback.c]]
+
+for {set i 1} {$i < 81} {incr i} {
+ if { [libffi_feature_test "#if FFI_CLOSURES"] } {
+ run-many-tests $tlist [format "-DDGTEST=%d %s" $i $warning_options]
+ } else {
+ foreach test $tlist {
+ unsupported [format "%s -DDGTEST=%d %s" $test $i $warning_options]
+ }
+ }
+}
+
+dg-finish
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/js/src/ctypes/libffi/testsuite/libffi.bhaible/test-call.c b/js/src/ctypes/libffi/testsuite/libffi.bhaible/test-call.c
new file mode 100644
index 0000000000..01a8a21570
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.bhaible/test-call.c
@@ -0,0 +1,1745 @@
+/**
+ Copyright 1993 Bill Triggs <Bill.Triggs@inrialpes.fr>
+ Copyright 1995-2017 Bruno Haible <bruno@clisp.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+**/
+
+/* { dg-do run } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ffi.h>
+#include "alignof.h"
+#include <stdarg.h>
+
+/* libffi testsuite local changes -------------------------------- */
+#ifdef DGTEST
+/* Redefine exit(1) as a test failure */
+#define exit(V) (void)((V) ? (abort(), 1) : exit(0))
+int count = 0;
+char rbuf1[2048];
+char rbuf2[2048];
+int _fprintf(FILE *stream, const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+
+ switch (count++)
+ {
+ case 0:
+ case 1:
+ vsprintf(&rbuf1[strlen(rbuf1)], format, args);
+ break;
+ case 2:
+ printf("%s", rbuf1);
+ vsprintf(rbuf2, format, args);
+ break;
+ case 3:
+ vsprintf(&rbuf2[strlen(rbuf2)], format, args);
+ printf("%s", rbuf2);
+ if (strcmp (rbuf1, rbuf2)) abort();
+ break;
+ }
+
+ va_end(args);
+
+ return 0;
+}
+#define fprintf _fprintf
+#endif
+/* --------------------------------------------------------------- */
+
+#include "testcases.c"
+
+#ifndef ABI_NUM
+#define ABI_NUM FFI_DEFAULT_ABI
+#endif
+
+/* Definitions that ought to be part of libffi. */
+static ffi_type ffi_type_char;
+#define ffi_type_slonglong ffi_type_sint64
+#define ffi_type_ulonglong ffi_type_uint64
+
+/* libffi does not support arrays inside structs. */
+#define SKIP_EXTRA_STRUCTS
+
+#define FFI_PREP_CIF(cif,argtypes,rettype) \
+ if (ffi_prep_cif(&(cif),ABI_NUM,sizeof(argtypes)/sizeof(argtypes[0]),&rettype,argtypes) != FFI_OK) abort()
+#define FFI_PREP_CIF_NOARGS(cif,rettype) \
+ if (ffi_prep_cif(&(cif),ABI_NUM,0,&rettype,NULL) != FFI_OK) abort()
+#define FFI_CALL(cif,fn,args,retaddr) \
+ ffi_call(&(cif),(void(*)(void))(fn),retaddr,args)
+
+long clear_traces_i (long a, long b, long c, long d, long e, long f, long g, long h,
+ long i, long j, long k, long l, long m, long n, long o, long p)
+{ return 0; }
+float clear_traces_f (float a, float b, float c, float d, float e, float f, float g,
+ float h, float i, float j, float k, float l, float m, float n,
+ float o, float p)
+{ return 0.0; }
+double clear_traces_d (double a, double b, double c, double d, double e, double f, double g,
+ double h, double i, double j, double k, double l, double m, double n,
+ double o, double p)
+{ return 0.0; }
+J clear_traces_J (void)
+{ J j; j.l1 = j.l2 = 0; return j; }
+void clear_traces (void)
+{ clear_traces_i(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+ clear_traces_f(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
+ clear_traces_d(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
+ clear_traces_J();
+}
+
+void
+ void_tests (void)
+{
+#if (!defined(DGTEST)) || DGTEST == 1
+ v_v();
+ clear_traces();
+ {
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_void);
+ {
+ FFI_CALL(cif,v_v,NULL,NULL);
+ }
+ }
+#endif
+ return;
+}
+void
+ int_tests (void)
+{
+ int ir;
+ ffi_arg retvalue;
+#if (!defined(DGTEST)) || DGTEST == 2
+ ir = i_v();
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ {
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_sint);
+ {
+ FFI_CALL(cif,i_v,NULL,&retvalue);
+ ir = retvalue;
+ }
+ }
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 3
+ ir = i_i(i1);
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
+ {
+ /*const*/ void* args[] = { &i1 };
+ FFI_CALL(cif,i_i,args,&retvalue);
+ ir = retvalue;
+ }
+ }
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 4
+ ir = i_i2(i1,i2);
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
+ {
+ /*const*/ void* args[] = { &i1, &i2 };
+ FFI_CALL(cif,i_i2,args,&retvalue);
+ ir = retvalue;
+ }
+ }
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 5
+ ir = i_i4(i1,i2,i3,i4);
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
+ {
+ /*const*/ void* args[] = { &i1, &i2, &i3, &i4 };
+ FFI_CALL(cif,i_i4,args,&retvalue);
+ ir = retvalue;
+ }
+ }
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 6
+ ir = i_i8(i1,i2,i3,i4,i5,i6,i7,i8);
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
+ {
+ /*const*/ void* args[] = { &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8 };
+ FFI_CALL(cif,i_i8,args,&retvalue);
+ ir = retvalue;
+ }
+ }
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 7
+ ir = i_i16(i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16);
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
+ {
+ /*const*/ void* args[] = { &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9, &i10, &i11, &i12, &i13, &i14, &i15, &i16 };
+ FFI_CALL(cif,i_i16,args,&retvalue);
+ ir = retvalue;
+ }
+ }
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+ return;
+}
+void
+ float_tests (void)
+{
+ float fr;
+
+#if (!defined(DGTEST)) || DGTEST == 8
+ fr = f_f(f1);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1 };
+ FFI_CALL(cif,f_f,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 9
+ fr = f_f2(f1,f2);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2 };
+ FFI_CALL(cif,f_f2,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 10
+ fr = f_f4(f1,f2,f3,f4);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &f4 };
+ FFI_CALL(cif,f_f4,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 11
+ fr = f_f8(f1,f2,f3,f4,f5,f6,f7,f8);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8 };
+ FFI_CALL(cif,f_f8,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 12
+ fr = f_f16(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9, &f10, &f11, &f12, &f13, &f14, &f15, &f16 };
+ FFI_CALL(cif,f_f16,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 13
+ fr = f_f24(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20,f21,f22,f23,f24);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9, &f10, &f11, &f12, &f13, &f14, &f15, &f16, &f17, &f18, &f19, &f20, &f21, &f22, &f23, &f24 };
+ FFI_CALL(cif,f_f24,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+}
+void
+ double_tests (void)
+{
+ double dr;
+
+#if (!defined(DGTEST)) || DGTEST == 14
+
+ dr = d_d(d1);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1 };
+ FFI_CALL(cif,d_d,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 15
+ dr = d_d2(d1,d2);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2 };
+ FFI_CALL(cif,d_d2,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 16
+ dr = d_d4(d1,d2,d3,d4);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &d3, &d4 };
+ FFI_CALL(cif,d_d4,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 17
+ dr = d_d8(d1,d2,d3,d4,d5,d6,d7,d8);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8 };
+ FFI_CALL(cif,d_d8,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 18
+ dr = d_d16(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &d13, &d14, &d15, &d16 };
+ FFI_CALL(cif,d_d16,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+ return;
+}
+void
+ pointer_tests (void)
+{
+ void* vpr;
+
+#if (!defined(DGTEST)) || DGTEST == 19
+ vpr = vp_vpdpcpsp(&uc1,&d2,str3,&I4);
+ fprintf(out,"->0x%p\n",vpr);
+ fflush(out);
+ vpr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_pointer, &ffi_type_pointer, &ffi_type_pointer, &ffi_type_pointer };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_pointer);
+ {
+ void* puc1 = &uc1;
+ void* pd2 = &d2;
+ void* pstr3 = str3;
+ void* pI4 = &I4;
+ /*const*/ void* args[] = { &puc1, &pd2, &pstr3, &pI4 };
+ FFI_CALL(cif,vp_vpdpcpsp,args,&vpr);
+ }
+ }
+ fprintf(out,"->0x%p\n",vpr);
+ fflush(out);
+#endif
+ return;
+}
+void
+ mixed_number_tests (void)
+{
+ uchar ucr;
+ ushort usr;
+ float fr;
+ double dr;
+ long long llr;
+
+ /* Unsigned types.
+ */
+#if (!defined(DGTEST)) || DGTEST == 20
+ ucr = uc_ucsil(uc1, us2, ui3, ul4);
+ fprintf(out,"->%u\n",ucr);
+ fflush(out);
+ ucr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_uchar, &ffi_type_ushort, &ffi_type_uint, &ffi_type_ulong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_uchar);
+ {
+ ffi_arg r;
+ /*const*/ void* args[] = { &uc1, &us2, &ui3, &ul4 };
+ FFI_CALL(cif,uc_ucsil,args,&r);
+ ucr = (uchar) r;
+ }
+ }
+ fprintf(out,"->%u\n",ucr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 21
+ /* Mixed int & float types.
+ */
+ dr = d_iidd(i1,i2,d3,d4);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &i1, &i2, &d3, &d4 };
+ FFI_CALL(cif,d_iidd,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 22
+ dr = d_iiidi(i1,i2,i3,d4,i5);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &i1, &i2, &i3, &d4, &i5 };
+ FFI_CALL(cif,d_iiidi,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 23
+ dr = d_idid(i1,d2,i3,d4);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_double, &ffi_type_sint, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &i1, &d2, &i3, &d4 };
+ FFI_CALL(cif,d_idid,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 24
+ dr = d_fdi(f1,d2,i3);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &f1, &d2, &i3 };
+ FFI_CALL(cif,d_fdi,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 25
+ usr = us_cdcd(c1,d2,c3,d4);
+ fprintf(out,"->%u\n",usr);
+ fflush(out);
+ usr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_char, &ffi_type_double, &ffi_type_char, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_ushort);
+ {
+ ffi_arg rint;
+ /*const*/ void* args[] = { &c1, &d2, &c3, &d4 };
+ FFI_CALL(cif,us_cdcd,args,&rint);
+ usr = (ushort) rint;
+ }
+ }
+ fprintf(out,"->%u\n",usr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 26
+ /* Long long types.
+ */
+ llr = ll_iiilli(i1,i2,i3,ll1,i13);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_slonglong, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ {
+ /*const*/ void* args[] = { &i1, &i2, &i3, &ll1, &i13 };
+ FFI_CALL(cif,ll_iiilli,args,&llr);
+ }
+ }
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 27
+ llr = ll_flli(f13,ll1,i13);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_slonglong, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ {
+ /*const*/ void* args[] = { &f13, &ll1, &i13 };
+ FFI_CALL(cif,ll_flli,args,&llr);
+ }
+ }
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 28
+ fr = f_fi(f1,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &i9 };
+ FFI_CALL(cif,f_fi,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 29
+ fr = f_f2i(f1,f2,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &i9 };
+ FFI_CALL(cif,f_f2i,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 30
+ fr = f_f3i(f1,f2,f3,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &i9 };
+ FFI_CALL(cif,f_f3i,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 31
+ fr = f_f4i(f1,f2,f3,f4,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &i9 };
+ FFI_CALL(cif,f_f4i,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 32
+ fr = f_f7i(f1,f2,f3,f4,f5,f6,f7,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &i9 };
+ FFI_CALL(cif,f_f7i,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 33
+ fr = f_f8i(f1,f2,f3,f4,f5,f6,f7,f8,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &i9 };
+ FFI_CALL(cif,f_f8i,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 34
+ fr = f_f12i(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9, &f10, &f11, &f12, &i9 };
+ FFI_CALL(cif,f_f12i,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 35
+ fr = f_f13i(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9, &f10, &f11, &f12, &f13, &i9 };
+ FFI_CALL(cif,f_f13i,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 36
+ dr = d_di(d1,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &i9 };
+ FFI_CALL(cif,d_di,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 37
+ dr = d_d2i(d1,d2,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &i9 };
+ FFI_CALL(cif,d_d2i,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 38
+ dr = d_d3i(d1,d2,d3,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &d3, &i9 };
+ FFI_CALL(cif,d_d3i,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 39
+ dr = d_d4i(d1,d2,d3,d4,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &i9 };
+ FFI_CALL(cif,d_d4i,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 40
+ dr = d_d7i(d1,d2,d3,d4,d5,d6,d7,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &i9 };
+ FFI_CALL(cif,d_d7i,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 41
+ dr = d_d8i(d1,d2,d3,d4,d5,d6,d7,d8,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &i9 };
+ FFI_CALL(cif,d_d8i,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 42
+ dr = d_d12i(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &i9 };
+ FFI_CALL(cif,d_d12i,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 43
+ dr = d_d13i(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &d13, &i9 };
+ FFI_CALL(cif,d_d13i,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+ return;
+}
+void
+ small_structure_return_tests (void)
+{
+#if (!defined(DGTEST)) || DGTEST == 44
+ {
+ Size1 r = S1_v();
+ fprintf(out,"->{%c}\n",r.x1);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ {
+ ffi_type* ffi_type_Size1_elements[] = { &ffi_type_char, NULL };
+ ffi_type ffi_type_Size1;
+ ffi_type_Size1.type = FFI_TYPE_STRUCT;
+ ffi_type_Size1.size = sizeof(Size1);
+ ffi_type_Size1.alignment = alignof_slot(Size1);
+ ffi_type_Size1.elements = ffi_type_Size1_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size1);
+ {
+ FFI_CALL(cif,S1_v,NULL,&r);
+ }
+ }
+ fprintf(out,"->{%c}\n",r.x1);
+ fflush(out);
+ }
+#endif
+#if (!defined(DGTEST)) || DGTEST == 45
+ {
+ Size2 r = S2_v();
+ fprintf(out,"->{%c%c}\n",r.x1,r.x2);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ {
+ ffi_type* ffi_type_Size2_elements[] = { &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size2;
+ ffi_type_Size2.type = FFI_TYPE_STRUCT;
+ ffi_type_Size2.size = sizeof(Size2);
+ ffi_type_Size2.alignment = alignof_slot(Size2);
+ ffi_type_Size2.elements = ffi_type_Size2_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size2);
+ {
+ FFI_CALL(cif,S2_v,NULL,&r);
+ }
+ }
+ fprintf(out,"->{%c%c}\n",r.x1,r.x2);
+ fflush(out);
+ }
+#endif
+#if (!defined(DGTEST)) || DGTEST == 46
+ {
+ Size3 r = S3_v();
+ fprintf(out,"->{%c%c%c}\n",r.x1,r.x2,r.x3);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ {
+ ffi_type* ffi_type_Size3_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size3;
+ ffi_type_Size3.type = FFI_TYPE_STRUCT;
+ ffi_type_Size3.size = sizeof(Size3);
+ ffi_type_Size3.alignment = alignof_slot(Size3);
+ ffi_type_Size3.elements = ffi_type_Size3_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size3);
+ {
+ FFI_CALL(cif,S3_v,NULL,&r);
+ }
+ }
+ fprintf(out,"->{%c%c%c}\n",r.x1,r.x2,r.x3);
+ fflush(out);
+ }
+#endif
+#if (!defined(DGTEST)) || DGTEST == 47
+ {
+ Size4 r = S4_v();
+ fprintf(out,"->{%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ {
+ ffi_type* ffi_type_Size4_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size4;
+ ffi_type_Size4.type = FFI_TYPE_STRUCT;
+ ffi_type_Size4.size = sizeof(Size4);
+ ffi_type_Size4.alignment = alignof_slot(Size4);
+ ffi_type_Size4.elements = ffi_type_Size4_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size4);
+ {
+ FFI_CALL(cif,S4_v,NULL,&r);
+ }
+ }
+ fprintf(out,"->{%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4);
+ fflush(out);
+ }
+#endif
+#if (!defined(DGTEST)) || DGTEST == 48
+ {
+ Size7 r = S7_v();
+ fprintf(out,"->{%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ {
+ ffi_type* ffi_type_Size7_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size7;
+ ffi_type_Size7.type = FFI_TYPE_STRUCT;
+ ffi_type_Size7.size = sizeof(Size7);
+ ffi_type_Size7.alignment = alignof_slot(Size7);
+ ffi_type_Size7.elements = ffi_type_Size7_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size7);
+ {
+ FFI_CALL(cif,S7_v,NULL,&r);
+ }
+ }
+ fprintf(out,"->{%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7);
+ fflush(out);
+ }
+#endif
+#if (!defined(DGTEST)) || DGTEST == 49
+ {
+ Size8 r = S8_v();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ {
+ ffi_type* ffi_type_Size8_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size8;
+ ffi_type_Size8.type = FFI_TYPE_STRUCT;
+ ffi_type_Size8.size = sizeof(Size8);
+ ffi_type_Size8.alignment = alignof_slot(Size8);
+ ffi_type_Size8.elements = ffi_type_Size8_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size8);
+ {
+ FFI_CALL(cif,S8_v,NULL,&r);
+ }
+ }
+ fprintf(out,"->{%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8);
+ fflush(out);
+ }
+#endif
+#if (!defined(DGTEST)) || DGTEST == 50
+ {
+ Size12 r = S12_v();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ {
+ ffi_type* ffi_type_Size12_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size12;
+ ffi_type_Size12.type = FFI_TYPE_STRUCT;
+ ffi_type_Size12.size = sizeof(Size12);
+ ffi_type_Size12.alignment = alignof_slot(Size12);
+ ffi_type_Size12.elements = ffi_type_Size12_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size12);
+ {
+ FFI_CALL(cif,S12_v,NULL,&r);
+ }
+ }
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12);
+ fflush(out);
+ }
+#endif
+#if (!defined(DGTEST)) || DGTEST == 51
+ {
+ Size15 r = S15_v();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ {
+ ffi_type* ffi_type_Size15_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size15;
+ ffi_type_Size15.type = FFI_TYPE_STRUCT;
+ ffi_type_Size15.size = sizeof(Size15);
+ ffi_type_Size15.alignment = alignof_slot(Size15);
+ ffi_type_Size15.elements = ffi_type_Size15_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size15);
+ {
+ FFI_CALL(cif,S15_v,NULL,&r);
+ }
+ }
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15);
+ fflush(out);
+ }
+#endif
+#if (!defined(DGTEST)) || DGTEST == 52
+ {
+ Size16 r = S16_v();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15,r.x16);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ {
+ ffi_type* ffi_type_Size16_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size16;
+ ffi_type_Size16.type = FFI_TYPE_STRUCT;
+ ffi_type_Size16.size = sizeof(Size16);
+ ffi_type_Size16.alignment = alignof_slot(Size16);
+ ffi_type_Size16.elements = ffi_type_Size16_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size16);
+ {
+ FFI_CALL(cif,S16_v,NULL,&r);
+ }
+ }
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15,r.x16);
+ fflush(out);
+ }
+#endif
+}
+void
+ structure_tests (void)
+{
+ Int Ir;
+ Char Cr;
+ Float Fr;
+ Double Dr;
+ J Jr;
+#ifndef SKIP_EXTRA_STRUCTS
+ T Tr;
+ X Xr;
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 53
+ Ir = I_III(I1,I2,I3);
+ fprintf(out,"->{%d}\n",Ir.x);
+ fflush(out);
+ Ir.x = 0; clear_traces();
+ {
+ ffi_type* ffi_type_Int_elements[] = { &ffi_type_sint, NULL };
+ ffi_type ffi_type_Int;
+ ffi_type_Int.type = FFI_TYPE_STRUCT;
+ ffi_type_Int.size = sizeof(Int);
+ ffi_type_Int.alignment = alignof_slot(Int);
+ ffi_type_Int.elements = ffi_type_Int_elements;
+ ffi_type* argtypes[] = { &ffi_type_Int, &ffi_type_Int, &ffi_type_Int };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_Int);
+ {
+ /*const*/ void* args[] = { &I1, &I2, &I3 };
+ FFI_CALL(cif,I_III,args,&Ir);
+ }
+ }
+ fprintf(out,"->{%d}\n",Ir.x);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 54
+ Cr = C_CdC(C1,d2,C3);
+ fprintf(out,"->{'%c'}\n",Cr.x);
+ fflush(out);
+ Cr.x = '\0'; clear_traces();
+ {
+ ffi_type* ffi_type_Char_elements[] = { &ffi_type_char, NULL };
+ ffi_type ffi_type_Char;
+ ffi_type_Char.type = FFI_TYPE_STRUCT;
+ ffi_type_Char.size = sizeof(Char);
+ ffi_type_Char.alignment = alignof_slot(Char);
+ ffi_type_Char.elements = ffi_type_Char_elements;
+ ffi_type* argtypes[] = { &ffi_type_Char, &ffi_type_double, &ffi_type_Char };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_Char);
+ {
+ /*const*/ void* args[] = { &C1, &d2, &C3 };
+ FFI_CALL(cif,C_CdC,args,&Cr);
+ }
+ }
+ fprintf(out,"->{'%c'}\n",Cr.x);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 55
+ Fr = F_Ffd(F1,f2,d3);
+ fprintf(out,"->{%g}\n",Fr.x);
+ fflush(out);
+ Fr.x = 0.0; clear_traces();
+ {
+ ffi_type* ffi_type_Float_elements[] = { &ffi_type_float, NULL };
+ ffi_type ffi_type_Float;
+ ffi_type_Float.type = FFI_TYPE_STRUCT;
+ ffi_type_Float.size = sizeof(Float);
+ ffi_type_Float.alignment = alignof_slot(Float);
+ ffi_type_Float.elements = ffi_type_Float_elements;
+ ffi_type* argtypes[] = { &ffi_type_Float, &ffi_type_float, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_Float);
+ {
+ /*const*/ void* args[] = { &F1, &f2, &d3 };
+ FFI_CALL(cif,F_Ffd,args,&Fr);
+ }
+ }
+ fprintf(out,"->{%g}\n",Fr.x);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 56
+ Dr = D_fDd(f1,D2,d3);
+ fprintf(out,"->{%g}\n",Dr.x);
+ fflush(out);
+ Dr.x = 0.0; clear_traces();
+ {
+ ffi_type* ffi_type_Double_elements[] = { &ffi_type_double, NULL };
+ ffi_type ffi_type_Double;
+ ffi_type_Double.type = FFI_TYPE_STRUCT;
+ ffi_type_Double.size = sizeof(Double);
+ ffi_type_Double.alignment = alignof_slot(Double);
+ ffi_type_Double.elements = ffi_type_Double_elements;
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_Double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_Double);
+ {
+ /*const*/ void* args[] = { &f1, &D2, &d3 };
+ FFI_CALL(cif,D_fDd,args,&Dr);
+ }
+ }
+ fprintf(out,"->{%g}\n",Dr.x);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 57
+ Dr = D_Dfd(D1,f2,d3);
+ fprintf(out,"->{%g}\n",Dr.x);
+ fflush(out);
+ Dr.x = 0.0; clear_traces();
+ {
+ ffi_type* ffi_type_Double_elements[] = { &ffi_type_double, NULL };
+ ffi_type ffi_type_Double;
+ ffi_type_Double.type = FFI_TYPE_STRUCT;
+ ffi_type_Double.size = sizeof(Double);
+ ffi_type_Double.alignment = alignof_slot(Double);
+ ffi_type_Double.elements = ffi_type_Double_elements;
+ ffi_type* argtypes[] = { &ffi_type_Double, &ffi_type_float, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_Double);
+ {
+ /*const*/ void* args[] = { &D1, &f2, &d3 };
+ FFI_CALL(cif,D_Dfd,args,&Dr);
+ }
+ }
+ fprintf(out,"->{%g}\n",Dr.x);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 58
+ Jr = J_JiJ(J1,i2,J2);
+ fprintf(out,"->{%ld,%ld}\n",Jr.l1,Jr.l2);
+ fflush(out);
+ Jr.l1 = Jr.l2 = 0; clear_traces();
+ {
+ ffi_type* ffi_type_J_elements[] = { &ffi_type_slong, &ffi_type_slong, NULL };
+ ffi_type ffi_type_J;
+ ffi_type_J.type = FFI_TYPE_STRUCT;
+ ffi_type_J.size = sizeof(J);
+ ffi_type_J.alignment = alignof_slot(J);
+ ffi_type_J.elements = ffi_type_J_elements;
+ ffi_type* argtypes[] = { &ffi_type_J, &ffi_type_sint, &ffi_type_J };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_J);
+ {
+ /*const*/ void* args[] = { &J1, &i2, &J2 };
+ FFI_CALL(cif,J_JiJ,args,&Jr);
+ }
+ }
+ fprintf(out,"->{%ld,%ld}\n",Jr.l1,Jr.l2);
+ fflush(out);
+#endif
+#ifndef SKIP_EXTRA_STRUCTS
+#if (!defined(DGTEST)) || DGTEST == 59
+ Tr = T_TcT(T1,' ',T2);
+ fprintf(out,"->{\"%c%c%c\"}\n",Tr.c[0],Tr.c[1],Tr.c[2]);
+ fflush(out);
+ Tr.c[0] = Tr.c[1] = Tr.c[2] = 0; clear_traces();
+ {
+ ffi_type* ffi_type_T_elements[] = { ??, NULL };
+ ffi_type ffi_type_T;
+ ffi_type_T.type = FFI_TYPE_STRUCT;
+ ffi_type_T.size = sizeof(T);
+ ffi_type_T.alignment = alignof_slot(T);
+ ffi_type_T.elements = ffi_type_T_elements;
+ ffi_type* argtypes[] = { &ffi_type_T, &ffi_type_char, &ffi_type_T };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_T);
+ {
+ char space = ' ';
+ /*const*/ void* args[] = { &T1, &space, &T2 };
+ FFI_CALL(cif,T_TcT,args,&Tr);
+ }
+ }
+ fprintf(out,"->{\"%c%c%c\"}\n",Tr.c[0],Tr.c[1],Tr.c[2]);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 60
+ Xr = X_BcdB(B1,c2,d3,B2);
+ fprintf(out,"->{\"%s\",'%c'}\n",Xr.c,Xr.c1);
+ fflush(out);
+ Xr.c[0]=Xr.c1='\0'; clear_traces();
+ {
+ ffi_type* ffi_type_X_elements[] = { ??, NULL };
+ ffi_type ffi_type_X;
+ ffi_type_X.type = FFI_TYPE_STRUCT;
+ ffi_type_X.size = sizeof(X);
+ ffi_type_X.alignment = alignof_slot(X);
+ ffi_type_X.elements = ffi_type_X_elements;
+ ffi_type* argtypes[] = { &ffi_type_X, &ffi_type_char, &ffi_type_double, &ffi_type_X };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_X);
+ {
+ /*const*/ void* args[] = { &B1, &c2, &d3, &B2 };
+ FFI_CALL(cif,X_BcdB,args,&Xr);
+ }
+ }
+ fprintf(out,"->{\"%s\",'%c'}\n",Xr.c,Xr.c1);
+ fflush(out);
+#endif
+#endif
+
+ return;
+}
+
+void
+ gpargs_boundary_tests (void)
+{
+ ffi_type* ffi_type_K_elements[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, NULL };
+ ffi_type ffi_type_K;
+ ffi_type* ffi_type_L_elements[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, NULL };
+ ffi_type ffi_type_L;
+ long lr;
+ long long llr;
+ float fr;
+ double dr;
+
+ ffi_type_K.type = FFI_TYPE_STRUCT;
+ ffi_type_K.size = sizeof(K);
+ ffi_type_K.alignment = alignof_slot(K);
+ ffi_type_K.elements = ffi_type_K_elements;
+
+ ffi_type_L.type = FFI_TYPE_STRUCT;
+ ffi_type_L.size = sizeof(L);
+ ffi_type_L.alignment = alignof_slot(L);
+ ffi_type_L.elements = ffi_type_L_elements;
+
+#if (!defined(DGTEST)) || DGTEST == 61
+ lr = l_l0K(K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ {
+ /*const*/ void* args[] = { &K1, &l9 };
+ FFI_CALL(cif,l_l0K,args,&lr);
+ }
+ }
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 62
+ lr = l_l1K(l1,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ {
+ /*const*/ void* args[] = { &l1, &K1, &l9 };
+ FFI_CALL(cif,l_l1K,args,&lr);
+ }
+ }
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 63
+ lr = l_l2K(l1,l2,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &K1, &l9 };
+ FFI_CALL(cif,l_l2K,args,&lr);
+ }
+ }
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 64
+ lr = l_l3K(l1,l2,l3,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &K1, &l9 };
+ FFI_CALL(cif,l_l3K,args,&lr);
+ }
+ }
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 65
+ lr = l_l4K(l1,l2,l3,l4,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &K1, &l9 };
+ FFI_CALL(cif,l_l4K,args,&lr);
+ }
+ }
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 66
+ lr = l_l5K(l1,l2,l3,l4,l5,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &K1, &l9 };
+ FFI_CALL(cif,l_l5K,args,&lr);
+ }
+ }
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 67
+ lr = l_l6K(l1,l2,l3,l4,l5,l6,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &l6, &K1, &l9 };
+ FFI_CALL(cif,l_l6K,args,&lr);
+ }
+ }
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 68
+ fr = f_f17l3L(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,l6,l7,l8,L1);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_L };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ {
+ /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9, &f10, &f11, &f12, &f13, &f14, &f15, &f16, &f17, &l6, &l7, &l8, &L1 };
+ FFI_CALL(cif,f_f17l3L,args,&fr);
+ }
+ }
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 69
+ dr = d_d17l3L(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,d17,l6,l7,l8,L1);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_L };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &d13, &d14, &d15, &d16, &d17, &l6, &l7, &l8, &L1 };
+ FFI_CALL(cif,d_d17l3L,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 70
+ llr = ll_l2ll(l1,l2,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &ll1, &l9 };
+ FFI_CALL(cif,ll_l2ll,args,&llr);
+ }
+ }
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 71
+ llr = ll_l3ll(l1,l2,l3,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &ll1, &l9 };
+ FFI_CALL(cif,ll_l3ll,args,&llr);
+ }
+ }
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 72
+ llr = ll_l4ll(l1,l2,l3,l4,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &ll1, &l9 };
+ FFI_CALL(cif,ll_l4ll,args,&llr);
+ }
+ }
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 73
+ llr = ll_l5ll(l1,l2,l3,l4,l5,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &ll1, &l9 };
+ FFI_CALL(cif,ll_l5ll,args,&llr);
+ }
+ }
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 74
+ llr = ll_l6ll(l1,l2,l3,l4,l5,l6,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &l6, &ll1, &l9 };
+ FFI_CALL(cif,ll_l6ll,args,&llr);
+ }
+ }
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 75
+ llr = ll_l7ll(l1,l2,l3,l4,l5,l6,l7,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &l6, &l7, &ll1, &l9 };
+ FFI_CALL(cif,ll_l7ll,args,&llr);
+ }
+ }
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 76
+ dr = d_l2d(l1,l2,d2,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &d2, &l9 };
+ FFI_CALL(cif,d_l2d,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 77
+ dr = d_l3d(l1,l2,l3,d2,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &d2, &l9 };
+ FFI_CALL(cif,d_l3d,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 78
+ dr = d_l4d(l1,l2,l3,l4,d2,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &d2, &l9 };
+ FFI_CALL(cif,d_l4d,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 79
+ dr = d_l5d(l1,l2,l3,l4,l5,d2,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &d2, &l9 };
+ FFI_CALL(cif,d_l5d,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 80
+ dr = d_l6d(l1,l2,l3,l4,l5,l6,d2,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &l6, &d2, &l9 };
+ FFI_CALL(cif,d_l6d,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+#if (!defined(DGTEST)) || DGTEST == 81
+ dr = d_l7d(l1,l2,l3,l4,l5,l6,l7,d2,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ {
+ /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &l6, &l7, &d2, &l9 };
+ FFI_CALL(cif,d_l7d,args,&dr);
+ }
+ }
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+ return;
+}
+
+int
+ main (void)
+{
+ ffi_type_char = (char)(-1) < 0 ? ffi_type_schar : ffi_type_uchar;
+ out = stdout;
+
+ void_tests();
+ int_tests();
+ float_tests();
+ double_tests();
+ pointer_tests();
+ mixed_number_tests();
+ small_structure_return_tests();
+ structure_tests();
+ gpargs_boundary_tests();
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.bhaible/test-callback.c b/js/src/ctypes/libffi/testsuite/libffi.bhaible/test-callback.c
new file mode 100644
index 0000000000..c2633c79bb
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.bhaible/test-callback.c
@@ -0,0 +1,2885 @@
+/*
+ * Copyright 1993 Bill Triggs <Bill.Triggs@inrialpes.fr>
+ * Copyright 1995-2017 Bruno Haible <bruno@clisp.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* { dg-do run } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ffi.h>
+#include "alignof.h"
+#include <stdarg.h>
+
+/* libffi testsuite local changes -------------------------------- */
+#ifdef DGTEST
+/* Redefine exit(1) as a test failure */
+#define exit(V) (void)((V) ? (abort(), 1) : exit(0))
+int count = 0;
+char rbuf1[2048];
+char rbuf2[2048];
+int _fprintf(FILE *stream, const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+
+ switch (count++)
+ {
+ case 0:
+ case 1:
+ vsprintf(&rbuf1[strlen(rbuf1)], format, args);
+ break;
+ case 2:
+ printf("%s", rbuf1);
+ vsprintf(rbuf2, format, args);
+ break;
+ case 3:
+ vsprintf(&rbuf2[strlen(rbuf2)], format, args);
+ printf("%s", rbuf2);
+ if (strcmp (rbuf1, rbuf2)) abort();
+ break;
+ }
+
+ va_end(args);
+
+ return 0;
+}
+#define fprintf _fprintf
+#endif
+/* --------------------------------------------------------------- */
+
+#include "testcases.c"
+
+#ifndef ABI_NUM
+#define ABI_NUM FFI_DEFAULT_ABI
+#endif
+
+/* Definitions that ought to be part of libffi. */
+static ffi_type ffi_type_char;
+#define ffi_type_slonglong ffi_type_sint64
+#define ffi_type_ulonglong ffi_type_uint64
+
+/* libffi does not support arrays inside structs. */
+#define SKIP_EXTRA_STRUCTS
+
+#define FFI_PREP_CIF(cif,argtypes,rettype) \
+ if (ffi_prep_cif(&(cif),ABI_NUM,sizeof(argtypes)/sizeof(argtypes[0]),&rettype,argtypes) != FFI_OK) abort()
+#define FFI_PREP_CIF_NOARGS(cif,rettype) \
+ if (ffi_prep_cif(&(cif),ABI_NUM,0,&rettype,NULL) != FFI_OK) abort()
+
+#if defined(__sparc__) && defined(__sun) && defined(__SUNPRO_C) /* SUNWspro cc */
+/* SunPRO cc miscompiles the simulator function for X_BcdB: d.i[1] is
+ * temporarily stored in %l2 and put onto the stack from %l2, but in between
+ * the copy of X has used %l2 as a counter without saving and restoring its
+ * value.
+ */
+#define SKIP_X
+#endif
+#if defined(__mipsn32__) && !defined(__GNUC__)
+/* The X test crashes for an unknown reason. */
+#define SKIP_X
+#endif
+
+
+/* These functions simulate the behaviour of the functions defined in testcases.c. */
+
+/* void tests */
+void v_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&v_v) { fprintf(out,"wrong data for v_v\n"); exit(1); }
+ fprintf(out,"void f(void):\n");
+ fflush(out);
+}
+
+/* int tests */
+void i_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&i_v) { fprintf(out,"wrong data for i_v\n"); exit(1); }
+ {int r=99;
+ fprintf(out,"int f(void):");
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void i_i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&i_i) { fprintf(out,"wrong data for i_i\n"); exit(1); }
+ int a = *(int*)(*args++);
+ int r=a+1;
+ fprintf(out,"int f(int):(%d)",a);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}
+void i_i2_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&i_i2) { fprintf(out,"wrong data for i_i2\n"); exit(1); }
+ {int a = *(int*)(*args++);
+ int b = *(int*)(*args++);
+ int r=a+b;
+ fprintf(out,"int f(2*int):(%d,%d)",a,b);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void i_i4_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&i_i4) { fprintf(out,"wrong data for i_i4\n"); exit(1); }
+ {int a = *(int*)(*args++);
+ int b = *(int*)(*args++);
+ int c = *(int*)(*args++);
+ int d = *(int*)(*args++);
+ int r=a+b+c+d;
+ fprintf(out,"int f(4*int):(%d,%d,%d,%d)",a,b,c,d);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void i_i8_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&i_i8) { fprintf(out,"wrong data for i_i8\n"); exit(1); }
+ {int a = *(int*)(*args++);
+ int b = *(int*)(*args++);
+ int c = *(int*)(*args++);
+ int d = *(int*)(*args++);
+ int e = *(int*)(*args++);
+ int f = *(int*)(*args++);
+ int g = *(int*)(*args++);
+ int h = *(int*)(*args++);
+ int r=a+b+c+d+e+f+g+h;
+ fprintf(out,"int f(8*int):(%d,%d,%d,%d,%d,%d,%d,%d)",a,b,c,d,e,f,g,h);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void i_i16_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&i_i16) { fprintf(out,"wrong data for i_i16\n"); exit(1); }
+ {int a = *(int*)(*args++);
+ int b = *(int*)(*args++);
+ int c = *(int*)(*args++);
+ int d = *(int*)(*args++);
+ int e = *(int*)(*args++);
+ int f = *(int*)(*args++);
+ int g = *(int*)(*args++);
+ int h = *(int*)(*args++);
+ int i = *(int*)(*args++);
+ int j = *(int*)(*args++);
+ int k = *(int*)(*args++);
+ int l = *(int*)(*args++);
+ int m = *(int*)(*args++);
+ int n = *(int*)(*args++);
+ int o = *(int*)(*args++);
+ int p = *(int*)(*args++);
+ int r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
+ fprintf(out,"int f(16*int):(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
+ a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+
+/* float tests */
+void f_f_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f) { fprintf(out,"wrong data for f_f\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float r=a+1.0;
+ fprintf(out,"float f(float):(%g)",a);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f2_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f2) { fprintf(out,"wrong data for f_f2\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float r=a+b;
+ fprintf(out,"float f(2*float):(%g,%g)",a,b);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f4_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f4) { fprintf(out,"wrong data for f_f4\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ float d = *(float*)(*args++);
+ float r=a+b+c+d;
+ fprintf(out,"float f(4*float):(%g,%g,%g,%g)",a,b,c,d);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f8_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f8) { fprintf(out,"wrong data for f_f8\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ float d = *(float*)(*args++);
+ float e = *(float*)(*args++);
+ float f = *(float*)(*args++);
+ float g = *(float*)(*args++);
+ float h = *(float*)(*args++);
+ float r=a+b+c+d+e+f+g+h;
+ fprintf(out,"float f(8*float):(%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f16_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f16) { fprintf(out,"wrong data for f_f16\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ float d = *(float*)(*args++);
+ float e = *(float*)(*args++);
+ float f = *(float*)(*args++);
+ float g = *(float*)(*args++);
+ float h = *(float*)(*args++);
+ float i = *(float*)(*args++);
+ float j = *(float*)(*args++);
+ float k = *(float*)(*args++);
+ float l = *(float*)(*args++);
+ float m = *(float*)(*args++);
+ float n = *(float*)(*args++);
+ float o = *(float*)(*args++);
+ float p = *(float*)(*args++);
+ float r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
+ fprintf(out,"float f(16*float):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f24_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f24) { fprintf(out,"wrong data for f_f24\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ float d = *(float*)(*args++);
+ float e = *(float*)(*args++);
+ float f = *(float*)(*args++);
+ float g = *(float*)(*args++);
+ float h = *(float*)(*args++);
+ float i = *(float*)(*args++);
+ float j = *(float*)(*args++);
+ float k = *(float*)(*args++);
+ float l = *(float*)(*args++);
+ float m = *(float*)(*args++);
+ float n = *(float*)(*args++);
+ float o = *(float*)(*args++);
+ float p = *(float*)(*args++);
+ float q = *(float*)(*args++);
+ float s = *(float*)(*args++);
+ float t = *(float*)(*args++);
+ float u = *(float*)(*args++);
+ float v = *(float*)(*args++);
+ float w = *(float*)(*args++);
+ float x = *(float*)(*args++);
+ float y = *(float*)(*args++);
+ float r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+v+w+x+y;
+ fprintf(out,"float f(24*float):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,v,w,x,y);
+ fflush(out);
+ *(float*)retp = r;
+}}
+
+/* double tests */
+void d_d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d) { fprintf(out,"wrong data for d_d\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double r=a+1.0;
+ fprintf(out,"double f(double):(%g)",a);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d2_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d2) { fprintf(out,"wrong data for d_d2\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double r=a+b;
+ fprintf(out,"double f(2*double):(%g,%g)",a,b);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d4_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d4) { fprintf(out,"wrong data for d_d4\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double c = *(double*)(*args++);
+ double d = *(double*)(*args++);
+ double r=a+b+c+d;
+ fprintf(out,"double f(4*double):(%g,%g,%g,%g)",a,b,c,d);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d8_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d8) { fprintf(out,"wrong data for d_d8\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double c = *(double*)(*args++);
+ double d = *(double*)(*args++);
+ double e = *(double*)(*args++);
+ double f = *(double*)(*args++);
+ double g = *(double*)(*args++);
+ double h = *(double*)(*args++);
+ double r=a+b+c+d+e+f+g+h;
+ fprintf(out,"double f(8*double):(%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d16_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d16) { fprintf(out,"wrong data for d_d16\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double c = *(double*)(*args++);
+ double d = *(double*)(*args++);
+ double e = *(double*)(*args++);
+ double f = *(double*)(*args++);
+ double g = *(double*)(*args++);
+ double h = *(double*)(*args++);
+ double i = *(double*)(*args++);
+ double j = *(double*)(*args++);
+ double k = *(double*)(*args++);
+ double l = *(double*)(*args++);
+ double m = *(double*)(*args++);
+ double n = *(double*)(*args++);
+ double o = *(double*)(*args++);
+ double p = *(double*)(*args++);
+ double r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
+ fprintf(out,"double f(16*double):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
+ fflush(out);
+ *(double*)retp = r;
+}}
+
+/* pointer tests */
+void vp_vpdpcpsp_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&vp_vpdpcpsp) { fprintf(out,"wrong data for vp_vpdpcpsp\n"); exit(1); }
+ {void* a = *(void* *)(*args++);
+ double* b = *(double* *)(*args++);
+ char* c = *(char* *)(*args++);
+ Int* d = *(Int* *)(*args++);
+ void* ret = (char*)b + 1;
+ fprintf(out,"void* f(void*,double*,char*,Int*):(0x%p,0x%p,0x%p,0x%p)",a,b,c,d);
+ fflush(out);
+ *(void* *)retp = ret;
+}}
+
+/* mixed number tests */
+void uc_ucsil_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&uc_ucsil) { fprintf(out,"wrong data for uc_ucsil\n"); exit(1); }
+ {uchar a = *(unsigned char *)(*args++);
+ ushort b = *(unsigned short *)(*args++);
+ uint c = *(unsigned int *)(*args++);
+ ulong d = *(unsigned long *)(*args++);
+ uchar r = (uchar)-1;
+ fprintf(out,"uchar f(uchar,ushort,uint,ulong):(%u,%u,%u,%lu)",a,b,c,d);
+ fflush(out);
+ *(ffi_arg *)retp = r;
+}}
+void d_iidd_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_iidd) { fprintf(out,"wrong data for d_iidd\n"); exit(1); }
+ {int a = *(int*)(*args++);
+ int b = *(int*)(*args++);
+ double c = *(double*)(*args++);
+ double d = *(double*)(*args++);
+ double r=a+b+c+d;
+ fprintf(out,"double f(int,int,double,double):(%d,%d,%g,%g)",a,b,c,d);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_iiidi_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_iiidi) { fprintf(out,"wrong data for d_iiidi\n"); exit(1); }
+ {int a = *(int*)(*args++);
+ int b = *(int*)(*args++);
+ int c = *(int*)(*args++);
+ double d = *(double*)(*args++);
+ int e = *(int*)(*args++);
+ double r=a+b+c+d+e;
+ fprintf(out,"double f(int,int,int,double,int):(%d,%d,%d,%g,%d)",a,b,c,d,e);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_idid_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_idid) { fprintf(out,"wrong data for d_idid\n"); exit(1); }
+ {int a = *(int*)(*args++);
+ double b = *(double*)(*args++);
+ int c = *(int*)(*args++);
+ double d = *(double*)(*args++);
+ double r=a+b+c+d;
+ fprintf(out,"double f(int,double,int,double):(%d,%g,%d,%g)",a,b,c,d);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_fdi_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_fdi) { fprintf(out,"wrong data for d_fdi\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ double b = *(double*)(*args++);
+ int c = *(int*)(*args++);
+ double r=a+b+c;
+ fprintf(out,"double f(float,double,int):(%g,%g,%d)",a,b,c);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void us_cdcd_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&us_cdcd) { fprintf(out,"wrong data for us_cdcd\n"); exit(1); }
+ {char a = *(char*)(*args++);
+ double b = *(double*)(*args++);
+ char c = *(char*)(*args++);
+ double d = *(double*)(*args++);
+ ushort r = (ushort)(a + b + c + d);
+ fprintf(out,"ushort f(char,double,char,double):('%c',%g,'%c',%g)",a,b,c,d);
+ fflush(out);
+ *(ffi_arg *)retp = r;
+}}
+void ll_iiilli_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&ll_iiilli) { fprintf(out,"wrong data for ll_iiilli\n"); exit(1); }
+ {int a = *(int*)(*args++);
+ int b = *(int*)(*args++);
+ int c = *(int*)(*args++);
+ long long d = *(long long *)(*args++);
+ int e = *(int*)(*args++);
+ long long r = (long long)(int)a + (long long)(int)b + (long long)(int)c + d + (long long)e;
+ fprintf(out,"long long f(int,int,int,long long,int):(%d,%d,%d,0x%lx%08lx,%d)",a,b,c,(long)(d>>32),(long)(d&0xffffffff),e);
+ fflush(out);
+ *(long long *)retp = r;
+}}
+void ll_flli_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&ll_flli) { fprintf(out,"wrong data for ll_flli\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ long long b = *(long long *)(*args++);
+ int c = *(int*)(*args++);
+ long long r = (long long)(int)a + b + (long long)c;
+ fprintf(out,"long long f(float,long long,int):(%g,0x%lx%08lx,0x%lx)",a,(long)(b>>32),(long)(b&0xffffffff),(long)c);
+ fflush(out);
+ *(long long *)retp = r;
+}}
+void f_fi_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_fi) { fprintf(out,"wrong data for f_fi\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ int z = *(int*)(*args++);
+ float r=a+z;
+ fprintf(out,"float f(float,int):(%g,%d)",a,z);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f2i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f2i) { fprintf(out,"wrong data for f_f2i\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ int z = *(int*)(*args++);
+ float r=a+b+z;
+ fprintf(out,"float f(2*float,int):(%g,%g,%d)",a,b,z);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f3i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f3i) { fprintf(out,"wrong data for f_f3i\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ int z = *(int*)(*args++);
+ float r=a+b+c+z;
+ fprintf(out,"float f(3*float,int):(%g,%g,%g,%d)",a,b,c,z);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f4i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f4i) { fprintf(out,"wrong data for f_f4i\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ float d = *(float*)(*args++);
+ int z = *(int*)(*args++);
+ float r=a+b+c+d+z;
+ fprintf(out,"float f(4*float,int):(%g,%g,%g,%g,%d)",a,b,c,d,z);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f7i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f7i) { fprintf(out,"wrong data for f_f7i\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ float d = *(float*)(*args++);
+ float e = *(float*)(*args++);
+ float f = *(float*)(*args++);
+ float g = *(float*)(*args++);
+ int z = *(int*)(*args++);
+ float r=a+b+c+d+e+f+g+z;
+ fprintf(out,"float f(7*float,int):(%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,z);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f8i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f8i) { fprintf(out,"wrong data for f_f8i\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ float d = *(float*)(*args++);
+ float e = *(float*)(*args++);
+ float f = *(float*)(*args++);
+ float g = *(float*)(*args++);
+ float h = *(float*)(*args++);
+ int z = *(int*)(*args++);
+ float r=a+b+c+d+e+f+g+h+z;
+ fprintf(out,"float f(8*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,z);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f12i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f12i) { fprintf(out,"wrong data for f_f12i\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ float d = *(float*)(*args++);
+ float e = *(float*)(*args++);
+ float f = *(float*)(*args++);
+ float g = *(float*)(*args++);
+ float h = *(float*)(*args++);
+ float i = *(float*)(*args++);
+ float j = *(float*)(*args++);
+ float k = *(float*)(*args++);
+ float l = *(float*)(*args++);
+ int z = *(int*)(*args++);
+ float r=a+b+c+d+e+f+g+h+i+j+k+l+z;
+ fprintf(out,"float f(12*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,z);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void f_f13i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f13i) { fprintf(out,"wrong data for f_f13i\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ float d = *(float*)(*args++);
+ float e = *(float*)(*args++);
+ float f = *(float*)(*args++);
+ float g = *(float*)(*args++);
+ float h = *(float*)(*args++);
+ float i = *(float*)(*args++);
+ float j = *(float*)(*args++);
+ float k = *(float*)(*args++);
+ float l = *(float*)(*args++);
+ float m = *(float*)(*args++);
+ int z = *(int*)(*args++);
+ float r=a+b+c+d+e+f+g+h+i+j+k+l+m+z;
+ fprintf(out,"float f(13*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,m,z);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void d_di_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_di) { fprintf(out,"wrong data for d_di\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ int z = *(int*)(*args++);
+ double r=a+z;
+ fprintf(out,"double f(double,int):(%g,%d)",a,z);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d2i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d2i) { fprintf(out,"wrong data for d_d2i\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ int z = *(int*)(*args++);
+ double r=a+b+z;
+ fprintf(out,"double f(2*double,int):(%g,%g,%d)",a,b,z);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d3i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d3i) { fprintf(out,"wrong data for d_d3i\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double c = *(double*)(*args++);
+ int z = *(int*)(*args++);
+ double r=a+b+c+z;
+ fprintf(out,"double f(3*double,int):(%g,%g,%g,%d)",a,b,c,z);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d4i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d4i) { fprintf(out,"wrong data for d_d4i\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double c = *(double*)(*args++);
+ double d = *(double*)(*args++);
+ int z = *(int*)(*args++);
+ double r=a+b+c+d+z;
+ fprintf(out,"double f(4*double,int):(%g,%g,%g,%g,%d)",a,b,c,d,z);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d7i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d7i) { fprintf(out,"wrong data for d_d7i\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double c = *(double*)(*args++);
+ double d = *(double*)(*args++);
+ double e = *(double*)(*args++);
+ double f = *(double*)(*args++);
+ double g = *(double*)(*args++);
+ int z = *(int*)(*args++);
+ double r=a+b+c+d+e+f+g+z;
+ fprintf(out,"double f(7*double,int):(%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,z);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d8i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d8i) { fprintf(out,"wrong data for d_d8i\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double c = *(double*)(*args++);
+ double d = *(double*)(*args++);
+ double e = *(double*)(*args++);
+ double f = *(double*)(*args++);
+ double g = *(double*)(*args++);
+ double h = *(double*)(*args++);
+ int z = *(int*)(*args++);
+ double r=a+b+c+d+e+f+g+h+z;
+ fprintf(out,"double f(8*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,z);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d12i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d12i) { fprintf(out,"wrong data for d_d12i\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double c = *(double*)(*args++);
+ double d = *(double*)(*args++);
+ double e = *(double*)(*args++);
+ double f = *(double*)(*args++);
+ double g = *(double*)(*args++);
+ double h = *(double*)(*args++);
+ double i = *(double*)(*args++);
+ double j = *(double*)(*args++);
+ double k = *(double*)(*args++);
+ double l = *(double*)(*args++);
+ int z = *(int*)(*args++);
+ double r=a+b+c+d+e+f+g+h+i+j+k+l+z;
+ fprintf(out,"double f(12*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,z);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_d13i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d13i) { fprintf(out,"wrong data for d_d13i\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double c = *(double*)(*args++);
+ double d = *(double*)(*args++);
+ double e = *(double*)(*args++);
+ double f = *(double*)(*args++);
+ double g = *(double*)(*args++);
+ double h = *(double*)(*args++);
+ double i = *(double*)(*args++);
+ double j = *(double*)(*args++);
+ double k = *(double*)(*args++);
+ double l = *(double*)(*args++);
+ double m = *(double*)(*args++);
+ int z = *(int*)(*args++);
+ double r=a+b+c+d+e+f+g+h+i+j+k+l+m+z;
+ fprintf(out,"double f(13*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,m,z);
+ fflush(out);
+ *(double*)retp = r;
+}}
+
+/* small structure return tests */
+void S1_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&S1_v) { fprintf(out,"wrong data for S1_v\n"); exit(1); }
+ {Size1 r = Size1_1;
+ fprintf(out,"Size1 f(void):");
+ fflush(out);
+ *(Size1*)retp = r;
+}}
+void S2_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&S2_v) { fprintf(out,"wrong data for S2_v\n"); exit(1); }
+ {Size2 r = Size2_1;
+ fprintf(out,"Size2 f(void):");
+ fflush(out);
+ *(Size2*)retp = r;
+}}
+void S3_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&S3_v) { fprintf(out,"wrong data for S3_v\n"); exit(1); }
+ {Size3 r = Size3_1;
+ fprintf(out,"Size3 f(void):");
+ fflush(out);
+ *(Size3*)retp = r;
+}}
+void S4_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&S4_v) { fprintf(out,"wrong data for S4_v\n"); exit(1); }
+ {Size4 r = Size4_1;
+ fprintf(out,"Size4 f(void):");
+ fflush(out);
+ *(Size4*)retp = r;
+}}
+void S7_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&S7_v) { fprintf(out,"wrong data for S7_v\n"); exit(1); }
+ {Size7 r = Size7_1;
+ fprintf(out,"Size7 f(void):");
+ fflush(out);
+ *(Size7*)retp = r;
+}}
+void S8_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&S8_v) { fprintf(out,"wrong data for S8_v\n"); exit(1); }
+ {Size8 r = Size8_1;
+ fprintf(out,"Size8 f(void):");
+ fflush(out);
+ *(Size8*)retp = r;
+}}
+void S12_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&S12_v) { fprintf(out,"wrong data for S12_v\n"); exit(1); }
+ {Size12 r = Size12_1;
+ fprintf(out,"Size12 f(void):");
+ fflush(out);
+ *(Size12*)retp = r;
+}}
+void S15_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&S15_v) { fprintf(out,"wrong data for S15_v\n"); exit(1); }
+ {Size15 r = Size15_1;
+ fprintf(out,"Size15 f(void):");
+ fflush(out);
+ *(Size15*)retp = r;
+}}
+void S16_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&S16_v) { fprintf(out,"wrong data for S16_v\n"); exit(1); }
+ {Size16 r = Size16_1;
+ fprintf(out,"Size16 f(void):");
+ fflush(out);
+ *(Size16*)retp = r;
+}}
+
+/* structure tests */
+void I_III_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&I_III) { fprintf(out,"wrong data for I_III\n"); exit(1); }
+ {Int a = *(Int*)(*args++);
+ Int b = *(Int*)(*args++);
+ Int c = *(Int*)(*args++);
+ Int r;
+ r.x = a.x + b.x + c.x;
+ fprintf(out,"Int f(Int,Int,Int):({%d},{%d},{%d})",a.x,b.x,c.x);
+ fflush(out);
+ *(Int*)retp = r;
+}}
+void C_CdC_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&C_CdC) { fprintf(out,"wrong data for C_CdC\n"); exit(1); }
+ {Char a = *(Char*)(*args++);
+ double b = *(double*)(*args++);
+ Char c = *(Char*)(*args++);
+ Char r;
+ r.x = (a.x + c.x)/2;
+ fprintf(out,"Char f(Char,double,Char):({'%c'},%g,{'%c'})",a.x,b,c.x);
+ fflush(out);
+ *(Char*)retp = r;
+}}
+void F_Ffd_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&F_Ffd) { fprintf(out,"wrong data for F_Ffd\n"); exit(1); }
+ {Float a = *(Float*)(*args++);
+ float b = *(float*)(*args++);
+ double c = *(double*)(*args++);
+ Float r;
+ r.x = a.x + b + c;
+ fprintf(out,"Float f(Float,float,double):({%g},%g,%g)",a.x,b,c);
+ fflush(out);
+ *(Float*)retp = r;
+}}
+void D_fDd_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&D_fDd) { fprintf(out,"wrong data for D_fDd\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ Double b = *(Double*)(*args++);
+ double c = *(double*)(*args++);
+ Double r;
+ r.x = a + b.x + c;
+ fprintf(out,"Double f(float,Double,double):(%g,{%g},%g)",a,b.x,c);
+ fflush(out);
+ *(Double*)retp = r;
+}}
+void D_Dfd_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&D_Dfd) { fprintf(out,"wrong data for D_Dfd\n"); exit(1); }
+ {Double a = *(Double*)(*args++);
+ float b = *(float*)(*args++);
+ double c = *(double*)(*args++);
+ Double r;
+ r.x = a.x + b + c;
+ fprintf(out,"Double f(Double,float,double):({%g},%g,%g)",a.x,b,c);
+ fflush(out);
+ *(Double*)retp = r;
+}}
+void J_JiJ_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&J_JiJ) { fprintf(out,"wrong data for J_JiJ\n"); exit(1); }
+ {J a = *(J*)(*args++);
+ int b= *(int*)(*args++);
+ J c = *(J*)(*args++);
+ J r;
+ r.l1 = a.l1+c.l1; r.l2 = a.l2+b+c.l2;
+ fprintf(out,"J f(J,int,J):({%ld,%ld},%d,{%ld,%ld})",a.l1,a.l2,b,c.l1,c.l2);
+ fflush(out);
+ *(J*)retp = r;
+}}
+#ifndef SKIP_EXTRA_STRUCTS
+void T_TcT_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&T_TcT) { fprintf(out,"wrong data for T_TcT\n"); exit(1); }
+ {T a = *(T*)(*args++);
+ char b = *(char*)(*args++);
+ T c = *(T*)(*args++);
+ T r;
+ r.c[0]='b'; r.c[1]=c.c[1]; r.c[2]=c.c[2];
+ fprintf(out,"T f(T,char,T):({\"%c%c%c\"},'%c',{\"%c%c%c\"})",a.c[0],a.c[1],a.c[2],b,c.c[0],c.c[1],c.c[2]);
+ fflush(out);
+ *(T*)retp = r;
+}}
+void X_BcdB_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&X_BcdB) { fprintf(out,"wrong data for X_BcdB\n"); exit(1); }
+ {B a = *(B*)(*args++);
+ char b = *(char*)(*args++);
+ double c = *(double*)(*args++);
+ B d = *(B*)(*args++);
+ static X xr={"return val",'R'};
+ X r;
+ r = xr;
+ r.c1 = b;
+ fprintf(out,"X f(B,char,double,B):({%g,{%d,%d,%d}},'%c',%g,{%g,{%d,%d,%d}})",
+ a.d,a.i[0],a.i[1],a.i[2],b,c,d.d,d.i[0],d.i[1],d.i[2]);
+ fflush(out);
+ *(X*)retp = r;
+}}
+#endif
+
+/* gpargs boundary tests */
+void l_l0K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&l_l0K) { fprintf(out,"wrong data for l_l0K\n"); exit(1); }
+ {K b = *(K*)(*args++);
+ long c = *(long*)(*args++);
+ long r = b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(K,long):(%ld,%ld,%ld,%ld,%ld)",b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void l_l1K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&l_l1K) { fprintf(out,"wrong data for l_l1K\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ K b = *(K*)(*args++);
+ long c = *(long*)(*args++);
+ long r = a1 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld)",a1,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void l_l2K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&l_l2K) { fprintf(out,"wrong data for l_l2K\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ K b = *(K*)(*args++);
+ long c = *(long*)(*args++);
+ long r = a1 + a2 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(2*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void l_l3K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&l_l3K) { fprintf(out,"wrong data for l_l3K\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ K b = *(K*)(*args++);
+ long c = *(long*)(*args++);
+ long r = a1 + a2 + a3 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(3*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void l_l4K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&l_l4K) { fprintf(out,"wrong data for l_l4K\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ K b = *(K*)(*args++);
+ long c = *(long*)(*args++);
+ long r = a1 + a2 + a3 + a4 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(4*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void l_l5K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&l_l5K) { fprintf(out,"wrong data for l_l5K\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ long a5 = *(long*)(*args++);
+ K b = *(K*)(*args++);
+ long c = *(long*)(*args++);
+ long r = a1 + a2 + a3 + a4 + a5 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(5*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,a5,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void l_l6K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&l_l6K) { fprintf(out,"wrong data for l_l6K\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ long a5 = *(long*)(*args++);
+ long a6 = *(long*)(*args++);
+ K b = *(K*)(*args++);
+ long c = *(long*)(*args++);
+ long r = a1 + a2 + a3 + a4 + a5 + a6 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(6*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,a5,a6,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ *(ffi_arg*)retp = r;
+}}
+void f_f17l3L_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&f_f17l3L) { fprintf(out,"wrong data for f_f17l3L\n"); exit(1); }
+ {float a = *(float*)(*args++);
+ float b = *(float*)(*args++);
+ float c = *(float*)(*args++);
+ float d = *(float*)(*args++);
+ float e = *(float*)(*args++);
+ float f = *(float*)(*args++);
+ float g = *(float*)(*args++);
+ float h = *(float*)(*args++);
+ float i = *(float*)(*args++);
+ float j = *(float*)(*args++);
+ float k = *(float*)(*args++);
+ float l = *(float*)(*args++);
+ float m = *(float*)(*args++);
+ float n = *(float*)(*args++);
+ float o = *(float*)(*args++);
+ float p = *(float*)(*args++);
+ float q = *(float*)(*args++);
+ long s = *(long*)(*args++);
+ long t = *(long*)(*args++);
+ long u = *(long*)(*args++);
+ L z = *(L*)(*args++);
+ float r = a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+z.l1+z.l2+z.l3+z.l4+z.l5+z.l6;
+ fprintf(out,"float f(17*float,3*int,L):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,z.l1,z.l2,z.l3,z.l4,z.l5,z.l6);
+ fflush(out);
+ *(float*)retp = r;
+}}
+void d_d17l3L_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_d17l3L) { fprintf(out,"wrong data for d_d17l3L\n"); exit(1); }
+ {double a = *(double*)(*args++);
+ double b = *(double*)(*args++);
+ double c = *(double*)(*args++);
+ double d = *(double*)(*args++);
+ double e = *(double*)(*args++);
+ double f = *(double*)(*args++);
+ double g = *(double*)(*args++);
+ double h = *(double*)(*args++);
+ double i = *(double*)(*args++);
+ double j = *(double*)(*args++);
+ double k = *(double*)(*args++);
+ double l = *(double*)(*args++);
+ double m = *(double*)(*args++);
+ double n = *(double*)(*args++);
+ double o = *(double*)(*args++);
+ double p = *(double*)(*args++);
+ double q = *(double*)(*args++);
+ long s = *(long*)(*args++);
+ long t = *(long*)(*args++);
+ long u = *(long*)(*args++);
+ L z = *(L*)(*args++);
+ double r = a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+z.l1+z.l2+z.l3+z.l4+z.l5+z.l6;
+ fprintf(out,"double f(17*double,3*int,L):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,z.l1,z.l2,z.l3,z.l4,z.l5,z.l6);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void ll_l2ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&ll_l2ll) { fprintf(out,"wrong data for ll_l2ll\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long long b = *(long long *)(*args++);
+ long c = *(long*)(*args++);
+ long long r = (long long) (a1 + a2) + b + c;
+ fprintf(out,"long long f(2*long,long long,long):(%ld,%ld,0x%lx%08lx,%ld)",a1,a2,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ *(long long *)retp = r;
+}}
+void ll_l3ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&ll_l3ll) { fprintf(out,"wrong data for ll_l3ll\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long long b = *(long long *)(*args++);
+ long c = *(long*)(*args++);
+ long long r = (long long) (a1 + a2 + a3) + b + c;
+ fprintf(out,"long long f(3*long,long long,long):(%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ *(long long *)retp = r;
+}}
+void ll_l4ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&ll_l4ll) { fprintf(out,"wrong data for ll_l4ll\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ long long b = *(long long *)(*args++);
+ long c = *(long*)(*args++);
+ long long r = (long long) (a1 + a2 + a3 + a4) + b + c;
+ fprintf(out,"long long f(4*long,long long,long):(%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ *(long long *)retp = r;
+}}
+void ll_l5ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&ll_l5ll) { fprintf(out,"wrong data for ll_l5ll\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ long a5 = *(long*)(*args++);
+ long long b = *(long long *)(*args++);
+ long c = *(long*)(*args++);
+ long long r = (long long) (a1 + a2 + a3 + a4 + a5) + b + c;
+ fprintf(out,"long long f(5*long,long long,long):(%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ *(long long *)retp = r;
+}}
+void ll_l6ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&ll_l6ll) { fprintf(out,"wrong data for ll_l6ll\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ long a5 = *(long*)(*args++);
+ long a6 = *(long*)(*args++);
+ long long b = *(long long *)(*args++);
+ long c = *(long*)(*args++);
+ long long r = (long long) (a1 + a2 + a3 + a4 + a5 + a6) + b + c;
+ fprintf(out,"long long f(6*long,long long,long):(%ld,%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,a6,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ *(long long *)retp = r;
+}}
+void ll_l7ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&ll_l7ll) { fprintf(out,"wrong data for ll_l7ll\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ long a5 = *(long*)(*args++);
+ long a6 = *(long*)(*args++);
+ long a7 = *(long*)(*args++);
+ long long b = *(long long *)(*args++);
+ long c = *(long*)(*args++);
+ long long r = (long long) (a1 + a2 + a3 + a4 + a5 + a6 + a7) + b + c;
+ fprintf(out,"long long f(7*long,long long,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,a6,a7,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ *(long long *)retp = r;
+}}
+void d_l2d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_l2d) { fprintf(out,"wrong data for d_l2d\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ double b = *(double*)(*args++);
+ long c = *(long*)(*args++);
+ double r = (double) (a1 + a2) + b + c;
+ fprintf(out,"double f(2*long,double,long):(%ld,%ld,%g,%ld)",a1,a2,b,c);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_l3d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_l3d) { fprintf(out,"wrong data for d_l3d\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ double b = *(double*)(*args++);
+ long c = *(long*)(*args++);
+ double r = (double) (a1 + a2 + a3) + b + c;
+ fprintf(out,"double f(3*long,double,long):(%ld,%ld,%ld,%g,%ld)",a1,a2,a3,b,c);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_l4d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_l4d) { fprintf(out,"wrong data for d_l4d\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ double b = *(double*)(*args++);
+ long c = *(long*)(*args++);
+ double r = (double) (a1 + a2 + a3 + a4) + b + c;
+ fprintf(out,"double f(4*long,double,long):(%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,b,c);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_l5d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_l5d) { fprintf(out,"wrong data for d_l5d\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ long a5 = *(long*)(*args++);
+ double b = *(double*)(*args++);
+ long c = *(long*)(*args++);
+ double r = (double) (a1 + a2 + a3 + a4 + a5) + b + c;
+ fprintf(out,"double f(5*long,double,long):(%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,b,c);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_l6d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_l6d) { fprintf(out,"wrong data for d_l6d\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ long a5 = *(long*)(*args++);
+ long a6 = *(long*)(*args++);
+ double b = *(double*)(*args++);
+ long c = *(long*)(*args++);
+ double r = (double) (a1 + a2 + a3 + a4 + a5 + a6) + b + c;
+ fprintf(out,"double f(6*long,double,long):(%ld,%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,a6,b,c);
+ fflush(out);
+ *(double*)retp = r;
+}}
+void d_l7d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
+{
+ if (data != (void*)&d_l7d) { fprintf(out,"wrong data for d_l7d\n"); exit(1); }
+ {long a1 = *(long*)(*args++);
+ long a2 = *(long*)(*args++);
+ long a3 = *(long*)(*args++);
+ long a4 = *(long*)(*args++);
+ long a5 = *(long*)(*args++);
+ long a6 = *(long*)(*args++);
+ long a7 = *(long*)(*args++);
+ double b = *(double*)(*args++);
+ long c = *(long*)(*args++);
+ double r = (double) (a1 + a2 + a3 + a4 + a5 + a6 + a7) + b + c;
+ fprintf(out,"double f(7*long,double,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,a6,a7,b,c);
+ fflush(out);
+ *(double*)retp = r;
+}}
+
+
+/*
+ * The way we run these tests - first call the function directly, then
+ * through vacall() - there is the danger that arguments or results seem
+ * to be passed correctly, but what we are seeing are in fact the vestiges
+ * (traces) or the previous call. This may seriously fake the test.
+ * Avoid this by clearing the registers between the first and the second call.
+ */
+long clear_traces_i (long a, long b, long c, long d, long e, long f, long g, long h,
+ long i, long j, long k, long l, long m, long n, long o, long p)
+{ return 0; }
+float clear_traces_f (float a, float b, float c, float d, float e, float f, float g,
+ float h, float i, float j, float k, float l, float m, float n,
+ float o, float p)
+{ return 0.0; }
+double clear_traces_d (double a, double b, double c, double d, double e, double f, double g,
+ double h, double i, double j, double k, double l, double m, double n,
+ double o, double p)
+{ return 0.0; }
+J clear_traces_J (void)
+{ J j; j.l1 = j.l2 = 0; return j; }
+void clear_traces (void)
+{ clear_traces_i(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+ clear_traces_f(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
+ clear_traces_d(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
+ clear_traces_J();
+}
+
+int main (void)
+{
+ void* callback_code;
+ void* callback_writable;
+#define ALLOC_CALLBACK() \
+ callback_writable = ffi_closure_alloc(sizeof(ffi_closure),&callback_code); \
+ if (!callback_writable) abort()
+#define PREP_CALLBACK(cif,simulator,data) \
+ if (ffi_prep_closure_loc(callback_writable,&(cif),simulator,data,callback_code) != FFI_OK) abort()
+#define FREE_CALLBACK() \
+ ffi_closure_free(callback_writable)
+
+ ffi_type_char = (char)(-1) < 0 ? ffi_type_schar : ffi_type_uchar;
+ out = stdout;
+
+#if (!defined(DGTEST)) || DGTEST == 1
+ /* void tests */
+ v_v();
+ clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_void);
+ PREP_CALLBACK(cif,v_v_simulator,(void*)&v_v);
+ ((void (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+#endif
+
+ /* int tests */
+ { int ir;
+
+#if (!defined(DGTEST)) || DGTEST == 2
+ ir = i_v();
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_sint);
+ PREP_CALLBACK(cif,i_v_simulator,(void*)&i_v);
+ ir = ((int (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 3
+ ir = i_i(i1);
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
+ PREP_CALLBACK(cif,i_i_simulator,(void*)&i_i);
+ ir = ((int (ABI_ATTR *) (int)) callback_code) (i1);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 4
+ ir = i_i2(i1,i2);
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
+ PREP_CALLBACK(cif,i_i2_simulator,(void*)&i_i2);
+ ir = ((int (ABI_ATTR *) (int,int)) callback_code) (i1,i2);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 5
+ ir = i_i4(i1,i2,i3,i4);
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
+ PREP_CALLBACK(cif,i_i4_simulator,(void*)&i_i4);
+ ir = ((int (ABI_ATTR *) (int,int,int,int)) callback_code) (i1,i2,i3,i4);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 6
+ ir = i_i8(i1,i2,i3,i4,i5,i6,i7,i8);
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
+ PREP_CALLBACK(cif,i_i8_simulator,(void*)&i_i8);
+ ir = ((int (ABI_ATTR *) (int,int,int,int,int,int,int,int)) callback_code) (i1,i2,i3,i4,i5,i6,i7,i8);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 7
+ ir = i_i16(i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16);
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+ ir = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
+ PREP_CALLBACK(cif,i_i16_simulator,(void*)&i_i16);
+ ir = ((int (ABI_ATTR *) (int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int)) callback_code) (i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%d\n",ir);
+ fflush(out);
+#endif
+ }
+
+ /* float tests */
+ { float fr;
+
+#if (!defined(DGTEST)) || DGTEST == 8
+ fr = f_f(f1);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f_simulator,(void*)&f_f);
+ fr = ((float (ABI_ATTR *) (float)) callback_code) (f1);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 9
+ fr = f_f2(f1,f2);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f2_simulator,(void*)&f_f2);
+ fr = ((float (ABI_ATTR *) (float,float)) callback_code) (f1,f2);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 10
+ fr = f_f4(f1,f2,f3,f4);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f4_simulator,(void*)&f_f4);
+ fr = ((float (ABI_ATTR *) (float,float,float,float)) callback_code) (f1,f2,f3,f4);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 11
+ fr = f_f8(f1,f2,f3,f4,f5,f6,f7,f8);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f8_simulator,(void*)&f_f8);
+ fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 12
+ fr = f_f16(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f16_simulator,(void*)&f_f16);
+ fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 13
+ fr = f_f24(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20,f21,f22,f23,f24);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f24_simulator,(void*)&f_f24);
+ fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20,f21,f22,f23,f24);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+ }
+
+ /* double tests */
+ { double dr;
+
+#if (!defined(DGTEST)) || DGTEST == 14
+ dr = d_d(d1);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d_simulator,(void*)&d_d);
+ dr = ((double (ABI_ATTR *) (double)) callback_code) (d1);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 15
+ dr = d_d2(d1,d2);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d2_simulator,(void*)&d_d2);
+ dr = ((double (ABI_ATTR *) (double,double)) callback_code) (d1,d2);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 16
+ dr = d_d4(d1,d2,d3,d4);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d4_simulator,(void*)&d_d4);
+ dr = ((double (ABI_ATTR *) (double,double,double,double)) callback_code) (d1,d2,d3,d4);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 17
+ dr = d_d8(d1,d2,d3,d4,d5,d6,d7,d8);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d8_simulator,(void*)&d_d8);
+ dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 18
+ dr = d_d16(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d16_simulator,(void*)&d_d16);
+ dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,double)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+ }
+
+ /* pointer tests */
+ { void* vpr;
+
+#if (!defined(DGTEST)) || DGTEST == 19
+ vpr = vp_vpdpcpsp(&uc1,&d2,str3,&I4);
+ fprintf(out,"->0x%p\n",vpr);
+ fflush(out);
+ vpr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_pointer, &ffi_type_pointer, &ffi_type_pointer, &ffi_type_pointer };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_pointer);
+ PREP_CALLBACK(cif,vp_vpdpcpsp_simulator,(void*)&vp_vpdpcpsp);
+ vpr = ((void* (ABI_ATTR *) (void*,double*,char*,Int*)) callback_code) (&uc1,&d2,str3,&I4);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->0x%p\n",vpr);
+ fflush(out);
+#endif
+ }
+
+ /* mixed number tests */
+ { uchar ucr;
+ ushort usr;
+ float fr;
+ double dr;
+ long long llr;
+
+#if (!defined(DGTEST)) || DGTEST == 20
+ ucr = uc_ucsil(uc1,us2,ui3,ul4);
+ fprintf(out,"->%u\n",ucr);
+ fflush(out);
+ ucr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_uchar, &ffi_type_ushort, &ffi_type_uint, &ffi_type_ulong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_uchar);
+ PREP_CALLBACK(cif,uc_ucsil_simulator,(void*)&uc_ucsil);
+ ucr = ((uchar (ABI_ATTR *) (uchar,ushort,uint,ulong)) callback_code) (uc1,us2,ui3,ul4);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%u\n",ucr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 21
+ dr = d_iidd(i1,i2,d3,d4);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_iidd_simulator,(void*)&d_iidd);
+ dr = ((double (ABI_ATTR *) (int,int,double,double)) callback_code) (i1,i2,d3,d4);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 22
+ dr = d_iiidi(i1,i2,i3,d4,i5);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_iiidi_simulator,(void*)&d_iiidi);
+ dr = ((double (ABI_ATTR *) (int,int,int,double,int)) callback_code) (i1,i2,i3,d4,i5);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 23
+ dr = d_idid(i1,d2,i3,d4);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_double, &ffi_type_sint, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_idid_simulator,(void*)&d_idid);
+ dr = ((double (ABI_ATTR *) (int,double,int,double)) callback_code) (i1,d2,i3,d4);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 24
+ dr = d_fdi(f1,d2,i3);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_fdi_simulator,(void*)&d_fdi);
+ dr = ((double (ABI_ATTR *) (float,double,int)) callback_code) (f1,d2,i3);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 25
+ usr = us_cdcd(c1,d2,c3,d4);
+ fprintf(out,"->%u\n",usr);
+ fflush(out);
+ usr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_char, &ffi_type_double, &ffi_type_char, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_ushort);
+ PREP_CALLBACK(cif,us_cdcd_simulator,(void*)&us_cdcd);
+ usr = ((ushort (ABI_ATTR *) (char,double,char,double)) callback_code) (c1,d2,c3,d4);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%u\n",usr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 26
+ llr = ll_iiilli(i1,i2,i3,ll1,i13);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_slonglong, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ PREP_CALLBACK(cif,ll_iiilli_simulator,(void*)&ll_iiilli);
+ llr = ((long long (ABI_ATTR *) (int,int,int,long long,int)) callback_code) (i1,i2,i3,ll1,i13);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 27
+ llr = ll_flli(f13,ll1,i13);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_slonglong, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ PREP_CALLBACK(cif,ll_flli_simulator,(void*)&ll_flli);
+ llr = ((long long (ABI_ATTR *) (float,long long,int)) callback_code) (f13,ll1,i13);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 28
+ fr = f_fi(f1,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_fi_simulator,(void*)&f_fi);
+ fr = ((float (ABI_ATTR *) (float,int)) callback_code) (f1,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 29
+ fr = f_f2i(f1,f2,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f2i_simulator,(void*)&f_f2i);
+ fr = ((float (ABI_ATTR *) (float,float,int)) callback_code) (f1,f2,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 30
+ fr = f_f3i(f1,f2,f3,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f3i_simulator,(void*)&f_f3i);
+ fr = ((float (ABI_ATTR *) (float,float,float,int)) callback_code) (f1,f2,f3,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 31
+ fr = f_f4i(f1,f2,f3,f4,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f4i_simulator,(void*)&f_f4i);
+ fr = ((float (ABI_ATTR *) (float,float,float,float,int)) callback_code) (f1,f2,f3,f4,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 32
+ fr = f_f7i(f1,f2,f3,f4,f5,f6,f7,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f7i_simulator,(void*)&f_f7i);
+ fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,int)) callback_code) (f1,f2,f3,f4,f5,f6,f7,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 33
+ fr = f_f8i(f1,f2,f3,f4,f5,f6,f7,f8,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f8i_simulator,(void*)&f_f8i);
+ fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float,int)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 34
+ fr = f_f13i(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,i9);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f13i_simulator,(void*)&f_f13i);
+ fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float,float,float,float,float,float,int)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 35
+ dr = d_di(d1,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_di_simulator,(void*)&d_di);
+ dr = ((double (ABI_ATTR *) (double,int)) callback_code) (d1,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 36
+ dr = d_d2i(d1,d2,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d2i_simulator,(void*)&d_d2i);
+ dr = ((double (ABI_ATTR *) (double,double,int)) callback_code) (d1,d2,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 37
+ dr = d_d3i(d1,d2,d3,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d3i_simulator,(void*)&d_d3i);
+ dr = ((double (ABI_ATTR *) (double,double,double,int)) callback_code) (d1,d2,d3,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 38
+ dr = d_d4i(d1,d2,d3,d4,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d4i_simulator,(void*)&d_d4i);
+ dr = ((double (ABI_ATTR *) (double,double,double,double,int)) callback_code) (d1,d2,d3,d4,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 39
+ dr = d_d7i(d1,d2,d3,d4,d5,d6,d7,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d7i_simulator,(void*)&d_d7i);
+ dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,int)) callback_code) (d1,d2,d3,d4,d5,d6,d7,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 40
+ dr = d_d8i(d1,d2,d3,d4,d5,d6,d7,d8,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d8i_simulator,(void*)&d_d8i);
+ dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double,int)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 41
+ dr = d_d12i(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d12i_simulator,(void*)&d_d12i);
+ dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double,double,double,double,double,int)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 42
+ dr = d_d13i(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,i9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d13i_simulator,(void*)&d_d13i);
+ dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double,double,double,double,double,double,int)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,i9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+ }
+
+ /* small structure return tests */
+#if (!defined(DGTEST)) || DGTEST == 43
+ {
+ Size1 r = S1_v();
+ fprintf(out,"->{%c}\n",r.x1);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Size1_elements[] = { &ffi_type_char, NULL };
+ ffi_type ffi_type_Size1;
+ ffi_type_Size1.type = FFI_TYPE_STRUCT;
+ ffi_type_Size1.size = sizeof(Size1);
+ ffi_type_Size1.alignment = alignof_slot(Size1);
+ ffi_type_Size1.elements = ffi_type_Size1_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size1);
+ PREP_CALLBACK(cif,S1_v_simulator,(void*)&S1_v);
+ r = ((Size1 (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%c}\n",r.x1);
+ fflush(out);
+ }
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 44
+ {
+ Size2 r = S2_v();
+ fprintf(out,"->{%c%c}\n",r.x1,r.x2);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Size2_elements[] = { &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size2;
+ ffi_type_Size2.type = FFI_TYPE_STRUCT;
+ ffi_type_Size2.size = sizeof(Size2);
+ ffi_type_Size2.alignment = alignof_slot(Size2);
+ ffi_type_Size2.elements = ffi_type_Size2_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size2);
+ PREP_CALLBACK(cif,S2_v_simulator,(void*)&S2_v);
+ r = ((Size2 (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%c%c}\n",r.x1,r.x2);
+ fflush(out);
+ }
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 45
+ {
+ Size3 r = S3_v();
+ fprintf(out,"->{%c%c%c}\n",r.x1,r.x2,r.x3);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Size3_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size3;
+ ffi_type_Size3.type = FFI_TYPE_STRUCT;
+ ffi_type_Size3.size = sizeof(Size3);
+ ffi_type_Size3.alignment = alignof_slot(Size3);
+ ffi_type_Size3.elements = ffi_type_Size3_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size3);
+ PREP_CALLBACK(cif,S3_v_simulator,(void*)&S3_v);
+ r = ((Size3 (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%c%c%c}\n",r.x1,r.x2,r.x3);
+ fflush(out);
+ }
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 46
+ {
+ Size4 r = S4_v();
+ fprintf(out,"->{%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Size4_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size4;
+ ffi_type_Size4.type = FFI_TYPE_STRUCT;
+ ffi_type_Size4.size = sizeof(Size4);
+ ffi_type_Size4.alignment = alignof_slot(Size4);
+ ffi_type_Size4.elements = ffi_type_Size4_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size4);
+ PREP_CALLBACK(cif,S4_v_simulator,(void*)&S4_v);
+ r = ((Size4 (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4);
+ fflush(out);
+ }
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 47
+ {
+ Size7 r = S7_v();
+ fprintf(out,"->{%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Size7_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size7;
+ ffi_type_Size7.type = FFI_TYPE_STRUCT;
+ ffi_type_Size7.size = sizeof(Size7);
+ ffi_type_Size7.alignment = alignof_slot(Size7);
+ ffi_type_Size7.elements = ffi_type_Size7_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size7);
+ PREP_CALLBACK(cif,S7_v_simulator,(void*)&S7_v);
+ r = ((Size7 (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7);
+ fflush(out);
+ }
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 48
+ {
+ Size8 r = S8_v();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Size8_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size8;
+ ffi_type_Size8.type = FFI_TYPE_STRUCT;
+ ffi_type_Size8.size = sizeof(Size8);
+ ffi_type_Size8.alignment = alignof_slot(Size8);
+ ffi_type_Size8.elements = ffi_type_Size8_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size8);
+ PREP_CALLBACK(cif,S8_v_simulator,(void*)&S8_v);
+ r = ((Size8 (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8);
+ fflush(out);
+ }
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 49
+ {
+ Size12 r = S12_v();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Size12_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size12;
+ ffi_type_Size12.type = FFI_TYPE_STRUCT;
+ ffi_type_Size12.size = sizeof(Size12);
+ ffi_type_Size12.alignment = alignof_slot(Size12);
+ ffi_type_Size12.elements = ffi_type_Size12_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size12);
+ PREP_CALLBACK(cif,S12_v_simulator,(void*)&S12_v);
+ r = ((Size12 (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12);
+ fflush(out);
+ }
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 50
+ {
+ Size15 r = S15_v();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Size15_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size15;
+ ffi_type_Size15.type = FFI_TYPE_STRUCT;
+ ffi_type_Size15.size = sizeof(Size15);
+ ffi_type_Size15.alignment = alignof_slot(Size15);
+ ffi_type_Size15.elements = ffi_type_Size15_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size15);
+ PREP_CALLBACK(cif,S15_v_simulator,(void*)&S15_v);
+ r = ((Size15 (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15);
+ fflush(out);
+ }
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 51
+ {
+ Size16 r = S16_v();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15,r.x16);
+ fflush(out);
+ memset(&r,0,sizeof(r)); clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Size16_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
+ ffi_type ffi_type_Size16;
+ ffi_type_Size16.type = FFI_TYPE_STRUCT;
+ ffi_type_Size16.size = sizeof(Size16);
+ ffi_type_Size16.alignment = alignof_slot(Size16);
+ ffi_type_Size16.elements = ffi_type_Size16_elements;
+ ffi_cif cif;
+ FFI_PREP_CIF_NOARGS(cif,ffi_type_Size16);
+ PREP_CALLBACK(cif,S16_v_simulator,(void*)&S16_v);
+ r = ((Size16 (ABI_ATTR *) (void)) callback_code) ();
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15,r.x16);
+ fflush(out);
+ }
+#endif
+
+
+ /* structure tests */
+ { Int Ir;
+ Char Cr;
+ Float Fr;
+ Double Dr;
+ J Jr;
+#ifndef SKIP_EXTRA_STRUCTS
+ T Tr;
+ X Xr;
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 52
+ Ir = I_III(I1,I2,I3);
+ fprintf(out,"->{%d}\n",Ir.x);
+ fflush(out);
+ Ir.x = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Int_elements[] = { &ffi_type_sint, NULL };
+ ffi_type ffi_type_Int;
+ ffi_type_Int.type = FFI_TYPE_STRUCT;
+ ffi_type_Int.size = sizeof(Int);
+ ffi_type_Int.alignment = alignof_slot(Int);
+ ffi_type_Int.elements = ffi_type_Int_elements;
+ ffi_type* argtypes[] = { &ffi_type_Int, &ffi_type_Int, &ffi_type_Int };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_Int);
+ PREP_CALLBACK(cif,I_III_simulator,(void*)&I_III);
+ Ir = ((Int (ABI_ATTR *) (Int,Int,Int)) callback_code) (I1,I2,I3);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%d}\n",Ir.x);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 53
+ Cr = C_CdC(C1,d2,C3);
+ fprintf(out,"->{'%c'}\n",Cr.x);
+ fflush(out);
+ Cr.x = '\0'; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Char_elements[] = { &ffi_type_char, NULL };
+ ffi_type ffi_type_Char;
+ ffi_type_Char.type = FFI_TYPE_STRUCT;
+ ffi_type_Char.size = sizeof(Char);
+ ffi_type_Char.alignment = alignof_slot(Char);
+ ffi_type_Char.elements = ffi_type_Char_elements;
+ ffi_type* argtypes[] = { &ffi_type_Char, &ffi_type_double, &ffi_type_Char };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_Char);
+ PREP_CALLBACK(cif,C_CdC_simulator,(void*)&C_CdC);
+ Cr = ((Char (ABI_ATTR *) (Char,double,Char)) callback_code) (C1,d2,C3);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{'%c'}\n",Cr.x);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 54
+ Fr = F_Ffd(F1,f2,d3);
+ fprintf(out,"->{%g}\n",Fr.x);
+ fflush(out);
+ Fr.x = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Float_elements[] = { &ffi_type_float, NULL };
+ ffi_type ffi_type_Float;
+ ffi_type_Float.type = FFI_TYPE_STRUCT;
+ ffi_type_Float.size = sizeof(Float);
+ ffi_type_Float.alignment = alignof_slot(Float);
+ ffi_type_Float.elements = ffi_type_Float_elements;
+ ffi_type* argtypes[] = { &ffi_type_Float, &ffi_type_float, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_Float);
+ PREP_CALLBACK(cif,F_Ffd_simulator,(void*)&F_Ffd);
+ Fr = ((Float (ABI_ATTR *) (Float,float,double)) callback_code) (F1,f2,d3);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%g}\n",Fr.x);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 55
+ Dr = D_fDd(f1,D2,d3);
+ fprintf(out,"->{%g}\n",Dr.x);
+ fflush(out);
+ Dr.x = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Double_elements[] = { &ffi_type_double, NULL };
+ ffi_type ffi_type_Double;
+ ffi_type_Double.type = FFI_TYPE_STRUCT;
+ ffi_type_Double.size = sizeof(Double);
+ ffi_type_Double.alignment = alignof_slot(Double);
+ ffi_type_Double.elements = ffi_type_Double_elements;
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_Double, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_Double);
+ PREP_CALLBACK(cif,D_fDd_simulator,(void*)&D_fDd);
+ Dr = ((Double (ABI_ATTR *) (float,Double,double)) callback_code) (f1,D2,d3);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%g}\n",Dr.x);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 56
+ Dr = D_Dfd(D1,f2,d3);
+ fprintf(out,"->{%g}\n",Dr.x);
+ fflush(out);
+ Dr.x = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_Double_elements[] = { &ffi_type_double, NULL };
+ ffi_type ffi_type_Double;
+ ffi_type_Double.type = FFI_TYPE_STRUCT;
+ ffi_type_Double.size = sizeof(Double);
+ ffi_type_Double.alignment = alignof_slot(Double);
+ ffi_type_Double.elements = ffi_type_Double_elements;
+ ffi_type* argtypes[] = { &ffi_type_Double, &ffi_type_float, &ffi_type_double };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_Double);
+ PREP_CALLBACK(cif,D_Dfd_simulator,(void*)&D_Dfd);
+ Dr = ((Double (ABI_ATTR *) (Double,float,double)) callback_code) (D1,f2,d3);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%g}\n",Dr.x);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 57
+ Jr = J_JiJ(J1,i2,J2);
+ fprintf(out,"->{%ld,%ld}\n",Jr.l1,Jr.l2);
+ fflush(out);
+ Jr.l1 = Jr.l2 = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_J_elements[] = { &ffi_type_slong, &ffi_type_slong, NULL };
+ ffi_type ffi_type_J;
+ ffi_type_J.type = FFI_TYPE_STRUCT;
+ ffi_type_J.size = sizeof(J);
+ ffi_type_J.alignment = alignof_slot(J);
+ ffi_type_J.elements = ffi_type_J_elements;
+ ffi_type* argtypes[] = { &ffi_type_J, &ffi_type_sint, &ffi_type_J };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_J);
+ PREP_CALLBACK(cif,J_JiJ_simulator,(void*)&J_JiJ);
+ Jr = ((J (ABI_ATTR *) (J,int,J)) callback_code) (J1,i2,J2);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{%ld,%ld}\n",Jr.l1,Jr.l2);
+ fflush(out);
+#endif
+
+#ifndef SKIP_EXTRA_STRUCTS
+#if (!defined(DGTEST)) || DGTEST == 58
+ Tr = T_TcT(T1,' ',T2);
+ fprintf(out,"->{\"%c%c%c\"}\n",Tr.c[0],Tr.c[1],Tr.c[2]);
+ fflush(out);
+ Tr.c[0] = Tr.c[1] = Tr.c[2] = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_T_elements[] = { ??, NULL };
+ ffi_type ffi_type_T;
+ ffi_type_T.type = FFI_TYPE_STRUCT;
+ ffi_type_T.size = sizeof(T);
+ ffi_type_T.alignment = alignof_slot(T);
+ ffi_type_T.elements = ffi_type_T_elements;
+ ffi_type* argtypes[] = { &ffi_type_T, &ffi_type_char, &ffi_type_T };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_T);
+ PREP_CALLBACK(cif,T_TcT_simulator,(void*)&T_TcT);
+ Tr = ((T (ABI_ATTR *) (T,char,T)) callback_code) (T1,' ',T2);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{\"%c%c%c\"}\n",Tr.c[0],Tr.c[1],Tr.c[2]);
+ fflush(out);
+#endif
+
+#ifndef SKIP_X
+#if (!defined(DGTEST)) || DGTEST == 59
+ Xr = X_BcdB(B1,c2,d3,B2);
+ fprintf(out,"->{\"%s\",'%c'}\n",Xr.c,Xr.c1);
+ fflush(out);
+ Xr.c[0]=Xr.c1='\0'; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* ffi_type_X_elements[] = { ??, NULL };
+ ffi_type ffi_type_X;
+ ffi_type_X.type = FFI_TYPE_STRUCT;
+ ffi_type_X.size = sizeof(X);
+ ffi_type_X.alignment = alignof_slot(X);
+ ffi_type_X.elements = ffi_type_X_elements;
+ ffi_type* argtypes[] = { &ffi_type_X, &ffi_type_char, &ffi_type_double, &ffi_type_X };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_X);
+ PREP_CALLBACK(cif,X_BcdB_simulator,(void*)&X_BcdB);
+ Xr = ((X (ABI_ATTR *) (B,char,double,B)) callback_code) (B1,c2,d3,B2);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->{\"%s\",'%c'}\n",Xr.c,Xr.c1);
+ fflush(out);
+#endif
+#endif
+#endif
+ }
+
+
+ /* gpargs boundary tests */
+ {
+ ffi_type* ffi_type_K_elements[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, NULL };
+ ffi_type ffi_type_K;
+ ffi_type* ffi_type_L_elements[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, NULL };
+ ffi_type ffi_type_L;
+ long lr;
+ long long llr;
+ float fr;
+ double dr;
+
+ ffi_type_K.type = FFI_TYPE_STRUCT;
+ ffi_type_K.size = sizeof(K);
+ ffi_type_K.alignment = alignof_slot(K);
+ ffi_type_K.elements = ffi_type_K_elements;
+
+ ffi_type_L.type = FFI_TYPE_STRUCT;
+ ffi_type_L.size = sizeof(L);
+ ffi_type_L.alignment = alignof_slot(L);
+ ffi_type_L.elements = ffi_type_L_elements;
+
+#if (!defined(DGTEST)) || DGTEST == 60
+ lr = l_l0K(K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ PREP_CALLBACK(cif,l_l0K_simulator,(void*)l_l0K);
+ lr = ((long (ABI_ATTR *) (K,long)) callback_code) (K1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 61
+ lr = l_l1K(l1,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ PREP_CALLBACK(cif,l_l1K_simulator,(void*)l_l1K);
+ lr = ((long (ABI_ATTR *) (long,K,long)) callback_code) (l1,K1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 62
+ lr = l_l2K(l1,l2,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ PREP_CALLBACK(cif,l_l2K_simulator,(void*)l_l2K);
+ lr = ((long (ABI_ATTR *) (long,long,K,long)) callback_code) (l1,l2,K1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 63
+ lr = l_l3K(l1,l2,l3,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ PREP_CALLBACK(cif,l_l3K_simulator,(void*)l_l3K);
+ lr = ((long (ABI_ATTR *) (long,long,long,K,long)) callback_code) (l1,l2,l3,K1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 64
+ lr = l_l4K(l1,l2,l3,l4,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ PREP_CALLBACK(cif,l_l4K_simulator,(void*)l_l4K);
+ lr = ((long (ABI_ATTR *) (long,long,long,long,K,long)) callback_code) (l1,l2,l3,l4,K1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 65
+ lr = l_l5K(l1,l2,l3,l4,l5,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ PREP_CALLBACK(cif,l_l5K_simulator,(void*)l_l5K);
+ lr = ((long (ABI_ATTR *) (long,long,long,long,long,K,long)) callback_code) (l1,l2,l3,l4,l5,K1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 66
+ lr = l_l6K(l1,l2,l3,l4,l5,l6,K1,l9);
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+ lr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
+ PREP_CALLBACK(cif,l_l6K_simulator,(void*)l_l6K);
+ lr = ((long (ABI_ATTR *) (long,long,long,long,long,long,K,long)) callback_code) (l1,l2,l3,l4,l5,l6,K1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%ld\n",lr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 67
+ fr = f_f17l3L(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,l6,l7,l8,L1);
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+ fr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_L };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_float);
+ PREP_CALLBACK(cif,f_f17l3L_simulator,(void*)&f_f17l3L);
+ fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,long,long,long,L)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,l6,l7,l8,L1);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",fr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 68
+ dr = d_d17l3L(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,d17,l6,l7,l8,L1);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_L };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_d17l3L_simulator,(void*)&d_d17l3L);
+ dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,long,long,long,L)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,d17,l6,l7,l8,L1);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 69
+ llr = ll_l2ll(l1,l2,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ PREP_CALLBACK(cif,ll_l2ll_simulator,(void*)ll_l2ll);
+ llr = ((long long (ABI_ATTR *) (long,long,long long,long)) callback_code) (l1,l2,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 70
+ llr = ll_l3ll(l1,l2,l3,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ PREP_CALLBACK(cif,ll_l3ll_simulator,(void*)ll_l3ll);
+ llr = ((long long (ABI_ATTR *) (long,long,long,long long,long)) callback_code) (l1,l2,l3,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 71
+ llr = ll_l4ll(l1,l2,l3,l4,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ PREP_CALLBACK(cif,ll_l4ll_simulator,(void*)ll_l4ll);
+ llr = ((long long (ABI_ATTR *) (long,long,long,long,long long,long)) callback_code) (l1,l2,l3,l4,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 72
+ llr = ll_l5ll(l1,l2,l3,l4,l5,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ PREP_CALLBACK(cif,ll_l5ll_simulator,(void*)ll_l5ll);
+ llr = ((long long (ABI_ATTR *) (long,long,long,long,long,long long,long)) callback_code) (l1,l2,l3,l4,l5,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 73
+ llr = ll_l6ll(l1,l2,l3,l4,l5,l6,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ PREP_CALLBACK(cif,ll_l6ll_simulator,(void*)ll_l6ll);
+ llr = ((long long (ABI_ATTR *) (long,long,long,long,long,long,long long,long)) callback_code) (l1,l2,l3,l4,l5,l6,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 74
+ llr = ll_l7ll(l1,l2,l3,l4,l5,l6,l7,ll1,l9);
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+ llr = 0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
+ PREP_CALLBACK(cif,ll_l7ll_simulator,(void*)ll_l7ll);
+ llr = ((long long (ABI_ATTR *) (long,long,long,long,long,long,long,long long,long)) callback_code) (l1,l2,l3,l4,l5,l6,l7,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 75
+ dr = d_l2d(l1,l2,ll1,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_l2d_simulator,(void*)d_l2d);
+ dr = ((double (ABI_ATTR *) (long,long,double,long)) callback_code) (l1,l2,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 76
+ dr = d_l3d(l1,l2,l3,ll1,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_l3d_simulator,(void*)d_l3d);
+ dr = ((double (ABI_ATTR *) (long,long,long,double,long)) callback_code) (l1,l2,l3,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 77
+ dr = d_l4d(l1,l2,l3,l4,ll1,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_l4d_simulator,(void*)d_l4d);
+ dr = ((double (ABI_ATTR *) (long,long,long,long,double,long)) callback_code) (l1,l2,l3,l4,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 78
+ dr = d_l5d(l1,l2,l3,l4,l5,ll1,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_l5d_simulator,(void*)d_l5d);
+ dr = ((double (ABI_ATTR *) (long,long,long,long,long,double,long)) callback_code) (l1,l2,l3,l4,l5,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 79
+ dr = d_l6d(l1,l2,l3,l4,l5,l6,ll1,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_l6d_simulator,(void*)d_l6d);
+ dr = ((double (ABI_ATTR *) (long,long,long,long,long,long,double,long)) callback_code) (l1,l2,l3,l4,l5,l6,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+#if (!defined(DGTEST)) || DGTEST == 80
+ dr = d_l7d(l1,l2,l3,l4,l5,l6,l7,ll1,l9);
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+ dr = 0.0; clear_traces();
+ ALLOC_CALLBACK();
+ {
+ ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
+ ffi_cif cif;
+ FFI_PREP_CIF(cif,argtypes,ffi_type_double);
+ PREP_CALLBACK(cif,d_l7d_simulator,(void*)d_l7d);
+ dr = ((double (ABI_ATTR *) (long,long,long,long,long,long,long,double,long)) callback_code) (l1,l2,l3,l4,l5,l6,l7,ll1,l9);
+ }
+ FREE_CALLBACK();
+ fprintf(out,"->%g\n",dr);
+ fflush(out);
+#endif
+
+ }
+
+ exit(0);
+}
+
diff --git a/js/src/ctypes/libffi/testsuite/libffi.bhaible/testcases.c b/js/src/ctypes/libffi/testsuite/libffi.bhaible/testcases.c
new file mode 100644
index 0000000000..d25ebf48c9
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.bhaible/testcases.c
@@ -0,0 +1,743 @@
+/*
+ * Copyright 1993 Bill Triggs <Bill.Triggs@inrialpes.fr>
+ * Copyright 1995-2017 Bruno Haible <bruno@clisp.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This file defines test functions of selected signatures, that exercise
+ dark corners of the various ABIs. */
+
+#include <stdio.h>
+
+FILE* out;
+
+#define uchar unsigned char
+#define ushort unsigned short
+#define uint unsigned int
+#define ulong unsigned long
+
+typedef struct { char x; } Char;
+typedef struct { short x; } Short;
+typedef struct { int x; } Int;
+typedef struct { long x; } Long;
+typedef struct { float x; } Float;
+typedef struct { double x; } Double;
+typedef struct { char c; float f; } A;
+typedef struct { double d; int i[3]; } B;
+typedef struct { long l1; long l2; } J;
+typedef struct { long l1; long l2; long l3; long l4; } K;
+typedef struct { long l1; long l2; long l3; long l4; long l5; long l6; } L;
+typedef struct { char x1; } Size1;
+typedef struct { char x1; char x2; } Size2;
+typedef struct { char x1; char x2; char x3; } Size3;
+typedef struct { char x1; char x2; char x3; char x4; } Size4;
+typedef struct {
+ char x1; char x2; char x3; char x4; char x5; char x6; char x7;
+} Size7;
+typedef struct {
+ char x1; char x2; char x3; char x4; char x5; char x6; char x7; char x8;
+} Size8;
+typedef struct {
+ char x1; char x2; char x3; char x4; char x5; char x6; char x7; char x8;
+ char x9; char x10; char x11; char x12;
+} Size12;
+typedef struct {
+ char x1; char x2; char x3; char x4; char x5; char x6; char x7; char x8;
+ char x9; char x10; char x11; char x12; char x13; char x14; char x15;
+} Size15;
+typedef struct {
+ char x1; char x2; char x3; char x4; char x5; char x6; char x7; char x8;
+ char x9; char x10; char x11; char x12; char x13; char x14; char x15; char x16;
+} Size16;
+typedef struct { char c[3]; } T;
+typedef struct { char c[33],c1; } X;
+
+char c1='a', c2=127, c3=(char)128, c4=(char)255, c5=-1;
+short s1=32767, s2=(short)32768, s3=3, s4=4, s5=5, s6=6, s7=7, s8=8, s9=9;
+int i1=1, i2=2, i3=3, i4=4, i5=5, i6=6, i7=7, i8=8, i9=9,
+ i10=11, i11=12, i12=13, i13=14, i14=15, i15=16, i16=17;
+long l1=1, l2=2, l3=3, l4=4, l5=5, l6=6, l7=7, l8=8, l9=9;
+long long ll1 = 3875056143130689530LL;
+float f1=0.1f, f2=0.2f, f3=0.3f, f4=0.4f, f5=0.5f, f6=0.6f, f7=0.7f, f8=0.8f, f9=0.9f,
+ f10=1.1f, f11=1.2f, f12=1.3f, f13=1.4f, f14=1.5f, f15=1.6f, f16=1.7f, f17=1.8f,
+ f18=1.9f, f19=2.1f, f20=2.2f, f21=2.3f, f22=2.4f, f23=2.5f, f24=2.6f;
+double d1=0.1, d2=0.2, d3=0.3, d4=0.4, d5=0.5, d6=0.6, d7=0.7, d8=0.8, d9=0.9,
+ d10=1.1, d11=1.2, d12=1.3, d13=1.4, d14=1.5, d15=1.6, d16=1.7, d17=1.8;
+
+uchar uc1='a', uc2=127, uc3=128, uc4=255, uc5=(uchar)-1;
+ushort us1=1, us2=2, us3=3, us4=4, us5=5, us6=6, us7=7, us8=8, us9=9;
+uint ui1=1, ui2=2, ui3=3, ui4=4, ui5=5, ui6=6, ui7=7, ui8=8, ui9=9;
+ulong ul1=1, ul2=2, ul3=3, ul4=4, ul5=5, ul6=6, ul7=7, ul8=8, ul9=9;
+
+char *str1="hello",str2[]="goodbye",*str3="still here?";
+Char C1={'A'}, C2={'B'}, C3={'C'}, C4={'\377'}, C5={(char)(-1)};
+Short S1={1}, S2={2}, S3={3}, S4={4}, S5={5}, S6={6}, S7={7}, S8={8}, S9={9};
+Int I1={1}, I2={2}, I3={3}, I4={4}, I5={5}, I6={6}, I7={7}, I8={8}, I9={9};
+Float F1={0.1f}, F2={0.2f}, F3={0.3f}, F4={0.4f}, F5={0.5f}, F6={0.6f}, F7={0.7f}, F8={0.8f}, F9={0.9f};
+Double D1={0.1}, D2={0.2}, D3={0.3}, D4={0.4}, D5={0.5}, D6={0.6}, D7={0.7}, D8={0.8}, D9={0.9};
+
+A A1={'a',0.1f},A2={'b',0.2f},A3={'\377',0.3f};
+B B1={0.1,{1,2,3}},B2={0.2,{5,4,3}};
+J J1={47,11},J2={73,55};
+K K1={19,69,12,28};
+L L1={561,1105,1729,2465,2821,6601}; /* A002997 */
+Size1 Size1_1={'a'};
+Size2 Size2_1={'a','b'};
+Size3 Size3_1={'a','b','c'};
+Size4 Size4_1={'a','b','c','d'};
+Size7 Size7_1={'a','b','c','d','e','f','g'};
+Size8 Size8_1={'a','b','c','d','e','f','g','h'};
+Size12 Size12_1={'a','b','c','d','e','f','g','h','i','j','k','l'};
+Size15 Size15_1={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o'};
+Size16 Size16_1={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'};
+T T1={{'t','h','e'}},T2={{'f','o','x'}};
+X X1={"abcdefghijklmnopqrstuvwxyzABCDEF",'G'}, X2={"123",'9'}, X3={"return-return-return",'R'};
+
+#if defined(__GNUC__)
+#define __STDCALL__ __attribute__((stdcall))
+#define __THISCALL__ __attribute__((thiscall))
+#define __FASTCALL__ __attribute__((fastcall))
+#define __MSABI__ __attribute__((ms_abi))
+#else
+#define __STDCALL__ __stdcall
+#define __THISCALL__ __thiscall
+#define __FASTCALL__ __fastcall
+#endif
+
+#ifndef ABI_ATTR
+#define ABI_ATTR
+#endif
+
+/* void tests */
+void ABI_ATTR v_v (void)
+{
+ fprintf(out,"void f(void):\n");
+ fflush(out);
+}
+
+/* int tests */
+int ABI_ATTR i_v (void)
+{
+ int r=99;
+ fprintf(out,"int f(void):");
+ fflush(out);
+ return r;
+}
+int ABI_ATTR i_i (int a)
+{
+ int r=a+1;
+ fprintf(out,"int f(int):(%d)",a);
+ fflush(out);
+ return r;
+}
+int ABI_ATTR i_i2 (int a, int b)
+{
+ int r=a+b;
+ fprintf(out,"int f(2*int):(%d,%d)",a,b);
+ fflush(out);
+ return r;
+}
+int ABI_ATTR i_i4 (int a, int b, int c, int d)
+{
+ int r=a+b+c+d;
+ fprintf(out,"int f(4*int):(%d,%d,%d,%d)",a,b,c,d);
+ fflush(out);
+ return r;
+}
+int ABI_ATTR i_i8 (int a, int b, int c, int d, int e, int f, int g, int h)
+{
+ int r=a+b+c+d+e+f+g+h;
+ fprintf(out,"int f(8*int):(%d,%d,%d,%d,%d,%d,%d,%d)",a,b,c,d,e,f,g,h);
+ fflush(out);
+ return r;
+}
+int ABI_ATTR i_i16 (int a, int b, int c, int d, int e, int f, int g, int h,
+ int i, int j, int k, int l, int m, int n, int o, int p)
+{
+ int r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
+ fprintf(out,"int f(16*int):(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
+ a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
+ fflush(out);
+ return r;
+}
+
+/* float tests */
+float ABI_ATTR f_f (float a)
+{
+ float r=a+1.0f;
+ fprintf(out,"float f(float):(%g)",a);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f2 (float a, float b)
+{
+ float r=a+b;
+ fprintf(out,"float f(2*float):(%g,%g)",a,b);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f4 (float a, float b, float c, float d)
+{
+ float r=a+b+c+d;
+ fprintf(out,"float f(4*float):(%g,%g,%g,%g)",a,b,c,d);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f8 (float a, float b, float c, float d, float e, float f,
+ float g, float h)
+{
+ float r=a+b+c+d+e+f+g+h;
+ fprintf(out,"float f(8*float):(%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f16 (float a, float b, float c, float d, float e, float f, float g, float h,
+ float i, float j, float k, float l, float m, float n, float o, float p)
+{
+ float r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
+ fprintf(out,"float f(16*float):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f24 (float a, float b, float c, float d, float e, float f, float g, float h,
+ float i, float j, float k, float l, float m, float n, float o, float p,
+ float q, float s, float t, float u, float v, float w, float x, float y)
+{
+ float r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+v+w+x+y;
+ fprintf(out,"float f(24*float):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,v,w,x,y);
+ fflush(out);
+ return r;
+}
+
+/* double tests */
+double ABI_ATTR d_d (double a)
+{
+ double r=a+1.0;
+ fprintf(out,"double f(double):(%g)",a);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d2 (double a, double b)
+{
+ double r=a+b;
+ fprintf(out,"double f(2*double):(%g,%g)",a,b);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d4 (double a, double b, double c, double d)
+{
+ double r=a+b+c+d;
+ fprintf(out,"double f(4*double):(%g,%g,%g,%g)",a,b,c,d);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d8 (double a, double b, double c, double d, double e, double f,
+ double g, double h)
+{
+ double r=a+b+c+d+e+f+g+h;
+ fprintf(out,"double f(8*double):(%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d16 (double a, double b, double c, double d, double e, double f,
+ double g, double h, double i, double j, double k, double l,
+ double m, double n, double o, double p)
+{
+ double r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
+ fprintf(out,"double f(16*double):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
+ fflush(out);
+ return r;
+}
+
+/* pointer tests */
+void* ABI_ATTR vp_vpdpcpsp (void* a, double* b, char* c, Int* d)
+{
+ void* ret = (char*)b + 1;
+ fprintf(out,"void* f(void*,double*,char*,Int*):(0x%p,0x%p,0x%p,0x%p)",a,b,c,d);
+ fflush(out);
+ return ret;
+}
+
+/* mixed number tests */
+uchar ABI_ATTR uc_ucsil (uchar a, ushort b, uint c, ulong d)
+{
+ uchar r = (uchar)-1;
+ fprintf(out,"uchar f(uchar,ushort,uint,ulong):(%u,%u,%u,%lu)",a,b,c,d);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_iidd (int a, int b, double c, double d)
+{
+ double r = a+b+c+d;
+ fprintf(out,"double f(int,int,double,double):(%d,%d,%g,%g)",a,b,c,d);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_iiidi (int a, int b, int c, double d, int e)
+{
+ double r = a+b+c+d+e;
+ fprintf(out,"double f(int,int,int,double,int):(%d,%d,%d,%g,%d)",a,b,c,d,e);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_idid (int a, double b, int c, double d)
+{
+ double r = a+b+c+d;
+ fprintf(out,"double f(int,double,int,double):(%d,%g,%d,%g)",a,b,c,d);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_fdi (float a, double b, int c)
+{
+ double r = a+b+c;
+ fprintf(out,"double f(float,double,int):(%g,%g,%d)",a,b,c);
+ fflush(out);
+ return r;
+}
+ushort ABI_ATTR us_cdcd (char a, double b, char c, double d)
+{
+ ushort r = (ushort)(a + b + c + d);
+ fprintf(out,"ushort f(char,double,char,double):('%c',%g,'%c',%g)",a,b,c,d);
+ fflush(out);
+ return r;
+}
+
+long long ABI_ATTR ll_iiilli (int a, int b, int c, long long d, int e)
+{
+ long long r = (long long)(int)a+(long long)(int)b+(long long)(int)c+d+(long long)(int)e;
+ fprintf(out,"long long f(int,int,int,long long,int):(%d,%d,%d,0x%lx%08lx,%d)",a,b,c,(long)(d>>32),(long)(d&0xffffffff),e);
+ fflush(out);
+ return r;
+}
+long long ABI_ATTR ll_flli (float a, long long b, int c)
+{
+ long long r = (long long)(int)a + b + (long long)c;
+ fprintf(out,"long long f(float,long long,int):(%g,0x%lx%08lx,0x%lx)",a,(long)(b>>32),(long)(b&0xffffffff),(long)c);
+ fflush(out);
+ return r;
+}
+
+float ABI_ATTR f_fi (float a, int z)
+{
+ float r = a+z;
+ fprintf(out,"float f(float,int):(%g,%d)",a,z);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f2i (float a, float b, int z)
+{
+ float r = a+b+z;
+ fprintf(out,"float f(2*float,int):(%g,%g,%d)",a,b,z);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f3i (float a, float b, float c, int z)
+{
+ float r = a+b+c+z;
+ fprintf(out,"float f(3*float,int):(%g,%g,%g,%d)",a,b,c,z);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f4i (float a, float b, float c, float d, int z)
+{
+ float r = a+b+c+d+z;
+ fprintf(out,"float f(4*float,int):(%g,%g,%g,%g,%d)",a,b,c,d,z);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f7i (float a, float b, float c, float d, float e, float f, float g,
+ int z)
+{
+ float r = a+b+c+d+e+f+g+z;
+ fprintf(out,"float f(7*float,int):(%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,z);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f8i (float a, float b, float c, float d, float e, float f, float g,
+ float h, int z)
+{
+ float r = a+b+c+d+e+f+g+h+z;
+ fprintf(out,"float f(8*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,z);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f12i (float a, float b, float c, float d, float e, float f, float g,
+ float h, float i, float j, float k, float l, int z)
+{
+ float r = a+b+c+d+e+f+g+h+i+j+k+l+z;
+ fprintf(out,"float f(12*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,z);
+ fflush(out);
+ return r;
+}
+float ABI_ATTR f_f13i (float a, float b, float c, float d, float e, float f, float g,
+ float h, float i, float j, float k, float l, float m, int z)
+{
+ float r = a+b+c+d+e+f+g+h+i+j+k+l+m+z;
+ fprintf(out,"float f(13*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,m,z);
+ fflush(out);
+ return r;
+}
+
+double ABI_ATTR d_di (double a, int z)
+{
+ double r = a+z;
+ fprintf(out,"double f(double,int):(%g,%d)",a,z);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d2i (double a, double b, int z)
+{
+ double r = a+b+z;
+ fprintf(out,"double f(2*double,int):(%g,%g,%d)",a,b,z);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d3i (double a, double b, double c, int z)
+{
+ double r = a+b+c+z;
+ fprintf(out,"double f(3*double,int):(%g,%g,%g,%d)",a,b,c,z);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d4i (double a, double b, double c, double d, int z)
+{
+ double r = a+b+c+d+z;
+ fprintf(out,"double f(4*double,int):(%g,%g,%g,%g,%d)",a,b,c,d,z);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d7i (double a, double b, double c, double d, double e, double f,
+ double g, int z)
+{
+ double r = a+b+c+d+e+f+g+z;
+ fprintf(out,"double f(7*double,int):(%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,z);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d8i (double a, double b, double c, double d, double e, double f,
+ double g, double h, int z)
+{
+ double r = a+b+c+d+e+f+g+h+z;
+ fprintf(out,"double f(8*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,z);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d12i (double a, double b, double c, double d, double e, double f,
+ double g, double h, double i, double j, double k, double l,
+ int z)
+{
+ double r = a+b+c+d+e+f+g+h+i+j+k+l+z;
+ fprintf(out,"double f(12*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,z);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d13i (double a, double b, double c, double d, double e, double f,
+ double g, double h, double i, double j, double k, double l,
+ double m, int z)
+{
+ double r = a+b+c+d+e+f+g+h+i+j+k+l+m+z;
+ fprintf(out,"double f(13*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,m,z);
+ fflush(out);
+ return r;
+}
+
+/* small structure return tests */
+Size1 ABI_ATTR S1_v (void)
+{
+ fprintf(out,"Size1 f(void):");
+ fflush(out);
+ return Size1_1;
+}
+Size2 ABI_ATTR S2_v (void)
+{
+ fprintf(out,"Size2 f(void):");
+ fflush(out);
+ return Size2_1;
+}
+Size3 ABI_ATTR S3_v (void)
+{
+ fprintf(out,"Size3 f(void):");
+ fflush(out);
+ return Size3_1;
+}
+Size4 ABI_ATTR S4_v (void)
+{
+ fprintf(out,"Size4 f(void):");
+ fflush(out);
+ return Size4_1;
+}
+Size7 ABI_ATTR S7_v (void)
+{
+ fprintf(out,"Size7 f(void):");
+ fflush(out);
+ return Size7_1;
+}
+Size8 ABI_ATTR S8_v (void)
+{
+ fprintf(out,"Size8 f(void):");
+ fflush(out);
+ return Size8_1;
+}
+Size12 ABI_ATTR S12_v (void)
+{
+ fprintf(out,"Size12 f(void):");
+ fflush(out);
+ return Size12_1;
+}
+Size15 ABI_ATTR S15_v (void)
+{
+ fprintf(out,"Size15 f(void):");
+ fflush(out);
+ return Size15_1;
+}
+Size16 ABI_ATTR S16_v (void)
+{
+ fprintf(out,"Size16 f(void):");
+ fflush(out);
+ return Size16_1;
+}
+
+/* structure tests */
+Int ABI_ATTR I_III (Int a, Int b, Int c)
+{
+ Int r;
+ r.x = a.x + b.x + c.x;
+ fprintf(out,"Int f(Int,Int,Int):({%d},{%d},{%d})",a.x,b.x,c.x);
+ fflush(out);
+ return r;
+}
+Char ABI_ATTR C_CdC (Char a, double b, Char c)
+{
+ Char r;
+ r.x = (a.x + c.x)/2;
+ fprintf(out,"Char f(Char,double,Char):({'%c'},%g,{'%c'})",a.x,b,c.x);
+ fflush(out);
+ return r;
+}
+Float ABI_ATTR F_Ffd (Float a, float b, double c)
+{
+ Float r;
+ r.x = (float) (a.x + b + c);
+ fprintf(out,"Float f(Float,float,double):({%g},%g,%g)",a.x,b,c);
+ fflush(out);
+ return r;
+}
+Double ABI_ATTR D_fDd (float a, Double b, double c)
+{
+ Double r;
+ r.x = a + b.x + c;
+ fprintf(out,"Double f(float,Double,double):(%g,{%g},%g)",a,b.x,c);
+ fflush(out);
+ return r;
+}
+Double ABI_ATTR D_Dfd (Double a, float b, double c)
+{
+ Double r;
+ r.x = a.x + b + c;
+ fprintf(out,"Double f(Double,float,double):({%g},%g,%g)",a.x,b,c);
+ fflush(out);
+ return r;
+}
+J ABI_ATTR J_JiJ (J a, int b, J c)
+{
+ J r;
+ r.l1 = a.l1+c.l1; r.l2 = a.l2+b+c.l2;
+ fprintf(out,"J f(J,int,J):({%ld,%ld},%d,{%ld,%ld})",a.l1,a.l2,b,c.l1,c.l2);
+ fflush(out);
+ return r;
+}
+T ABI_ATTR T_TcT (T a, char b, T c)
+{
+ T r;
+ r.c[0]='b'; r.c[1]=c.c[1]; r.c[2]=c.c[2];
+ fprintf(out,"T f(T,char,T):({\"%c%c%c\"},'%c',{\"%c%c%c\"})",a.c[0],a.c[1],a.c[2],b,c.c[0],c.c[1],c.c[2]);
+ fflush(out);
+ return r;
+}
+X ABI_ATTR X_BcdB (B a, char b, double c, B d)
+{
+ static X xr={"return val",'R'};
+ X r;
+ r = xr;
+ r.c1 = b;
+ fprintf(out,"X f(B,char,double,B):({%g,{%d,%d,%d}},'%c',%g,{%g,{%d,%d,%d}})",
+ a.d,a.i[0],a.i[1],a.i[2],b,c,d.d,d.i[0],d.i[1],d.i[2]);
+ fflush(out);
+ return r;
+}
+
+/* Test for cases where some argument (especially structure, 'long long', or
+ 'double') may be passed partially in general-purpose argument registers
+ and partially on the stack. Different ABIs pass between 4 and 8 arguments
+ (or none) in general-purpose argument registers. */
+
+long ABI_ATTR l_l0K (K b, long c)
+{
+ long r = b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(K,long):(%ld,%ld,%ld,%ld,%ld)",b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ return r;
+}
+long ABI_ATTR l_l1K (long a1, K b, long c)
+{
+ long r = a1 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld)",a1,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ return r;
+}
+long ABI_ATTR l_l2K (long a1, long a2, K b, long c)
+{
+ long r = a1 + a2 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(2*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ return r;
+}
+long ABI_ATTR l_l3K (long a1, long a2, long a3, K b, long c)
+{
+ long r = a1 + a2 + a3 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(3*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ return r;
+}
+long ABI_ATTR l_l4K (long a1, long a2, long a3, long a4, K b, long c)
+{
+ long r = a1 + a2 + a3 + a4 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(4*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ return r;
+}
+long ABI_ATTR l_l5K (long a1, long a2, long a3, long a4, long a5, K b, long c)
+{
+ long r = a1 + a2 + a3 + a4 + a5 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(5*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,a5,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ return r;
+}
+long ABI_ATTR l_l6K (long a1, long a2, long a3, long a4, long a5, long a6, K b, long c)
+{
+ long r = a1 + a2 + a3 + a4 + a5 + a6 + b.l1 + b.l2 + b.l3 + b.l4 + c;
+ fprintf(out,"long f(6*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,a5,a6,b.l1,b.l2,b.l3,b.l4,c);
+ fflush(out);
+ return r;
+}
+/* These tests is crafted on the knowledge that for all known ABIs:
+ * 17 > number of floating-point argument registers,
+ * 3 < number of general-purpose argument registers < 3 + 6. */
+float ABI_ATTR f_f17l3L (float a, float b, float c, float d, float e, float f, float g,
+ float h, float i, float j, float k, float l, float m, float n,
+ float o, float p, float q,
+ long s, long t, long u, L z)
+{
+ float r = a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+z.l1+z.l2+z.l3+z.l4+z.l5+z.l6;
+ fprintf(out,"float f(17*float,3*int,L):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,z.l1,z.l2,z.l3,z.l4,z.l5,z.l6);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_d17l3L (double a, double b, double c, double d, double e, double f,
+ double g, double h, double i, double j, double k, double l,
+ double m, double n, double o, double p, double q,
+ long s, long t, long u, L z)
+{
+ double r = a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+z.l1+z.l2+z.l3+z.l4+z.l5+z.l6;
+ fprintf(out,"double f(17*double,3*int,L):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,z.l1,z.l2,z.l3,z.l4,z.l5,z.l6);
+ fflush(out);
+ return r;
+}
+
+long long ABI_ATTR ll_l2ll (long a1, long a2, long long b, long c)
+{
+ long long r = (long long) (a1 + a2) + b + c;
+ fprintf(out,"long long f(2*long,long long,long):(%ld,%ld,0x%lx%08lx,%ld)",a1,a2,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ return r;
+}
+long long ABI_ATTR ll_l3ll (long a1, long a2, long a3, long long b, long c)
+{
+ long long r = (long long) (a1 + a2 + a3) + b + c;
+ fprintf(out,"long long f(3*long,long long,long):(%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ return r;
+}
+long long ABI_ATTR ll_l4ll (long a1, long a2, long a3, long a4, long long b, long c)
+{
+ long long r = (long long) (a1 + a2 + a3 + a4) + b + c;
+ fprintf(out,"long long f(4*long,long long,long):(%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ return r;
+}
+long long ABI_ATTR ll_l5ll (long a1, long a2, long a3, long a4, long a5, long long b, long c)
+{
+ long long r = (long long) (a1 + a2 + a3 + a4 + a5) + b + c;
+ fprintf(out,"long long f(5*long,long long,long):(%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ return r;
+}
+long long ABI_ATTR ll_l6ll (long a1, long a2, long a3, long a4, long a5, long a6, long long b, long c)
+{
+ long long r = (long long) (a1 + a2 + a3 + a4 + a5 + a6) + b + c;
+ fprintf(out,"long long f(6*long,long long,long):(%ld,%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,a6,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ return r;
+}
+long long ABI_ATTR ll_l7ll (long a1, long a2, long a3, long a4, long a5, long a6, long a7, long long b, long c)
+{
+ long long r = (long long) (a1 + a2 + a3 + a4 + a5 + a6 + a7) + b + c;
+ fprintf(out,"long long f(7*long,long long,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,a6,a7,(long)(b>>32),(long)(b&0xffffffff),c);
+ fflush(out);
+ return r;
+}
+
+double ABI_ATTR d_l2d (long a1, long a2, double b, long c)
+{
+ double r = (double) (a1 + a2) + b + c;
+ fprintf(out,"double f(2*long,double,long):(%ld,%ld,%g,%ld)",a1,a2,b,c);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_l3d (long a1, long a2, long a3, double b, long c)
+{
+ double r = (double) (a1 + a2 + a3) + b + c;
+ fprintf(out,"double f(3*long,double,long):(%ld,%ld,%ld,%g,%ld)",a1,a2,a3,b,c);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_l4d (long a1, long a2, long a3, long a4, double b, long c)
+{
+ double r = (double) (a1 + a2 + a3 + a4) + b + c;
+ fprintf(out,"double f(4*long,double,long):(%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,b,c);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_l5d (long a1, long a2, long a3, long a4, long a5, double b, long c)
+{
+ double r = (double) (a1 + a2 + a3 + a4 + a5) + b + c;
+ fprintf(out,"double f(5*long,double,long):(%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,b,c);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_l6d (long a1, long a2, long a3, long a4, long a5, long a6, double b, long c)
+{
+ double r = (double) (a1 + a2 + a3 + a4 + a5 + a6) + b + c;
+ fprintf(out,"double f(6*long,double,long):(%ld,%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,a6,b,c);
+ fflush(out);
+ return r;
+}
+double ABI_ATTR d_l7d (long a1, long a2, long a3, long a4, long a5, long a6, long a7, double b, long c)
+{
+ double r = (double) (a1 + a2 + a3 + a4 + a5 + a6 + a7) + b + c;
+ fprintf(out,"double f(7*long,double,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,a6,a7,b,c);
+ fflush(out);
+ return r;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/align_mixed.c b/js/src/ctypes/libffi/testsuite/libffi.call/align_mixed.c
new file mode 100644
index 0000000000..5d4959ce97
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/align_mixed.c
@@ -0,0 +1,46 @@
+/* Area: ffi_call
+ Purpose: Check for proper argument alignment.
+ Limitations: none.
+ PR: none.
+ Originator: <twalljava@java.net> (from many_win32.c) */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static float ABI_ATTR align_arguments(int i1,
+ double f2,
+ int i3,
+ double f4)
+{
+ return i1+f2+i3+f4;
+}
+
+int main(void)
+{
+ ffi_cif cif;
+ ffi_type *args[4] = {
+ &ffi_type_sint,
+ &ffi_type_double,
+ &ffi_type_sint,
+ &ffi_type_double
+ };
+ double fa[2] = {1,2};
+ int ia[2] = {1,2};
+ void *values[4] = {&ia[0], &fa[0], &ia[1], &fa[1]};
+ float f, ff;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 4,
+ &ffi_type_float, args) == FFI_OK);
+
+ ff = align_arguments(ia[0], fa[0], ia[1], fa[1]);
+
+ ffi_call(&cif, FFI_FN(align_arguments), &f, values);
+
+ if (f == ff)
+ printf("align arguments tests ok!\n");
+ else
+ CHECK(0);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/align_stdcall.c b/js/src/ctypes/libffi/testsuite/libffi.call/align_stdcall.c
new file mode 100644
index 0000000000..5e5cb860cc
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/align_stdcall.c
@@ -0,0 +1,46 @@
+/* Area: ffi_call
+ Purpose: Check for proper argument alignment.
+ Limitations: none.
+ PR: none.
+ Originator: <twalljava@java.net> (from many_win32.c) */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static float ABI_ATTR align_arguments(int i1,
+ double f2,
+ int i3,
+ double f4)
+{
+ return i1+f2+i3+f4;
+}
+
+int main(void)
+{
+ ffi_cif cif;
+ ffi_type *args[4] = {
+ &ffi_type_sint,
+ &ffi_type_double,
+ &ffi_type_sint,
+ &ffi_type_double
+ };
+ double fa[2] = {1,2};
+ int ia[2] = {1,2};
+ void *values[4] = {&ia[0], &fa[0], &ia[1], &fa[1]};
+ float f, ff;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 4,
+ &ffi_type_float, args) == FFI_OK);
+
+ ff = align_arguments(ia[0], fa[0], ia[1], fa[1]);;
+
+ ffi_call(&cif, FFI_FN(align_arguments), &f, values);
+
+ if (f == ff)
+ printf("align arguments tests ok!\n");
+ else
+ CHECK(0);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/call.exp b/js/src/ctypes/libffi/testsuite/libffi.call/call.exp
new file mode 100644
index 0000000000..256f237c4c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/call.exp
@@ -0,0 +1,54 @@
+# Copyright (C) 2003, 2006, 2009, 2010, 2014, 2019 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+dg-init
+libffi-init
+
+global srcdir subdir
+
+if { [string match $compiler_vendor "microsoft"] } {
+ # -wd4005 macro redefinition
+ # -wd4244 implicit conversion to type of smaller size
+ # -wd4305 truncation to smaller type
+ # -wd4477 printf %lu of uintptr_t
+ # -wd4312 implicit conversion to type of greater size
+ # -wd4311 pointer truncation to unsigned long
+ # -EHsc C++ Exception Handling (no SEH exceptions)
+ set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc";
+} else {
+ set additional_options "";
+}
+
+set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]]
+
+run-many-tests $tlist $additional_options
+
+set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]]
+
+# No C++ for or1k
+if { [istarget "or1k-*-*"] } {
+ foreach test $tlist {
+ unsupported "$test"
+ }
+} else {
+ run-many-tests $tlist $additional_options
+}
+
+dg-finish
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/err_bad_typedef.c b/js/src/ctypes/libffi/testsuite/libffi.call/err_bad_typedef.c
new file mode 100644
index 0000000000..bf60161861
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/err_bad_typedef.c
@@ -0,0 +1,26 @@
+/* Area: ffi_prep_cif
+ Purpose: Test error return for bad typedefs.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type* arg_types[1];
+
+ ffi_type badType = ffi_type_void;
+
+ arg_types[0] = NULL;
+
+ badType.size = 0;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType,
+ arg_types) == FFI_BAD_TYPEDEF);
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/ffitest.h b/js/src/ctypes/libffi/testsuite/libffi.call/ffitest.h
new file mode 100644
index 0000000000..cfce1ad589
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/ffitest.h
@@ -0,0 +1,138 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <ffi.h>
+#include "fficonfig.h"
+
+#if defined HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#if defined HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#define MAX_ARGS 256
+
+#define CHECK(x) (void)(!(x) ? (abort(), 1) : 0)
+
+/* Define macros so that compilers other than gcc can run the tests. */
+#undef __UNUSED__
+#if defined(__GNUC__)
+#define __UNUSED__ __attribute__((__unused__))
+#define __STDCALL__ __attribute__((stdcall))
+#define __THISCALL__ __attribute__((thiscall))
+#define __FASTCALL__ __attribute__((fastcall))
+#define __MSABI__ __attribute__((ms_abi))
+#else
+#define __UNUSED__
+#define __STDCALL__ __stdcall
+#define __THISCALL__ __thiscall
+#define __FASTCALL__ __fastcall
+#endif
+
+#ifndef ABI_NUM
+#define ABI_NUM FFI_DEFAULT_ABI
+#define ABI_ATTR
+#endif
+
+/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
+ file open. */
+#ifdef HAVE_MMAP_ANON
+# undef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED -1
+# endif
+# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+# endif
+# define USING_MMAP
+
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED -1
+# endif
+# define USING_MMAP
+
+#endif
+
+/* MinGW kludge. */
+#if defined(_WIN64) | defined(_WIN32)
+#define PRIdLL "I64d"
+#define PRIuLL "I64u"
+#else
+#define PRIdLL "lld"
+#define PRIuLL "llu"
+#endif
+
+/* Tru64 UNIX kludge. */
+#if defined(__alpha__) && defined(__osf__)
+/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit. */
+#undef PRIdLL
+#define PRIdLL "ld"
+#undef PRIuLL
+#define PRIuLL "lu"
+#define PRId8 "hd"
+#define PRIu8 "hu"
+#define PRId64 "ld"
+#define PRIu64 "lu"
+#define PRIuPTR "lu"
+#endif
+
+/* PA HP-UX kludge. */
+#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR)
+#define PRIuPTR "lu"
+#endif
+
+/* IRIX kludge. */
+#if defined(__sgi)
+/* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99
+ compilations. */
+#define PRId8 "hhd"
+#define PRIu8 "hhu"
+#if (_MIPS_SZLONG == 32)
+#define PRId64 "lld"
+#define PRIu64 "llu"
+#endif
+/* This doesn't match <inttypes.h>, which always has "lld" here, but the
+ arguments are uint64_t, int64_t, which are unsigned long, long for
+ 64-bit in <sgidefs.h>. */
+#if (_MIPS_SZLONG == 64)
+#define PRId64 "ld"
+#define PRIu64 "lu"
+#endif
+/* This doesn't match <inttypes.h>, which has "u" here, but the arguments
+ are uintptr_t, which is always unsigned long. */
+#define PRIuPTR "lu"
+#endif
+
+/* Solaris < 10 kludge. */
+#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR)
+#if defined(__arch64__) || defined (__x86_64__)
+#define PRIuPTR "lu"
+#else
+#define PRIuPTR "u"
+#endif
+#endif
+
+/* MSVC kludge. */
+#if defined _MSC_VER
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
+#define PRIuPTR "lu"
+#define PRIu8 "u"
+#define PRId8 "d"
+#define PRIu64 "I64u"
+#define PRId64 "I64d"
+#endif
+#endif
+
+#ifndef PRIuPTR
+#define PRIuPTR "u"
+#endif
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/float.c b/js/src/ctypes/libffi/testsuite/libffi.call/float.c
new file mode 100644
index 0000000000..fbc272d84f
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/float.c
@@ -0,0 +1,59 @@
+/* Area: ffi_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static int floating(int a, float b, double c, long double d)
+{
+ int i;
+
+ i = (int) ((float)a/b + ((float)c/(float)d));
+
+ return i;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+
+ float f;
+ signed int si1;
+ double d;
+ long double ld;
+
+ args[0] = &ffi_type_sint;
+ values[0] = &si1;
+ args[1] = &ffi_type_float;
+ values[1] = &f;
+ args[2] = &ffi_type_double;
+ values[2] = &d;
+ args[3] = &ffi_type_longdouble;
+ values[3] = &ld;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_sint, args) == FFI_OK);
+
+ si1 = 6;
+ f = 3.14159;
+ d = (double)1.0/(double)3.0;
+ ld = 2.71828182846L;
+
+ floating (si1, f, d, ld);
+
+ ffi_call(&cif, FFI_FN(floating), &rint, values);
+
+ printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld));
+
+ CHECK((int)rint == floating(si1, f, d, ld));
+
+ exit (0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/float1.c b/js/src/ctypes/libffi/testsuite/libffi.call/float1.c
new file mode 100644
index 0000000000..c48493c6b2
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/float1.c
@@ -0,0 +1,60 @@
+/* Area: ffi_call
+ Purpose: Check return value double.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+#include "float.h"
+
+#include <math.h>
+
+typedef union
+{
+ double d;
+ unsigned char c[sizeof (double)];
+} value_type;
+
+#define CANARY 0xba
+
+static double dblit(float f)
+{
+ return f/3.0;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float f;
+ value_type result[2];
+ unsigned int i;
+
+ args[0] = &ffi_type_float;
+ values[0] = &f;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_double, args) == FFI_OK);
+
+ f = 3.14159;
+
+ /* Put a canary in the return array. This is a regression test for
+ a buffer overrun. */
+ memset(result[1].c, CANARY, sizeof (double));
+
+ ffi_call(&cif, FFI_FN(dblit), &result[0].d, values);
+
+ /* These are not always the same!! Check for a reasonable delta */
+
+ CHECK(fabs(result[0].d - dblit(f)) < DBL_EPSILON);
+
+ /* Check the canary. */
+ for (i = 0; i < sizeof (double); ++i)
+ CHECK(result[1].c[i] == CANARY);
+
+ exit(0);
+
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/float2.c b/js/src/ctypes/libffi/testsuite/libffi.call/float2.c
new file mode 100644
index 0000000000..57cd9e30f9
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/float2.c
@@ -0,0 +1,61 @@
+/* Area: ffi_call
+ Purpose: Check return value long double.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+/* { dg-do run } */
+
+#include "ffitest.h"
+#include "float.h"
+
+#include <math.h>
+
+static long double ldblit(float f)
+{
+ return (long double) (((long double) f)/ (long double) 3.0);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float f;
+ long double ld;
+ long double original;
+
+ args[0] = &ffi_type_float;
+ values[0] = &f;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_longdouble, args) == FFI_OK);
+
+ f = 3.14159;
+
+#if defined(__sun) && defined(__GNUC__)
+ /* long double support under SunOS/gcc is pretty much non-existent.
+ You'll get the odd bus error in library routines like printf() */
+#else
+ printf ("%Lf\n", ldblit(f));
+#endif
+
+ ld = 666;
+ ffi_call(&cif, FFI_FN(ldblit), &ld, values);
+
+#if defined(__sun) && defined(__GNUC__)
+ /* long double support under SunOS/gcc is pretty much non-existent.
+ You'll get the odd bus error in library routines like printf() */
+#else
+ printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
+#endif
+
+ /* These are not always the same!! Check for a reasonable delta */
+ original = ldblit(f);
+ if (((ld > original) ? (ld - original) : (original - ld)) < LDBL_EPSILON)
+ puts("long double return value tests ok!");
+ else
+ CHECK(0);
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/float3.c b/js/src/ctypes/libffi/testsuite/libffi.call/float3.c
new file mode 100644
index 0000000000..bab3206a17
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/float3.c
@@ -0,0 +1,74 @@
+/* Area: ffi_call
+ Purpose: Check float arguments with different orders.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+#include "float.h"
+
+#include <math.h>
+
+static double floating_1(float a, double b, long double c)
+{
+ return (double) a + b + (double) c;
+}
+
+static double floating_2(long double a, double b, float c)
+{
+ return (double) a + b + (double) c;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ double rd;
+
+ float f;
+ double d;
+ long double ld;
+
+ args[0] = &ffi_type_float;
+ values[0] = &f;
+ args[1] = &ffi_type_double;
+ values[1] = &d;
+ args[2] = &ffi_type_longdouble;
+ values[2] = &ld;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_double, args) == FFI_OK);
+
+ f = 3.14159;
+ d = (double)1.0/(double)3.0;
+ ld = 2.71828182846L;
+
+ floating_1 (f, d, ld);
+
+ ffi_call(&cif, FFI_FN(floating_1), &rd, values);
+
+ CHECK(fabs(rd - floating_1(f, d, ld)) < DBL_EPSILON);
+
+ args[0] = &ffi_type_longdouble;
+ values[0] = &ld;
+ args[1] = &ffi_type_double;
+ values[1] = &d;
+ args[2] = &ffi_type_float;
+ values[2] = &f;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_double, args) == FFI_OK);
+
+ floating_2 (ld, d, f);
+
+ ffi_call(&cif, FFI_FN(floating_2), &rd, values);
+
+ CHECK(fabs(rd - floating_2(ld, d, f)) < DBL_EPSILON);
+
+ exit (0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/float4.c b/js/src/ctypes/libffi/testsuite/libffi.call/float4.c
new file mode 100644
index 0000000000..0dd6d85e7a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/float4.c
@@ -0,0 +1,62 @@
+/* Area: ffi_call
+ Purpose: Check denorm double value.
+ Limitations: none.
+ PR: PR26483.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+/* { dg-options "-mieee" { target alpha*-*-* } } */
+
+#include "ffitest.h"
+#include "float.h"
+
+typedef union
+{
+ double d;
+ unsigned char c[sizeof (double)];
+} value_type;
+
+#define CANARY 0xba
+
+static double dblit(double d)
+{
+ return d;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ double d;
+ value_type result[2];
+ unsigned int i;
+
+ args[0] = &ffi_type_double;
+ values[0] = &d;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_double, args) == FFI_OK);
+
+ d = DBL_MIN / 2;
+
+ /* Put a canary in the return array. This is a regression test for
+ a buffer overrun. */
+ memset(result[1].c, CANARY, sizeof (double));
+
+ ffi_call(&cif, FFI_FN(dblit), &result[0].d, values);
+
+ /* The standard delta check doesn't work for denorms. Since we didn't do
+ any arithmetic, we should get the original result back, and hence an
+ exact check should be OK here. */
+
+ CHECK(result[0].d == dblit(d));
+
+ /* Check the canary. */
+ for (i = 0; i < sizeof (double); ++i)
+ CHECK(result[1].c[i] == CANARY);
+
+ exit(0);
+
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/float_va.c b/js/src/ctypes/libffi/testsuite/libffi.call/float_va.c
new file mode 100644
index 0000000000..5acff91f66
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/float_va.c
@@ -0,0 +1,107 @@
+/* Area: fp and variadics
+ Purpose: check fp inputs and returns work on variadics, even the fixed params
+ Limitations: None
+ PR: none
+ Originator: <david.gilbert@linaro.org> 2011-01-25
+
+ Intended to stress the difference in ABI on ARM vfp
+*/
+
+/* { dg-do run } */
+
+#include <stdarg.h>
+
+#include "ffitest.h"
+
+/* prints out all the parameters, and returns the sum of them all.
+ * 'x' is the number of variadic parameters all of which are double in this test
+ */
+double float_va_fn(unsigned int x, double y,...)
+{
+ double total=0.0;
+ va_list ap;
+ unsigned int i;
+
+ total+=(double)x;
+ total+=y;
+
+ printf("%u: %.1f :", x, y);
+
+ va_start(ap, y);
+ for(i=0;i<x;i++)
+ {
+ double arg=va_arg(ap, double);
+ total+=arg;
+ printf(" %d:%.1f ", i, arg);
+ }
+ va_end(ap);
+
+ printf(" total: %.1f\n", total);
+
+ return total;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+
+ ffi_type *arg_types[5];
+ void *values[5];
+ double doubles[5];
+ unsigned int firstarg;
+ double resfp;
+
+ /* First test, pass float_va_fn(0,2.0) - note there are no actual
+ * variadic parameters, but it's declared variadic so the ABI may be
+ * different. */
+ /* Call it statically and then via ffi */
+ resfp=float_va_fn(0,2.0);
+ /* { dg-output "0: 2.0 : total: 2.0" } */
+ printf("compiled: %.1f\n", resfp);
+ /* { dg-output "\ncompiled: 2.0" } */
+
+ arg_types[0] = &ffi_type_uint;
+ arg_types[1] = &ffi_type_double;
+ arg_types[2] = NULL;
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 2, 2,
+ &ffi_type_double, arg_types) == FFI_OK);
+
+ firstarg = 0;
+ doubles[0] = 2.0;
+ values[0] = &firstarg;
+ values[1] = &doubles[0];
+ ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
+ /* { dg-output "\n0: 2.0 : total: 2.0" } */
+ printf("ffi: %.1f\n", resfp);
+ /* { dg-output "\nffi: 2.0" } */
+
+ /* Second test, float_va_fn(2,2.0,3.0,4.0), now with variadic params */
+ /* Call it statically and then via ffi */
+ resfp=float_va_fn(2,2.0,3.0,4.0);
+ /* { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } */
+ printf("compiled: %.1f\n", resfp);
+ /* { dg-output "\ncompiled: 11.0" } */
+
+ arg_types[0] = &ffi_type_uint;
+ arg_types[1] = &ffi_type_double;
+ arg_types[2] = &ffi_type_double;
+ arg_types[3] = &ffi_type_double;
+ arg_types[4] = NULL;
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 2, 4,
+ &ffi_type_double, arg_types) == FFI_OK);
+
+ firstarg = 2;
+ doubles[0] = 2.0;
+ doubles[1] = 3.0;
+ doubles[2] = 4.0;
+ values[0] = &firstarg;
+ values[1] = &doubles[0];
+ values[2] = &doubles[1];
+ values[3] = &doubles[2];
+ ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
+ /* { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } */
+ printf("ffi: %.1f\n", resfp);
+ /* { dg-output "\nffi: 11.0" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/many.c b/js/src/ctypes/libffi/testsuite/libffi.call/many.c
new file mode 100644
index 0000000000..336968c77a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/many.c
@@ -0,0 +1,59 @@
+/* Area: ffi_call
+ Purpose: Check return value float, with many arguments
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+#include <stdlib.h>
+#include <float.h>
+#include <math.h>
+
+static float ABI_ATTR many(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13)
+{
+#if 0
+ printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
+ (double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
+ (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
+ (double) f11, (double) f12, (double) f13);
+#endif
+
+ return f1+f2+f3+f4+f5+f6+f7+f8+f9+f10+f11+f12+f13;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[13];
+ void *values[13];
+ float fa[13];
+ float f, ff;
+ int i;
+
+ for (i = 0; i < 13; i++)
+ {
+ args[i] = &ffi_type_float;
+ values[i] = &fa[i];
+ fa[i] = (float) i;
+ }
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 13,
+ &ffi_type_float, args) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(many), &f, values);
+
+ ff = many(fa[0], fa[1],
+ fa[2], fa[3],
+ fa[4], fa[5],
+ fa[6], fa[7],
+ fa[8], fa[9],
+ fa[10],fa[11],fa[12]);
+
+ if (fabs(f - ff) < FLT_EPSILON)
+ exit(0);
+ else
+ abort();
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/many2.c b/js/src/ctypes/libffi/testsuite/libffi.call/many2.c
new file mode 100644
index 0000000000..1c85746e4c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/many2.c
@@ -0,0 +1,57 @@
+/* Area: ffi_call
+ Purpose: Check uint8_t arguments.
+ Limitations: none.
+ PR: PR45677.
+ Originator: Dan Witte <dwitte@gmail.com> 20100916 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+#define NARGS 7
+
+typedef unsigned char u8;
+
+#ifdef __GNUC__
+__attribute__((noinline))
+#endif
+uint8_t
+foo (uint8_t a, uint8_t b, uint8_t c, uint8_t d,
+ uint8_t e, uint8_t f, uint8_t g)
+{
+ return a + b + c + d + e + f + g;
+}
+
+uint8_t ABI_ATTR
+bar (uint8_t a, uint8_t b, uint8_t c, uint8_t d,
+ uint8_t e, uint8_t f, uint8_t g)
+{
+ return foo (a, b, c, d, e, f, g);
+}
+
+int
+main (void)
+{
+ ffi_type *ffitypes[NARGS];
+ int i;
+ ffi_cif cif;
+ ffi_arg result = 0;
+ uint8_t args[NARGS];
+ void *argptrs[NARGS];
+
+ for (i = 0; i < NARGS; ++i)
+ ffitypes[i] = &ffi_type_uint8;
+
+ CHECK (ffi_prep_cif (&cif, ABI_NUM, NARGS,
+ &ffi_type_uint8, ffitypes) == FFI_OK);
+
+ for (i = 0; i < NARGS; ++i)
+ {
+ args[i] = i;
+ argptrs[i] = &args[i];
+ }
+ ffi_call (&cif, FFI_FN (bar), &result, argptrs);
+
+ CHECK (result == 21);
+ return 0;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/many_double.c b/js/src/ctypes/libffi/testsuite/libffi.call/many_double.c
new file mode 100644
index 0000000000..4ef8c8ab28
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/many_double.c
@@ -0,0 +1,70 @@
+/* Area: ffi_call
+ Purpose: Check return value double, with many arguments
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+#include <stdlib.h>
+#include <float.h>
+#include <math.h>
+
+static double many(double f1,
+ double f2,
+ double f3,
+ double f4,
+ double f5,
+ double f6,
+ double f7,
+ double f8,
+ double f9,
+ double f10,
+ double f11,
+ double f12,
+ double f13)
+{
+#if 0
+ printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
+ (double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
+ (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
+ (double) f11, (double) f12, (double) f13);
+#endif
+
+ return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[13];
+ void *values[13];
+ double fa[13];
+ double f, ff;
+ int i;
+
+ for (i = 0; i < 13; i++)
+ {
+ args[i] = &ffi_type_double;
+ values[i] = &fa[i];
+ fa[i] = (double) i;
+ }
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
+ &ffi_type_double, args) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(many), &f, values);
+
+ ff = many(fa[0], fa[1],
+ fa[2], fa[3],
+ fa[4], fa[5],
+ fa[6], fa[7],
+ fa[8], fa[9],
+ fa[10],fa[11],fa[12]);
+ if (fabs(f - ff) < FLT_EPSILON)
+ exit(0);
+ else
+ abort();
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/many_mixed.c b/js/src/ctypes/libffi/testsuite/libffi.call/many_mixed.c
new file mode 100644
index 0000000000..85ec36ecbe
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/many_mixed.c
@@ -0,0 +1,78 @@
+/* Area: ffi_call
+ Purpose: Check return value double, with many arguments
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+#include <stdlib.h>
+#include <float.h>
+#include <math.h>
+
+static double many(double f1,
+ double f2,
+ long int i1,
+ double f3,
+ double f4,
+ long int i2,
+ double f5,
+ double f6,
+ long int i3,
+ double f7,
+ double f8,
+ long int i4,
+ double f9,
+ double f10,
+ long int i5,
+ double f11,
+ double f12,
+ long int i6,
+ double f13)
+{
+ return ((double) (i1 + i2 + i3 + i4 + i5 + i6) + (f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[19];
+ void *values[19];
+ double fa[19];
+ long int la[19];
+ double f, ff;
+ int i;
+
+ for (i = 0; i < 19; i++)
+ {
+ if( (i - 2) % 3 == 0) {
+ args[i] = &ffi_type_slong;
+ la[i] = (long int) i;
+ values[i] = &la[i];
+ }
+ else {
+ args[i] = &ffi_type_double;
+ fa[i] = (double) i;
+ values[i] = &fa[i];
+ }
+ }
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 19,
+ &ffi_type_double, args) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(many), &f, values);
+
+ ff = many(fa[0], fa[1], la[2],
+ fa[3], fa[4], la[5],
+ fa[6], fa[7], la[8],
+ fa[9], fa[10], la[11],
+ fa[12], fa[13], la[14],
+ fa[15], fa[16], la[17],
+ fa[18]);
+ if (fabs(f - ff) < FLT_EPSILON)
+ exit(0);
+ else
+ abort();
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/negint.c b/js/src/ctypes/libffi/testsuite/libffi.call/negint.c
new file mode 100644
index 0000000000..6e2f26fc10
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/negint.c
@@ -0,0 +1,52 @@
+/* Area: ffi_call
+ Purpose: Check that negative integers are passed correctly.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static int checking(int a, short b, signed char c)
+{
+
+ return (a < 0 && b < 0 && c < 0);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+
+ signed int si;
+ signed short ss;
+ signed char sc;
+
+ args[0] = &ffi_type_sint;
+ values[0] = &si;
+ args[1] = &ffi_type_sshort;
+ values[1] = &ss;
+ args[2] = &ffi_type_schar;
+ values[2] = &sc;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_sint, args) == FFI_OK);
+
+ si = -6;
+ ss = -12;
+ sc = -1;
+
+ checking (si, ss, sc);
+
+ ffi_call(&cif, FFI_FN(checking), &rint, values);
+
+ printf ("%d vs %d\n", (int)rint, checking (si, ss, sc));
+
+ CHECK(rint != 0);
+
+ exit (0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/offsets.c b/js/src/ctypes/libffi/testsuite/libffi.call/offsets.c
new file mode 100644
index 0000000000..23d88b35d5
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/offsets.c
@@ -0,0 +1,46 @@
+/* Area: Struct layout
+ Purpose: Test ffi_get_struct_offsets
+ Limitations: none.
+ PR: none.
+ Originator: Tom Tromey. */
+
+/* { dg-do run } */
+#include "ffitest.h"
+#include <stddef.h>
+
+struct test_1
+{
+ char c;
+ float f;
+ char c2;
+ int i;
+};
+
+int
+main (void)
+{
+ ffi_type test_1_type;
+ ffi_type *test_1_elements[5];
+ size_t test_1_offsets[4];
+
+ test_1_elements[0] = &ffi_type_schar;
+ test_1_elements[1] = &ffi_type_float;
+ test_1_elements[2] = &ffi_type_schar;
+ test_1_elements[3] = &ffi_type_sint;
+ test_1_elements[4] = NULL;
+
+ test_1_type.size = 0;
+ test_1_type.alignment = 0;
+ test_1_type.type = FFI_TYPE_STRUCT;
+ test_1_type.elements = test_1_elements;
+
+ CHECK (ffi_get_struct_offsets (FFI_DEFAULT_ABI, &test_1_type, test_1_offsets)
+ == FFI_OK);
+ CHECK (test_1_type.size == sizeof (struct test_1));
+ CHECK (offsetof (struct test_1, c) == test_1_offsets[0]);
+ CHECK (offsetof (struct test_1, f) == test_1_offsets[1]);
+ CHECK (offsetof (struct test_1, c2) == test_1_offsets[2]);
+ CHECK (offsetof (struct test_1, i) == test_1_offsets[3]);
+
+ return 0;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/pr1172638.c b/js/src/ctypes/libffi/testsuite/libffi.call/pr1172638.c
new file mode 100644
index 0000000000..7da1621cd6
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/pr1172638.c
@@ -0,0 +1,127 @@
+/* Area: ffi_call
+ Purpose: Reproduce bug found in python ctypes
+ Limitations: none.
+ PR: Fedora 1174037 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct {
+ long x;
+ long y;
+} POINT;
+
+typedef struct {
+ long left;
+ long top;
+ long right;
+ long bottom;
+} RECT;
+
+static RECT ABI_ATTR pr_test(int i __UNUSED__, RECT ar __UNUSED__,
+ RECT* br __UNUSED__, POINT cp __UNUSED__,
+ RECT dr __UNUSED__, RECT *er __UNUSED__,
+ POINT fp, RECT gr __UNUSED__)
+{
+ RECT result;
+
+ result.left = fp.x;
+ result.right = fp.y;
+ result.top = fp.x;
+ result.bottom = fp.y;
+
+ return result;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type point_type, rect_type;
+ ffi_type *point_type_elements[3];
+ ffi_type *rect_type_elements[5];
+
+ int i;
+ POINT cp, fp;
+ RECT ar, br, dr, er, gr;
+ RECT *p1, *p2;
+
+ /* This is a hack to get a properly aligned result buffer */
+ RECT *rect_result =
+ (RECT *) malloc (sizeof(RECT));
+
+ point_type.size = 0;
+ point_type.alignment = 0;
+ point_type.type = FFI_TYPE_STRUCT;
+ point_type.elements = point_type_elements;
+ point_type_elements[0] = &ffi_type_slong;
+ point_type_elements[1] = &ffi_type_slong;
+ point_type_elements[2] = NULL;
+
+ rect_type.size = 0;
+ rect_type.alignment = 0;
+ rect_type.type = FFI_TYPE_STRUCT;
+ rect_type.elements = rect_type_elements;
+ rect_type_elements[0] = &ffi_type_slong;
+ rect_type_elements[1] = &ffi_type_slong;
+ rect_type_elements[2] = &ffi_type_slong;
+ rect_type_elements[3] = &ffi_type_slong;
+ rect_type_elements[4] = NULL;
+
+ args[0] = &ffi_type_sint;
+ args[1] = &rect_type;
+ args[2] = &ffi_type_pointer;
+ args[3] = &point_type;
+ args[4] = &rect_type;
+ args[5] = &ffi_type_pointer;
+ args[6] = &point_type;
+ args[7] = &rect_type;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 8, &rect_type, args) == FFI_OK);
+
+ i = 1;
+ ar.left = 2;
+ ar.right = 3;
+ ar.top = 4;
+ ar.bottom = 5;
+ br.left = 6;
+ br.right = 7;
+ br.top = 8;
+ br.bottom = 9;
+ cp.x = 10;
+ cp.y = 11;
+ dr.left = 12;
+ dr.right = 13;
+ dr.top = 14;
+ dr.bottom = 15;
+ er.left = 16;
+ er.right = 17;
+ er.top = 18;
+ er.bottom = 19;
+ fp.x = 20;
+ fp.y = 21;
+ gr.left = 22;
+ gr.right = 23;
+ gr.top = 24;
+ gr.bottom = 25;
+
+ values[0] = &i;
+ values[1] = &ar;
+ p1 = &br;
+ values[2] = &p1;
+ values[3] = &cp;
+ values[4] = &dr;
+ p2 = &er;
+ values[5] = &p2;
+ values[6] = &fp;
+ values[7] = &gr;
+
+ ffi_call (&cif, FFI_FN(pr_test), rect_result, values);
+
+ CHECK(rect_result->top == 20);
+
+ free (rect_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/promotion.c b/js/src/ctypes/libffi/testsuite/libffi.call/promotion.c
new file mode 100644
index 0000000000..44561615dd
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/promotion.c
@@ -0,0 +1,59 @@
+/* Area: ffi_call
+ Purpose: Promotion test.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static int promotion(signed char sc, signed short ss,
+ unsigned char uc, unsigned short us)
+{
+ int r = (int) sc + (int) ss + (int) uc + (int) us;
+
+ return r;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+ signed char sc;
+ unsigned char uc;
+ signed short ss;
+ unsigned short us;
+ unsigned long ul;
+
+ args[0] = &ffi_type_schar;
+ args[1] = &ffi_type_sshort;
+ args[2] = &ffi_type_uchar;
+ args[3] = &ffi_type_ushort;
+ values[0] = &sc;
+ values[1] = &ss;
+ values[2] = &uc;
+ values[3] = &us;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_sint, args) == FFI_OK);
+
+ us = 0;
+ ul = 0;
+
+ for (sc = (signed char) -127;
+ sc <= (signed char) 120; sc += 1)
+ for (ss = -30000; ss <= 30000; ss += 10000)
+ for (uc = (unsigned char) 0;
+ uc <= (unsigned char) 200; uc += 20)
+ for (us = 0; us <= 60000; us += 10000)
+ {
+ ul++;
+ ffi_call(&cif, FFI_FN(promotion), &rint, values);
+ CHECK((int)rint == (signed char) sc + (signed short) ss +
+ (unsigned char) uc + (unsigned short) us);
+ }
+ printf("%lu promotion tests run\n", ul);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/pyobjc-tc.c b/js/src/ctypes/libffi/testsuite/libffi.call/pyobjc-tc.c
new file mode 100644
index 0000000000..e29bd6c283
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/pyobjc-tc.c
@@ -0,0 +1,114 @@
+/* Area: ffi_call
+ Purpose: Check different structures.
+ Limitations: none.
+ PR: none.
+ Originator: Ronald Oussoren <oussoren@cistron.nl> 20030824 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct Point {
+ float x;
+ float y;
+} Point;
+
+typedef struct Size {
+ float h;
+ float w;
+} Size;
+
+typedef struct Rect {
+ Point o;
+ Size s;
+} Rect;
+
+int doit(int o, char* s, Point p, Rect r, int last)
+{
+ printf("CALLED WITH %d %s {%f %f} {{%f %f} {%f %f}} %d\n",
+ o, s, p.x, p.y, r.o.x, r.o.y, r.s.h, r.s.w, last);
+ return 42;
+}
+
+
+int main(void)
+{
+ ffi_type point_type;
+ ffi_type size_type;
+ ffi_type rect_type;
+ ffi_cif cif;
+ ffi_type* arglist[6];
+ void* values[6];
+ int r;
+
+ /*
+ * First set up FFI types for the 3 struct types
+ */
+
+ point_type.size = 0; /*sizeof(Point);*/
+ point_type.alignment = 0; /*__alignof__(Point);*/
+ point_type.type = FFI_TYPE_STRUCT;
+ point_type.elements = malloc(3 * sizeof(ffi_type*));
+ point_type.elements[0] = &ffi_type_float;
+ point_type.elements[1] = &ffi_type_float;
+ point_type.elements[2] = NULL;
+
+ size_type.size = 0;/* sizeof(Size);*/
+ size_type.alignment = 0;/* __alignof__(Size);*/
+ size_type.type = FFI_TYPE_STRUCT;
+ size_type.elements = malloc(3 * sizeof(ffi_type*));
+ size_type.elements[0] = &ffi_type_float;
+ size_type.elements[1] = &ffi_type_float;
+ size_type.elements[2] = NULL;
+
+ rect_type.size = 0;/*sizeof(Rect);*/
+ rect_type.alignment =0;/* __alignof__(Rect);*/
+ rect_type.type = FFI_TYPE_STRUCT;
+ rect_type.elements = malloc(3 * sizeof(ffi_type*));
+ rect_type.elements[0] = &point_type;
+ rect_type.elements[1] = &size_type;
+ rect_type.elements[2] = NULL;
+
+ /*
+ * Create a CIF
+ */
+ arglist[0] = &ffi_type_sint;
+ arglist[1] = &ffi_type_pointer;
+ arglist[2] = &point_type;
+ arglist[3] = &rect_type;
+ arglist[4] = &ffi_type_sint;
+ arglist[5] = NULL;
+
+ r = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
+ 5, &ffi_type_sint, arglist);
+ if (r != FFI_OK) {
+ abort();
+ }
+
+
+ /* And call the function through the CIF */
+
+ {
+ Point p = { 1.0, 2.0 };
+ Rect r = { { 9.0, 10.0}, { -1.0, -2.0 } };
+ int o = 0;
+ int l = 42;
+ char* m = "myMethod";
+ ffi_arg result;
+
+ values[0] = &o;
+ values[1] = &m;
+ values[2] = &p;
+ values[3] = &r;
+ values[4] = &l;
+ values[5] = NULL;
+
+ printf("CALLING WITH %d %s {%f %f} {{%f %f} {%f %f}} %d\n",
+ o, m, p.x, p.y, r.o.x, r.o.y, r.s.h, r.s.w, l);
+
+ ffi_call(&cif, FFI_FN(doit), &result, values);
+
+ printf ("The result is %d\n", (int)result);
+
+ }
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_dbl.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_dbl.c
new file mode 100644
index 0000000000..fd07e50179
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_dbl.c
@@ -0,0 +1,36 @@
+/* Area: ffi_call
+ Purpose: Check return value double.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static double return_dbl(double dbl)
+{
+ printf ("%f\n", dbl);
+ return 2 * dbl;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ double dbl, rdbl;
+
+ args[0] = &ffi_type_double;
+ values[0] = &dbl;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_double, args) == FFI_OK);
+
+ for (dbl = -127.3; dbl < 127; dbl++)
+ {
+ ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
+ printf ("%f vs %f\n", rdbl, return_dbl(dbl));
+ CHECK(rdbl == 2 * dbl);
+ }
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_dbl1.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_dbl1.c
new file mode 100644
index 0000000000..0ea5d50551
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_dbl1.c
@@ -0,0 +1,43 @@
+/* Area: ffi_call
+ Purpose: Check return value double.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static double return_dbl(double dbl1, float fl2, unsigned int in3, double dbl4)
+{
+ return dbl1 + fl2 + in3 + dbl4;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ double dbl1, dbl4, rdbl;
+ float fl2;
+ unsigned int in3;
+ args[0] = &ffi_type_double;
+ args[1] = &ffi_type_float;
+ args[2] = &ffi_type_uint;
+ args[3] = &ffi_type_double;
+ values[0] = &dbl1;
+ values[1] = &fl2;
+ values[2] = &in3;
+ values[3] = &dbl4;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_double, args) == FFI_OK);
+ dbl1 = 127.0;
+ fl2 = 128.0;
+ in3 = 255;
+ dbl4 = 512.7;
+
+ ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
+ printf ("%f vs %f\n", rdbl, return_dbl(dbl1, fl2, in3, dbl4));
+ CHECK(rdbl == dbl1 + fl2 + in3 + dbl4);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_dbl2.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_dbl2.c
new file mode 100644
index 0000000000..b3818f866b
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_dbl2.c
@@ -0,0 +1,42 @@
+/* Area: ffi_call
+ Purpose: Check return value double.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static double return_dbl(double dbl1, double dbl2, unsigned int in3, double dbl4)
+{
+ return dbl1 + dbl2 + in3 + dbl4;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ double dbl1, dbl2, dbl4, rdbl;
+ unsigned int in3;
+ args[0] = &ffi_type_double;
+ args[1] = &ffi_type_double;
+ args[2] = &ffi_type_uint;
+ args[3] = &ffi_type_double;
+ values[0] = &dbl1;
+ values[1] = &dbl2;
+ values[2] = &in3;
+ values[3] = &dbl4;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_double, args) == FFI_OK);
+ dbl1 = 127.0;
+ dbl2 = 128.0;
+ in3 = 255;
+ dbl4 = 512.7;
+
+ ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
+ printf ("%f vs %f\n", rdbl, return_dbl(dbl1, dbl2, in3, dbl4));
+ CHECK(rdbl == dbl1 + dbl2 + in3 + dbl4);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_fl.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_fl.c
new file mode 100644
index 0000000000..fb8a09e32a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_fl.c
@@ -0,0 +1,35 @@
+/* Area: ffi_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static float return_fl(float fl)
+{
+ return 2 * fl;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float fl, rfl;
+
+ args[0] = &ffi_type_float;
+ values[0] = &fl;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_float, args) == FFI_OK);
+
+ for (fl = -127.0; fl < 127; fl++)
+ {
+ ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+ printf ("%f vs %f\n", rfl, return_fl(fl));
+ CHECK(rfl == 2 * fl);
+ }
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_fl1.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_fl1.c
new file mode 100644
index 0000000000..c3d92c283d
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_fl1.c
@@ -0,0 +1,36 @@
+/* Area: ffi_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static float return_fl(float fl1, float fl2)
+{
+ return fl1 + fl2;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float fl1, fl2, rfl;
+
+ args[0] = &ffi_type_float;
+ args[1] = &ffi_type_float;
+ values[0] = &fl1;
+ values[1] = &fl2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_float, args) == FFI_OK);
+ fl1 = 127.0;
+ fl2 = 128.0;
+
+ ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+ printf ("%f vs %f\n", rfl, return_fl(fl1, fl2));
+ CHECK(rfl == fl1 + fl2);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_fl2.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_fl2.c
new file mode 100644
index 0000000000..ddb976cc2b
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_fl2.c
@@ -0,0 +1,49 @@
+/* Area: ffi_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+/* Use volatile float to avoid false negative on ix86. See PR target/323. */
+static float return_fl(float fl1, float fl2, float fl3, float fl4)
+{
+ volatile float sum;
+
+ sum = fl1 + fl2 + fl3 + fl4;
+ return sum;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float fl1, fl2, fl3, fl4, rfl;
+ volatile float sum;
+
+ args[0] = &ffi_type_float;
+ args[1] = &ffi_type_float;
+ args[2] = &ffi_type_float;
+ args[3] = &ffi_type_float;
+ values[0] = &fl1;
+ values[1] = &fl2;
+ values[2] = &fl3;
+ values[3] = &fl4;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_float, args) == FFI_OK);
+ fl1 = 127.0;
+ fl2 = 128.0;
+ fl3 = 255.1;
+ fl4 = 512.7;
+
+ ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+ printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, fl3, fl4));
+
+ sum = fl1 + fl2 + fl3 + fl4;
+ CHECK(rfl == sum);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_fl3.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_fl3.c
new file mode 100644
index 0000000000..c37877b18e
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_fl3.c
@@ -0,0 +1,42 @@
+/* Area: ffi_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static float return_fl(float fl1, float fl2, unsigned int in3, float fl4)
+{
+ return fl1 + fl2 + in3 + fl4;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float fl1, fl2, fl4, rfl;
+ unsigned int in3;
+ args[0] = &ffi_type_float;
+ args[1] = &ffi_type_float;
+ args[2] = &ffi_type_uint;
+ args[3] = &ffi_type_float;
+ values[0] = &fl1;
+ values[1] = &fl2;
+ values[2] = &in3;
+ values[3] = &fl4;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_float, args) == FFI_OK);
+ fl1 = 127.0;
+ fl2 = 128.0;
+ in3 = 255;
+ fl4 = 512.7;
+
+ ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+ printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, in3, fl4));
+ CHECK(rfl == fl1 + fl2 + in3 + fl4);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_ldl.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_ldl.c
new file mode 100644
index 0000000000..52a92fe071
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_ldl.c
@@ -0,0 +1,34 @@
+/* Area: ffi_call
+ Purpose: Check return value long double.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20071113 */
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static long double return_ldl(long double ldl)
+{
+ return 2*ldl;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ long double ldl, rldl;
+
+ args[0] = &ffi_type_longdouble;
+ values[0] = &ldl;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_longdouble, args) == FFI_OK);
+
+ for (ldl = -127.0; ldl < 127.0; ldl++)
+ {
+ ffi_call(&cif, FFI_FN(return_ldl), &rldl, values);
+ CHECK(rldl == 2 * ldl);
+ }
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_ll.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_ll.c
new file mode 100644
index 0000000000..ea4a1e4478
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_ll.c
@@ -0,0 +1,41 @@
+/* Area: ffi_call
+ Purpose: Check return value long long.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static long long return_ll(long long ll)
+{
+ return ll;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ long long rlonglong;
+ long long ll;
+
+ args[0] = &ffi_type_sint64;
+ values[0] = &ll;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_sint64, args) == FFI_OK);
+
+ for (ll = 0LL; ll < 100LL; ll++)
+ {
+ ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+ CHECK(rlonglong == ll);
+ }
+
+ for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
+ {
+ ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+ CHECK(rlonglong == ll);
+ }
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_ll1.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_ll1.c
new file mode 100644
index 0000000000..593e8a307c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_ll1.c
@@ -0,0 +1,43 @@
+/* Area: ffi_call
+ Purpose: Check if long long are passed in the corresponding regs on ppc.
+ Limitations: none.
+ PR: 20104.
+ Originator: <andreast@gcc.gnu.org> 20050222 */
+
+/* { dg-do run } */
+/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
+#include "ffitest.h"
+static long long return_ll(int ll0, long long ll1, int ll2)
+{
+ return ll0 + ll1 + ll2;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ long long rlonglong;
+ long long ll1;
+ unsigned ll0, ll2;
+
+ args[0] = &ffi_type_sint;
+ args[1] = &ffi_type_sint64;
+ args[2] = &ffi_type_sint;
+ values[0] = &ll0;
+ values[1] = &ll1;
+ values[2] = &ll2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_sint64, args) == FFI_OK);
+
+ ll0 = 11111111;
+ ll1 = 11111111111000LL;
+ ll2 = 11111111;
+
+ ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+ printf("res: %" PRIdLL ", %" PRIdLL "\n", rlonglong, ll0 + ll1 + ll2);
+ /* { dg-output "res: 11111133333222, 11111133333222" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_sc.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_sc.c
new file mode 100644
index 0000000000..a36cf3eb88
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_sc.c
@@ -0,0 +1,36 @@
+/* Area: ffi_call
+ Purpose: Check return value signed char.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static signed char return_sc(signed char sc)
+{
+ return sc;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+ signed char sc;
+
+ args[0] = &ffi_type_schar;
+ values[0] = &sc;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_schar, args) == FFI_OK);
+
+ for (sc = (signed char) -127;
+ sc < (signed char) 127; sc++)
+ {
+ ffi_call(&cif, FFI_FN(return_sc), &rint, values);
+ CHECK((signed char)rint == sc);
+ }
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_sl.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_sl.c
new file mode 100644
index 0000000000..f0fd345f7a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_sl.c
@@ -0,0 +1,38 @@
+/* Area: ffi_call
+ Purpose: Check if long as return type is handled correctly.
+ Limitations: none.
+ PR: none.
+ */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static long return_sl(long l1, long l2)
+{
+ return l1 - l2;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg res;
+ unsigned long l1, l2;
+
+ args[0] = &ffi_type_slong;
+ args[1] = &ffi_type_slong;
+ values[0] = &l1;
+ values[1] = &l2;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_slong, args) == FFI_OK);
+
+ l1 = 1073741823L;
+ l2 = 1073741824L;
+
+ ffi_call(&cif, FFI_FN(return_sl), &res, values);
+ printf("res: %ld, %ld\n", (long)res, l1 - l2);
+ /* { dg-output "res: -1, -1" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_uc.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_uc.c
new file mode 100644
index 0000000000..6fe554619d
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_uc.c
@@ -0,0 +1,38 @@
+/* Area: ffi_call
+ Purpose: Check return value unsigned char.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static unsigned char return_uc(unsigned char uc)
+{
+ return uc;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+
+ unsigned char uc;
+
+ args[0] = &ffi_type_uchar;
+ values[0] = &uc;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uchar, args) == FFI_OK);
+
+ for (uc = (unsigned char) '\x00';
+ uc < (unsigned char) '\xff'; uc++)
+ {
+ ffi_call(&cif, FFI_FN(return_uc), &rint, values);
+ CHECK((unsigned char)rint == uc);
+ }
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/return_ul.c b/js/src/ctypes/libffi/testsuite/libffi.call/return_ul.c
new file mode 100644
index 0000000000..12b266f037
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/return_ul.c
@@ -0,0 +1,38 @@
+/* Area: ffi_call
+ Purpose: Check if unsigned long as return type is handled correctly.
+ Limitations: none.
+ PR: none.
+ Originator: <kaffeetisch at gmx dot de> 20060724 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static unsigned long return_ul(unsigned long ul1, unsigned long ul2)
+{
+ return ul1 + ul2;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg res;
+ unsigned long ul1, ul2;
+
+ args[0] = &ffi_type_ulong;
+ args[1] = &ffi_type_ulong;
+ values[0] = &ul1;
+ values[1] = &ul2;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_ulong, args) == FFI_OK);
+
+ ul1 = 1073741823L;
+ ul2 = 1073741824L;
+
+ ffi_call(&cif, FFI_FN(return_ul), &res, values);
+ printf("res: %lu, %lu\n", (unsigned long)res, ul1 + ul2);
+ /* { dg-output "res: 2147483647, 2147483647" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/strlen.c b/js/src/ctypes/libffi/testsuite/libffi.call/strlen.c
new file mode 100644
index 0000000000..35b70ea4e2
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/strlen.c
@@ -0,0 +1,44 @@
+/* Area: ffi_call
+ Purpose: Check strlen function call.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static size_t ABI_ATTR my_strlen(char *s)
+{
+ return (strlen(s));
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+ char *s;
+
+ args[0] = &ffi_type_pointer;
+ values[0] = (void*) &s;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1,
+ &ffi_type_sint, args) == FFI_OK);
+
+ s = "a";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 1);
+
+ s = "1234567";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 7);
+
+ s = "1234567890123456789012345";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 25);
+
+ exit (0);
+}
+
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/strlen2.c b/js/src/ctypes/libffi/testsuite/libffi.call/strlen2.c
new file mode 100644
index 0000000000..96282bc0a1
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/strlen2.c
@@ -0,0 +1,49 @@
+/* Area: ffi_call
+ Purpose: Check strlen function call with additional arguments.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static size_t ABI_ATTR my_f(char *s, float a)
+{
+ return (size_t) ((int) strlen(s) + (int) a);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+ char *s;
+ float v2;
+ args[0] = &ffi_type_pointer;
+ args[1] = &ffi_type_float;
+ values[0] = (void*) &s;
+ values[1] = (void*) &v2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 2,
+ &ffi_type_sint, args) == FFI_OK);
+
+ s = "a";
+ v2 = 0.0;
+ ffi_call(&cif, FFI_FN(my_f), &rint, values);
+ CHECK(rint == 1);
+
+ s = "1234567";
+ v2 = -1.0;
+ ffi_call(&cif, FFI_FN(my_f), &rint, values);
+ CHECK(rint == 6);
+
+ s = "1234567890123456789012345";
+ v2 = 1.0;
+ ffi_call(&cif, FFI_FN(my_f), &rint, values);
+ CHECK(rint == 26);
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/strlen3.c b/js/src/ctypes/libffi/testsuite/libffi.call/strlen3.c
new file mode 100644
index 0000000000..beba86e9ea
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/strlen3.c
@@ -0,0 +1,49 @@
+/* Area: ffi_call
+ Purpose: Check strlen function call with additional arguments.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static size_t ABI_ATTR my_f(float a, char *s)
+{
+ return (size_t) ((int) strlen(s) + (int) a);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+ char *s;
+ float v2;
+ args[1] = &ffi_type_pointer;
+ args[0] = &ffi_type_float;
+ values[1] = (void*) &s;
+ values[0] = (void*) &v2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 2,
+ &ffi_type_sint, args) == FFI_OK);
+
+ s = "a";
+ v2 = 0.0;
+ ffi_call(&cif, FFI_FN(my_f), &rint, values);
+ CHECK(rint == 1);
+
+ s = "1234567";
+ v2 = -1.0;
+ ffi_call(&cif, FFI_FN(my_f), &rint, values);
+ CHECK(rint == 6);
+
+ s = "1234567890123456789012345";
+ v2 = 1.0;
+ ffi_call(&cif, FFI_FN(my_f), &rint, values);
+ CHECK(rint == 26);
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/strlen4.c b/js/src/ctypes/libffi/testsuite/libffi.call/strlen4.c
new file mode 100644
index 0000000000..d5d42b4f6d
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/strlen4.c
@@ -0,0 +1,55 @@
+/* Area: ffi_call
+ Purpose: Check strlen function call with additional arguments.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static size_t ABI_ATTR my_f(float a, char *s, int i)
+{
+ return (size_t) ((int) strlen(s) + (int) a + i);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+ char *s;
+ int v1;
+ float v2;
+ args[2] = &ffi_type_sint;
+ args[1] = &ffi_type_pointer;
+ args[0] = &ffi_type_float;
+ values[2] = (void*) &v1;
+ values[1] = (void*) &s;
+ values[0] = (void*) &v2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 3,
+ &ffi_type_sint, args) == FFI_OK);
+
+ s = "a";
+ v1 = 1;
+ v2 = 0.0;
+ ffi_call(&cif, FFI_FN(my_f), &rint, values);
+ CHECK(rint == 2);
+
+ s = "1234567";
+ v2 = -1.0;
+ v1 = -2;
+ ffi_call(&cif, FFI_FN(my_f), &rint, values);
+ CHECK(rint == 4);
+
+ s = "1234567890123456789012345";
+ v2 = 1.0;
+ v1 = 2;
+ ffi_call(&cif, FFI_FN(my_f), &rint, values);
+ CHECK(rint == 28);
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/struct1.c b/js/src/ctypes/libffi/testsuite/libffi.call/struct1.c
new file mode 100644
index 0000000000..c13e23f872
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/struct1.c
@@ -0,0 +1,67 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ unsigned char uc;
+ double d;
+ unsigned int ui;
+} test_structure_1;
+
+static test_structure_1 ABI_ATTR struct1(test_structure_1 ts)
+{
+ ts.uc++;
+ ts.d--;
+ ts.ui++;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts1_type;
+ ffi_type *ts1_type_elements[4];
+
+ test_structure_1 ts1_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_1 *ts1_result =
+ (test_structure_1 *) malloc (sizeof(test_structure_1));
+
+ ts1_type.size = 0;
+ ts1_type.alignment = 0;
+ ts1_type.type = FFI_TYPE_STRUCT;
+ ts1_type.elements = ts1_type_elements;
+ ts1_type_elements[0] = &ffi_type_uchar;
+ ts1_type_elements[1] = &ffi_type_double;
+ ts1_type_elements[2] = &ffi_type_uint;
+ ts1_type_elements[3] = NULL;
+
+ args[0] = &ts1_type;
+ values[0] = &ts1_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1,
+ &ts1_type, args) == FFI_OK);
+
+ ts1_arg.uc = '\x01';
+ ts1_arg.d = 3.14159;
+ ts1_arg.ui = 555;
+
+ ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
+
+ CHECK(ts1_result->ui == 556);
+ CHECK(ts1_result->d == 3.14159 - 1);
+
+ free (ts1_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/struct10.c b/js/src/ctypes/libffi/testsuite/libffi.call/struct10.c
new file mode 100644
index 0000000000..17b1377424
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/struct10.c
@@ -0,0 +1,57 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: Sergei Trofimovich <slyfox@gentoo.org>
+
+ The test originally discovered in ruby's bindings
+ for ffi in https://bugs.gentoo.org/634190 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+struct s {
+ int s32;
+ float f32;
+ signed char s8;
+};
+
+struct s make_s(void) {
+ struct s r;
+ r.s32 = 0x1234;
+ r.f32 = 7.0;
+ r.s8 = 0x78;
+ return r;
+}
+
+int main() {
+ ffi_cif cif;
+ struct s r;
+ ffi_type rtype;
+ ffi_type* s_fields[] = {
+ &ffi_type_sint,
+ &ffi_type_float,
+ &ffi_type_schar,
+ NULL,
+ };
+
+ rtype.size = 0;
+ rtype.alignment = 0,
+ rtype.type = FFI_TYPE_STRUCT,
+ rtype.elements = s_fields,
+
+ r.s32 = 0xbad;
+ r.f32 = 999.999;
+ r.s8 = 0x51;
+
+ // Here we emulate the following call:
+ //r = make_s();
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &rtype, NULL) == FFI_OK);
+ ffi_call(&cif, FFI_FN(make_s), &r, NULL);
+
+ CHECK(r.s32 == 0x1234);
+ CHECK(r.f32 == 7.0);
+ CHECK(r.s8 == 0x78);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/struct2.c b/js/src/ctypes/libffi/testsuite/libffi.call/struct2.c
new file mode 100644
index 0000000000..5077a5ee45
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/struct2.c
@@ -0,0 +1,67 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ double d1;
+ double d2;
+} test_structure_2;
+
+static test_structure_2 ABI_ATTR struct2(test_structure_2 ts)
+{
+ ts.d1--;
+ ts.d2--;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ test_structure_2 ts2_arg;
+ ffi_type ts2_type;
+ ffi_type *ts2_type_elements[3];
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_2 *ts2_result =
+ (test_structure_2 *) malloc (sizeof(test_structure_2));
+
+ ts2_type.size = 0;
+ ts2_type.alignment = 0;
+ ts2_type.type = FFI_TYPE_STRUCT;
+ ts2_type.elements = ts2_type_elements;
+ ts2_type_elements[0] = &ffi_type_double;
+ ts2_type_elements[1] = &ffi_type_double;
+ ts2_type_elements[2] = NULL;
+
+ args[0] = &ts2_type;
+ values[0] = &ts2_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts2_type, args) == FFI_OK);
+
+ ts2_arg.d1 = 5.55;
+ ts2_arg.d2 = 6.66;
+
+ printf ("%g\n", ts2_arg.d1);
+ printf ("%g\n", ts2_arg.d2);
+
+ ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
+
+ printf ("%g\n", ts2_result->d1);
+ printf ("%g\n", ts2_result->d2);
+
+ CHECK(ts2_result->d1 == 5.55 - 1);
+ CHECK(ts2_result->d2 == 6.66 - 1);
+
+ free (ts2_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/struct3.c b/js/src/ctypes/libffi/testsuite/libffi.call/struct3.c
new file mode 100644
index 0000000000..7eba0ead6d
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/struct3.c
@@ -0,0 +1,60 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ int si;
+} test_structure_3;
+
+static test_structure_3 ABI_ATTR struct3(test_structure_3 ts)
+{
+ ts.si = -(ts.si*2);
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ int compare_value;
+ ffi_type ts3_type;
+ ffi_type *ts3_type_elements[2];
+
+ test_structure_3 ts3_arg;
+ test_structure_3 *ts3_result =
+ (test_structure_3 *) malloc (sizeof(test_structure_3));
+
+ ts3_type.size = 0;
+ ts3_type.alignment = 0;
+ ts3_type.type = FFI_TYPE_STRUCT;
+ ts3_type.elements = ts3_type_elements;
+ ts3_type_elements[0] = &ffi_type_sint;
+ ts3_type_elements[1] = NULL;
+
+ args[0] = &ts3_type;
+ values[0] = &ts3_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1,
+ &ts3_type, args) == FFI_OK);
+
+ ts3_arg.si = -123;
+ compare_value = ts3_arg.si;
+
+ ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
+
+ printf ("%d %d\n", ts3_result->si, -(compare_value*2));
+
+ CHECK(ts3_result->si == -(compare_value*2));
+
+ free (ts3_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/struct4.c b/js/src/ctypes/libffi/testsuite/libffi.call/struct4.c
new file mode 100644
index 0000000000..66a9551dd6
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/struct4.c
@@ -0,0 +1,64 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ unsigned ui1;
+ unsigned ui2;
+ unsigned ui3;
+} test_structure_4;
+
+static test_structure_4 ABI_ATTR struct4(test_structure_4 ts)
+{
+ ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts4_type;
+ ffi_type *ts4_type_elements[4];
+
+ test_structure_4 ts4_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_4 *ts4_result =
+ (test_structure_4 *) malloc (sizeof(test_structure_4));
+
+ ts4_type.size = 0;
+ ts4_type.alignment = 0;
+ ts4_type.type = FFI_TYPE_STRUCT;
+ ts4_type.elements = ts4_type_elements;
+ ts4_type_elements[0] = &ffi_type_uint;
+ ts4_type_elements[1] = &ffi_type_uint;
+ ts4_type_elements[2] = &ffi_type_uint;
+ ts4_type_elements[3] = NULL;
+
+ args[0] = &ts4_type;
+ values[0] = &ts4_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts4_type, args) == FFI_OK);
+
+ ts4_arg.ui1 = 2;
+ ts4_arg.ui2 = 3;
+ ts4_arg.ui3 = 4;
+
+ ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
+
+ CHECK(ts4_result->ui3 == 2U * 3U * 4U);
+
+
+ free (ts4_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/struct5.c b/js/src/ctypes/libffi/testsuite/libffi.call/struct5.c
new file mode 100644
index 0000000000..23e2a3f745
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/struct5.c
@@ -0,0 +1,66 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+ char c1;
+ char c2;
+} test_structure_5;
+
+static test_structure_5 ABI_ATTR struct5(test_structure_5 ts1, test_structure_5 ts2)
+{
+ ts1.c1 += ts2.c1;
+ ts1.c2 -= ts2.c2;
+
+ return ts1;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts5_type;
+ ffi_type *ts5_type_elements[3];
+
+ test_structure_5 ts5_arg1, ts5_arg2;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_5 *ts5_result =
+ (test_structure_5 *) malloc (sizeof(test_structure_5));
+
+ ts5_type.size = 0;
+ ts5_type.alignment = 0;
+ ts5_type.type = FFI_TYPE_STRUCT;
+ ts5_type.elements = ts5_type_elements;
+ ts5_type_elements[0] = &ffi_type_schar;
+ ts5_type_elements[1] = &ffi_type_schar;
+ ts5_type_elements[2] = NULL;
+
+ args[0] = &ts5_type;
+ args[1] = &ts5_type;
+ values[0] = &ts5_arg1;
+ values[1] = &ts5_arg2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts5_type, args) == FFI_OK);
+
+ ts5_arg1.c1 = 2;
+ ts5_arg1.c2 = 6;
+ ts5_arg2.c1 = 5;
+ ts5_arg2.c2 = 3;
+
+ ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
+
+ CHECK(ts5_result->c1 == 7);
+ CHECK(ts5_result->c2 == 3);
+
+
+ free (ts5_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/struct6.c b/js/src/ctypes/libffi/testsuite/libffi.call/struct6.c
new file mode 100644
index 0000000000..173c66eb4d
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/struct6.c
@@ -0,0 +1,64 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+ float f;
+ double d;
+} test_structure_6;
+
+static test_structure_6 ABI_ATTR struct6 (test_structure_6 ts)
+{
+ ts.f += 1;
+ ts.d += 1;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts6_type;
+ ffi_type *ts6_type_elements[3];
+
+ test_structure_6 ts6_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_6 *ts6_result =
+ (test_structure_6 *) malloc (sizeof(test_structure_6));
+
+ ts6_type.size = 0;
+ ts6_type.alignment = 0;
+ ts6_type.type = FFI_TYPE_STRUCT;
+ ts6_type.elements = ts6_type_elements;
+ ts6_type_elements[0] = &ffi_type_float;
+ ts6_type_elements[1] = &ffi_type_double;
+ ts6_type_elements[2] = NULL;
+
+ args[0] = &ts6_type;
+ values[0] = &ts6_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts6_type, args) == FFI_OK);
+
+ ts6_arg.f = 5.55f;
+ ts6_arg.d = 6.66;
+
+ printf ("%g\n", ts6_arg.f);
+ printf ("%g\n", ts6_arg.d);
+
+ ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
+
+ CHECK(ts6_result->f == 5.55f + 1);
+ CHECK(ts6_result->d == 6.66 + 1);
+
+ free (ts6_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/struct7.c b/js/src/ctypes/libffi/testsuite/libffi.call/struct7.c
new file mode 100644
index 0000000000..badc7e0556
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/struct7.c
@@ -0,0 +1,74 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+ float f1;
+ float f2;
+ double d;
+} test_structure_7;
+
+static test_structure_7 ABI_ATTR struct7 (test_structure_7 ts)
+{
+ ts.f1 += 1;
+ ts.f2 += 1;
+ ts.d += 1;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts7_type;
+ ffi_type *ts7_type_elements[4];
+
+ test_structure_7 ts7_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_7 *ts7_result =
+ (test_structure_7 *) malloc (sizeof(test_structure_7));
+
+ ts7_type.size = 0;
+ ts7_type.alignment = 0;
+ ts7_type.type = FFI_TYPE_STRUCT;
+ ts7_type.elements = ts7_type_elements;
+ ts7_type_elements[0] = &ffi_type_float;
+ ts7_type_elements[1] = &ffi_type_float;
+ ts7_type_elements[2] = &ffi_type_double;
+ ts7_type_elements[3] = NULL;
+
+ args[0] = &ts7_type;
+ values[0] = &ts7_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts7_type, args) == FFI_OK);
+
+ ts7_arg.f1 = 5.55f;
+ ts7_arg.f2 = 55.5f;
+ ts7_arg.d = 6.66;
+
+ printf ("%g\n", ts7_arg.f1);
+ printf ("%g\n", ts7_arg.f2);
+ printf ("%g\n", ts7_arg.d);
+
+ ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
+
+ printf ("%g\n", ts7_result->f1);
+ printf ("%g\n", ts7_result->f2);
+ printf ("%g\n", ts7_result->d);
+
+ CHECK(ts7_result->f1 == 5.55f + 1);
+ CHECK(ts7_result->f2 == 55.5f + 1);
+ CHECK(ts7_result->d == 6.66 + 1);
+
+ free (ts7_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/struct8.c b/js/src/ctypes/libffi/testsuite/libffi.call/struct8.c
new file mode 100644
index 0000000000..ef204ecbbc
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/struct8.c
@@ -0,0 +1,81 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+ float f1;
+ float f2;
+ float f3;
+ float f4;
+} test_structure_8;
+
+static test_structure_8 ABI_ATTR struct8 (test_structure_8 ts)
+{
+ ts.f1 += 1;
+ ts.f2 += 1;
+ ts.f3 += 1;
+ ts.f4 += 1;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts8_type;
+ ffi_type *ts8_type_elements[5];
+
+ test_structure_8 ts8_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_8 *ts8_result =
+ (test_structure_8 *) malloc (sizeof(test_structure_8));
+
+ ts8_type.size = 0;
+ ts8_type.alignment = 0;
+ ts8_type.type = FFI_TYPE_STRUCT;
+ ts8_type.elements = ts8_type_elements;
+ ts8_type_elements[0] = &ffi_type_float;
+ ts8_type_elements[1] = &ffi_type_float;
+ ts8_type_elements[2] = &ffi_type_float;
+ ts8_type_elements[3] = &ffi_type_float;
+ ts8_type_elements[4] = NULL;
+
+ args[0] = &ts8_type;
+ values[0] = &ts8_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts8_type, args) == FFI_OK);
+
+ ts8_arg.f1 = 5.55f;
+ ts8_arg.f2 = 55.5f;
+ ts8_arg.f3 = -5.55f;
+ ts8_arg.f4 = -55.5f;
+
+ printf ("%g\n", ts8_arg.f1);
+ printf ("%g\n", ts8_arg.f2);
+ printf ("%g\n", ts8_arg.f3);
+ printf ("%g\n", ts8_arg.f4);
+
+ ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
+
+ printf ("%g\n", ts8_result->f1);
+ printf ("%g\n", ts8_result->f2);
+ printf ("%g\n", ts8_result->f3);
+ printf ("%g\n", ts8_result->f4);
+
+ CHECK(ts8_result->f1 == 5.55f + 1);
+ CHECK(ts8_result->f2 == 55.5f + 1);
+ CHECK(ts8_result->f3 == -5.55f + 1);
+ CHECK(ts8_result->f4 == -55.5f + 1);
+
+ free (ts8_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/struct9.c b/js/src/ctypes/libffi/testsuite/libffi.call/struct9.c
new file mode 100644
index 0000000000..4a13b818c4
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/struct9.c
@@ -0,0 +1,68 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ float f;
+ int i;
+} test_structure_9;
+
+static test_structure_9 ABI_ATTR struct9 (test_structure_9 ts)
+{
+ ts.f += 1;
+ ts.i += 1;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts9_type;
+ ffi_type *ts9_type_elements[3];
+
+ test_structure_9 ts9_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_9 *ts9_result =
+ (test_structure_9 *) malloc (sizeof(test_structure_9));
+
+ ts9_type.size = 0;
+ ts9_type.alignment = 0;
+ ts9_type.type = FFI_TYPE_STRUCT;
+ ts9_type.elements = ts9_type_elements;
+ ts9_type_elements[0] = &ffi_type_float;
+ ts9_type_elements[1] = &ffi_type_sint;
+ ts9_type_elements[2] = NULL;
+
+ args[0] = &ts9_type;
+ values[0] = &ts9_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts9_type, args) == FFI_OK);
+
+ ts9_arg.f = 5.55f;
+ ts9_arg.i = 5;
+
+ printf ("%g\n", ts9_arg.f);
+ printf ("%d\n", ts9_arg.i);
+
+ ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
+
+ printf ("%g\n", ts9_result->f);
+ printf ("%d\n", ts9_result->i);
+
+ CHECK(ts9_result->f == 5.55f + 1);
+ CHECK(ts9_result->i == 5 + 1);
+
+ free (ts9_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/uninitialized.c b/js/src/ctypes/libffi/testsuite/libffi.call/uninitialized.c
new file mode 100644
index 0000000000..f00d830234
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/uninitialized.c
@@ -0,0 +1,61 @@
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ unsigned char uc;
+ double d;
+ unsigned int ui;
+} test_structure_1;
+
+static test_structure_1 struct1(test_structure_1 ts)
+{
+ ts.uc++;
+ ts.d--;
+ ts.ui++;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts1_type;
+ ffi_type *ts1_type_elements[4];
+
+ memset(&cif, 1, sizeof(cif));
+ ts1_type.size = 0;
+ ts1_type.alignment = 0;
+ ts1_type.type = FFI_TYPE_STRUCT;
+ ts1_type.elements = ts1_type_elements;
+ ts1_type_elements[0] = &ffi_type_uchar;
+ ts1_type_elements[1] = &ffi_type_double;
+ ts1_type_elements[2] = &ffi_type_uint;
+ ts1_type_elements[3] = NULL;
+
+ test_structure_1 ts1_arg;
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_1 *ts1_result =
+ (test_structure_1 *) malloc (sizeof(test_structure_1));
+
+ args[0] = &ts1_type;
+ values[0] = &ts1_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ts1_type, args) == FFI_OK);
+
+ ts1_arg.uc = '\x01';
+ ts1_arg.d = 3.14159;
+ ts1_arg.ui = 555;
+
+ ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
+
+ CHECK(ts1_result->ui == 556);
+ CHECK(ts1_result->d == 3.14159 - 1);
+
+ free (ts1_result);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/va_1.c b/js/src/ctypes/libffi/testsuite/libffi.call/va_1.c
new file mode 100644
index 0000000000..59d085c832
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/va_1.c
@@ -0,0 +1,196 @@
+/* Area: ffi_call
+ Purpose: Test passing struct in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: ARM Ltd. */
+
+/* { dg-do run } */
+/* { dg-output "" { xfail avr32*-*-* m68k-*-* alpha-*-* } } */
+
+#include "ffitest.h"
+#include <stdarg.h>
+
+struct small_tag
+{
+ unsigned char a;
+ unsigned char b;
+};
+
+struct large_tag
+{
+ unsigned a;
+ unsigned b;
+ unsigned c;
+ unsigned d;
+ unsigned e;
+};
+
+static int
+test_fn (int n, ...)
+{
+ va_list ap;
+ struct small_tag s1;
+ struct small_tag s2;
+ struct large_tag l;
+ unsigned char uc;
+ signed char sc;
+ unsigned short us;
+ signed short ss;
+ unsigned int ui;
+ signed int si;
+ unsigned long ul;
+ signed long sl;
+ float f;
+ double d;
+
+ va_start (ap, n);
+ s1 = va_arg (ap, struct small_tag);
+ l = va_arg (ap, struct large_tag);
+ s2 = va_arg (ap, struct small_tag);
+
+ uc = va_arg (ap, unsigned);
+ sc = va_arg (ap, signed);
+
+ us = va_arg (ap, unsigned);
+ ss = va_arg (ap, signed);
+
+ ui = va_arg (ap, unsigned int);
+ si = va_arg (ap, signed int);
+
+ ul = va_arg (ap, unsigned long);
+ sl = va_arg (ap, signed long);
+
+ f = va_arg (ap, double); /* C standard promotes float->double
+ when anonymous */
+ d = va_arg (ap, double);
+
+ printf ("%u %u %u %u %u %u %u %u %u uc=%u sc=%d %u %d %u %d %lu %ld %f %f\n",
+ s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
+ s2.a, s2.b,
+ uc, sc,
+ us, ss,
+ ui, si,
+ ul, sl,
+ f, d);
+ va_end (ap);
+ return n + 1;
+}
+
+int
+main (void)
+{
+ ffi_cif cif;
+ void* args[15];
+ ffi_type* arg_types[15];
+
+ ffi_type s_type;
+ ffi_type *s_type_elements[3];
+
+ ffi_type l_type;
+ ffi_type *l_type_elements[6];
+
+ struct small_tag s1;
+ struct small_tag s2;
+ struct large_tag l1;
+
+ int n;
+ ffi_arg res;
+
+ unsigned char uc;
+ signed char sc;
+ unsigned short us;
+ signed short ss;
+ unsigned int ui;
+ signed int si;
+ unsigned long ul;
+ signed long sl;
+ double d1;
+ double f1;
+
+ s_type.size = 0;
+ s_type.alignment = 0;
+ s_type.type = FFI_TYPE_STRUCT;
+ s_type.elements = s_type_elements;
+
+ s_type_elements[0] = &ffi_type_uchar;
+ s_type_elements[1] = &ffi_type_uchar;
+ s_type_elements[2] = NULL;
+
+ l_type.size = 0;
+ l_type.alignment = 0;
+ l_type.type = FFI_TYPE_STRUCT;
+ l_type.elements = l_type_elements;
+
+ l_type_elements[0] = &ffi_type_uint;
+ l_type_elements[1] = &ffi_type_uint;
+ l_type_elements[2] = &ffi_type_uint;
+ l_type_elements[3] = &ffi_type_uint;
+ l_type_elements[4] = &ffi_type_uint;
+ l_type_elements[5] = NULL;
+
+ arg_types[0] = &ffi_type_sint;
+ arg_types[1] = &s_type;
+ arg_types[2] = &l_type;
+ arg_types[3] = &s_type;
+ arg_types[4] = &ffi_type_uchar;
+ arg_types[5] = &ffi_type_schar;
+ arg_types[6] = &ffi_type_ushort;
+ arg_types[7] = &ffi_type_sshort;
+ arg_types[8] = &ffi_type_uint;
+ arg_types[9] = &ffi_type_sint;
+ arg_types[10] = &ffi_type_ulong;
+ arg_types[11] = &ffi_type_slong;
+ arg_types[12] = &ffi_type_double;
+ arg_types[13] = &ffi_type_double;
+ arg_types[14] = NULL;
+
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 14, &ffi_type_sint, arg_types) == FFI_OK);
+
+ s1.a = 5;
+ s1.b = 6;
+
+ l1.a = 10;
+ l1.b = 11;
+ l1.c = 12;
+ l1.d = 13;
+ l1.e = 14;
+
+ s2.a = 7;
+ s2.b = 8;
+
+ n = 41;
+
+ uc = 9;
+ sc = 10;
+ us = 11;
+ ss = 12;
+ ui = 13;
+ si = 14;
+ ul = 15;
+ sl = 16;
+ f1 = 2.12;
+ d1 = 3.13;
+
+ args[0] = &n;
+ args[1] = &s1;
+ args[2] = &l1;
+ args[3] = &s2;
+ args[4] = &uc;
+ args[5] = &sc;
+ args[6] = &us;
+ args[7] = &ss;
+ args[8] = &ui;
+ args[9] = &si;
+ args[10] = &ul;
+ args[11] = &sl;
+ args[12] = &f1;
+ args[13] = &d1;
+ args[14] = NULL;
+
+ ffi_call(&cif, FFI_FN(test_fn), &res, args);
+ /* { dg-output "5 6 10 11 12 13 14 7 8 uc=9 sc=10 11 12 13 14 15 16 2.120000 3.130000" } */
+ printf("res: %d\n", (int) res);
+ /* { dg-output "\nres: 42" } */
+
+ return 0;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/va_struct1.c b/js/src/ctypes/libffi/testsuite/libffi.call/va_struct1.c
new file mode 100644
index 0000000000..e6452061c1
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/va_struct1.c
@@ -0,0 +1,121 @@
+/* Area: ffi_call
+ Purpose: Test passing struct in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: ARM Ltd. */
+
+/* { dg-do run } */
+/* { dg-output "" { xfail avr32*-*-* } } */
+
+#include "ffitest.h"
+#include <stdarg.h>
+
+struct small_tag
+{
+ unsigned char a;
+ unsigned char b;
+};
+
+struct large_tag
+{
+ unsigned a;
+ unsigned b;
+ unsigned c;
+ unsigned d;
+ unsigned e;
+};
+
+static int
+test_fn (int n, ...)
+{
+ va_list ap;
+ struct small_tag s1;
+ struct small_tag s2;
+ struct large_tag l;
+
+ va_start (ap, n);
+ s1 = va_arg (ap, struct small_tag);
+ l = va_arg (ap, struct large_tag);
+ s2 = va_arg (ap, struct small_tag);
+ printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
+ s2.a, s2.b);
+ va_end (ap);
+ return n + 1;
+}
+
+int
+main (void)
+{
+ ffi_cif cif;
+ void* args[5];
+ ffi_type* arg_types[5];
+
+ ffi_type s_type;
+ ffi_type *s_type_elements[3];
+
+ ffi_type l_type;
+ ffi_type *l_type_elements[6];
+
+ struct small_tag s1;
+ struct small_tag s2;
+ struct large_tag l1;
+
+ int n;
+ ffi_arg res;
+
+ s_type.size = 0;
+ s_type.alignment = 0;
+ s_type.type = FFI_TYPE_STRUCT;
+ s_type.elements = s_type_elements;
+
+ s_type_elements[0] = &ffi_type_uchar;
+ s_type_elements[1] = &ffi_type_uchar;
+ s_type_elements[2] = NULL;
+
+ l_type.size = 0;
+ l_type.alignment = 0;
+ l_type.type = FFI_TYPE_STRUCT;
+ l_type.elements = l_type_elements;
+
+ l_type_elements[0] = &ffi_type_uint;
+ l_type_elements[1] = &ffi_type_uint;
+ l_type_elements[2] = &ffi_type_uint;
+ l_type_elements[3] = &ffi_type_uint;
+ l_type_elements[4] = &ffi_type_uint;
+ l_type_elements[5] = NULL;
+
+ arg_types[0] = &ffi_type_sint;
+ arg_types[1] = &s_type;
+ arg_types[2] = &l_type;
+ arg_types[3] = &s_type;
+ arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint, arg_types) == FFI_OK);
+
+ s1.a = 5;
+ s1.b = 6;
+
+ l1.a = 10;
+ l1.b = 11;
+ l1.c = 12;
+ l1.d = 13;
+ l1.e = 14;
+
+ s2.a = 7;
+ s2.b = 8;
+
+ n = 41;
+
+ args[0] = &n;
+ args[1] = &s1;
+ args[2] = &l1;
+ args[3] = &s2;
+ args[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(test_fn), &res, args);
+ /* { dg-output "5 6 10 11 12 13 14 7 8" } */
+ printf("res: %d\n", (int) res);
+ /* { dg-output "\nres: 42" } */
+
+ return 0;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/va_struct2.c b/js/src/ctypes/libffi/testsuite/libffi.call/va_struct2.c
new file mode 100644
index 0000000000..56f5b9c75f
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/va_struct2.c
@@ -0,0 +1,123 @@
+/* Area: ffi_call
+ Purpose: Test passing struct in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: ARM Ltd. */
+
+/* { dg-do run } */
+/* { dg-output "" { xfail avr32*-*-* } } */
+
+#include "ffitest.h"
+#include <stdarg.h>
+
+struct small_tag
+{
+ unsigned char a;
+ unsigned char b;
+};
+
+struct large_tag
+{
+ unsigned a;
+ unsigned b;
+ unsigned c;
+ unsigned d;
+ unsigned e;
+};
+
+static struct small_tag
+test_fn (int n, ...)
+{
+ va_list ap;
+ struct small_tag s1;
+ struct small_tag s2;
+ struct large_tag l;
+
+ va_start (ap, n);
+ s1 = va_arg (ap, struct small_tag);
+ l = va_arg (ap, struct large_tag);
+ s2 = va_arg (ap, struct small_tag);
+ printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
+ s2.a, s2.b);
+ va_end (ap);
+ s1.a += s2.a;
+ s1.b += s2.b;
+ return s1;
+}
+
+int
+main (void)
+{
+ ffi_cif cif;
+ void* args[5];
+ ffi_type* arg_types[5];
+
+ ffi_type s_type;
+ ffi_type *s_type_elements[3];
+
+ ffi_type l_type;
+ ffi_type *l_type_elements[6];
+
+ struct small_tag s1;
+ struct small_tag s2;
+ struct large_tag l1;
+
+ int n;
+ struct small_tag res;
+
+ s_type.size = 0;
+ s_type.alignment = 0;
+ s_type.type = FFI_TYPE_STRUCT;
+ s_type.elements = s_type_elements;
+
+ s_type_elements[0] = &ffi_type_uchar;
+ s_type_elements[1] = &ffi_type_uchar;
+ s_type_elements[2] = NULL;
+
+ l_type.size = 0;
+ l_type.alignment = 0;
+ l_type.type = FFI_TYPE_STRUCT;
+ l_type.elements = l_type_elements;
+
+ l_type_elements[0] = &ffi_type_uint;
+ l_type_elements[1] = &ffi_type_uint;
+ l_type_elements[2] = &ffi_type_uint;
+ l_type_elements[3] = &ffi_type_uint;
+ l_type_elements[4] = &ffi_type_uint;
+ l_type_elements[5] = NULL;
+
+ arg_types[0] = &ffi_type_sint;
+ arg_types[1] = &s_type;
+ arg_types[2] = &l_type;
+ arg_types[3] = &s_type;
+ arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &s_type, arg_types) == FFI_OK);
+
+ s1.a = 5;
+ s1.b = 6;
+
+ l1.a = 10;
+ l1.b = 11;
+ l1.c = 12;
+ l1.d = 13;
+ l1.e = 14;
+
+ s2.a = 7;
+ s2.b = 8;
+
+ n = 41;
+
+ args[0] = &n;
+ args[1] = &s1;
+ args[2] = &l1;
+ args[3] = &s2;
+ args[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(test_fn), &res, args);
+ /* { dg-output "5 6 10 11 12 13 14 7 8" } */
+ printf("res: %d %d\n", res.a, res.b);
+ /* { dg-output "\nres: 12 14" } */
+
+ return 0;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/va_struct3.c b/js/src/ctypes/libffi/testsuite/libffi.call/va_struct3.c
new file mode 100644
index 0000000000..9a27e7fd4a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/va_struct3.c
@@ -0,0 +1,125 @@
+/* Area: ffi_call
+ Purpose: Test passing struct in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: ARM Ltd. */
+
+/* { dg-do run } */
+/* { dg-output "" { xfail avr32*-*-* } } */
+
+#include "ffitest.h"
+#include <stdarg.h>
+
+struct small_tag
+{
+ unsigned char a;
+ unsigned char b;
+};
+
+struct large_tag
+{
+ unsigned a;
+ unsigned b;
+ unsigned c;
+ unsigned d;
+ unsigned e;
+};
+
+static struct large_tag
+test_fn (int n, ...)
+{
+ va_list ap;
+ struct small_tag s1;
+ struct small_tag s2;
+ struct large_tag l;
+
+ va_start (ap, n);
+ s1 = va_arg (ap, struct small_tag);
+ l = va_arg (ap, struct large_tag);
+ s2 = va_arg (ap, struct small_tag);
+ printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
+ s2.a, s2.b);
+ va_end (ap);
+ l.a += s1.a;
+ l.b += s1.b;
+ l.c += s2.a;
+ l.d += s2.b;
+ return l;
+}
+
+int
+main (void)
+{
+ ffi_cif cif;
+ void* args[5];
+ ffi_type* arg_types[5];
+
+ ffi_type s_type;
+ ffi_type *s_type_elements[3];
+
+ ffi_type l_type;
+ ffi_type *l_type_elements[6];
+
+ struct small_tag s1;
+ struct small_tag s2;
+ struct large_tag l1;
+
+ int n;
+ struct large_tag res;
+
+ s_type.size = 0;
+ s_type.alignment = 0;
+ s_type.type = FFI_TYPE_STRUCT;
+ s_type.elements = s_type_elements;
+
+ s_type_elements[0] = &ffi_type_uchar;
+ s_type_elements[1] = &ffi_type_uchar;
+ s_type_elements[2] = NULL;
+
+ l_type.size = 0;
+ l_type.alignment = 0;
+ l_type.type = FFI_TYPE_STRUCT;
+ l_type.elements = l_type_elements;
+
+ l_type_elements[0] = &ffi_type_uint;
+ l_type_elements[1] = &ffi_type_uint;
+ l_type_elements[2] = &ffi_type_uint;
+ l_type_elements[3] = &ffi_type_uint;
+ l_type_elements[4] = &ffi_type_uint;
+ l_type_elements[5] = NULL;
+
+ arg_types[0] = &ffi_type_sint;
+ arg_types[1] = &s_type;
+ arg_types[2] = &l_type;
+ arg_types[3] = &s_type;
+ arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &l_type, arg_types) == FFI_OK);
+
+ s1.a = 5;
+ s1.b = 6;
+
+ l1.a = 10;
+ l1.b = 11;
+ l1.c = 12;
+ l1.d = 13;
+ l1.e = 14;
+
+ s2.a = 7;
+ s2.b = 8;
+
+ n = 41;
+
+ args[0] = &n;
+ args[1] = &s1;
+ args[2] = &l1;
+ args[3] = &s2;
+ args[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(test_fn), &res, args);
+ /* { dg-output "5 6 10 11 12 13 14 7 8" } */
+ printf("res: %d %d %d %d %d\n", res.a, res.b, res.c, res.d, res.e);
+ /* { dg-output "\nres: 15 17 19 21 14" } */
+
+ return 0;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/closure.exp b/js/src/ctypes/libffi/testsuite/libffi.closures/closure.exp
new file mode 100644
index 0000000000..ed4145ca84
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/closure.exp
@@ -0,0 +1,67 @@
+# Copyright (C) 2003, 2006, 2009, 2010, 2014, 2019 Free Software Foundation, Inc.
+# Copyright (C) 2019 Anthony Green
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+dg-init
+libffi-init
+
+global srcdir subdir
+
+if { [string match $compiler_vendor "microsoft"] } {
+ # -wd4005 macro redefinition
+ # -wd4244 implicit conversion to type of smaller size
+ # -wd4305 truncation to smaller type
+ # -wd4477 printf %lu of uintptr_t
+ # -wd4312 implicit conversion to type of greater size
+ # -wd4311 pointer truncation to unsigned long
+ # -EHsc C++ Exception Handling (no SEH exceptions)
+ set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc";
+} else {
+ set additional_options "";
+}
+
+set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]]
+
+if { [libffi_feature_test "#if FFI_CLOSURES"] } {
+ run-many-tests $tlist ""
+} else {
+ foreach test $tlist {
+ unsupported "$test"
+ }
+}
+
+set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]]
+
+# No C++ for or1k
+if { [istarget "or1k-*-*"] } {
+ foreach test $tlist {
+ unsupported "$test"
+ }
+} else {
+ if { [libffi_feature_test "#if FFI_CLOSURES"] } {
+ run-many-tests $tlist $additional_options
+ } else {
+ foreach test $tlist {
+ unsupported "$test"
+ }
+ }
+}
+
+dg-finish
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn0.c b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn0.c
new file mode 100644
index 0000000000..a579ff6c97
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn0.c
@@ -0,0 +1,89 @@
+/* Area: closure_call
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
+ (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
+ (int)(*(signed short *)args[4]) +
+ (int)(*(unsigned long long *)args[5]) +
+ (int)*(int *)args[6] + (int)(*(int *)args[7]) +
+ (int)(*(double *)args[8]) + (int)*(int *)args[9] +
+ (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+ (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+ (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
+ (int)(*(unsigned long long *)args[2]),
+ (int)*(int *)args[3], (int)(*(signed short *)args[4]),
+ (int)(*(unsigned long long *)args[5]),
+ (int)*(int *)args[6], (int)(*(int *)args[7]),
+ (int)(*(double *)args[8]), (int)*(int *)args[9],
+ (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+ (int)*(int *)args[12], (int)(*(int *)args[13]),
+ (int)(*(int *)args[14]),*(int *)args[15],
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long, int, unsigned long long,
+ int, signed short, unsigned long long, int,
+ int, double, int, int, float, int, int,
+ int, int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void * code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[17];
+ int res;
+
+ cl_arg_types[0] = &ffi_type_uint64;
+ cl_arg_types[1] = &ffi_type_sint;
+ cl_arg_types[2] = &ffi_type_uint64;
+ cl_arg_types[3] = &ffi_type_sint;
+ cl_arg_types[4] = &ffi_type_sshort;
+ cl_arg_types[5] = &ffi_type_uint64;
+ cl_arg_types[6] = &ffi_type_sint;
+ cl_arg_types[7] = &ffi_type_sint;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_sint;
+ cl_arg_types[10] = &ffi_type_sint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_sint;
+ cl_arg_types[14] = &ffi_type_sint;
+ cl_arg_types[15] = &ffi_type_sint;
+ cl_arg_types[16] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
+ (void *) 3 /* userdata */, code) == FFI_OK);
+
+ res = (*((closure_test_type0)code))
+ (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
+ 19, 21, 1);
+ /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 680" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn1.c b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn1.c
new file mode 100644
index 0000000000..91231738c1
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn1.c
@@ -0,0 +1,81 @@
+/* Area: closure_call.
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+
+static void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(float *)args[0] +(int)(*(float *)args[1]) +
+ (int)(*(float *)args[2]) + (int)*(float *)args[3] +
+ (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) +
+ (int)*(float *)args[6] + (int)(*(int *)args[7]) +
+ (int)(*(double*)args[8]) + (int)*(int *)args[9] +
+ (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+ (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+ (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(float *)args[0], (int)(*(float *)args[1]),
+ (int)(*(float *)args[2]), (int)*(float *)args[3],
+ (int)(*(signed short *)args[4]), (int)(*(float *)args[5]),
+ (int)*(float *)args[6], (int)(*(int *)args[7]),
+ (int)(*(double *)args[8]), (int)*(int *)args[9],
+ (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+ (int)*(int *)args[12], (int)(*(int *)args[13]),
+ (int)(*(int *)args[14]), *(int *)args[15],
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+}
+
+typedef int (*closure_test_type1)(float, float, float, float, signed short,
+ float, float, int, double, int, int, float,
+ int, int, int, int);
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[17];
+ int res;
+
+ cl_arg_types[0] = &ffi_type_float;
+ cl_arg_types[1] = &ffi_type_float;
+ cl_arg_types[2] = &ffi_type_float;
+ cl_arg_types[3] = &ffi_type_float;
+ cl_arg_types[4] = &ffi_type_sshort;
+ cl_arg_types[5] = &ffi_type_float;
+ cl_arg_types[6] = &ffi_type_float;
+ cl_arg_types[7] = &ffi_type_sint;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_sint;
+ cl_arg_types[10] = &ffi_type_sint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_sint;
+ cl_arg_types[14] = &ffi_type_sint;
+ cl_arg_types[15] = &ffi_type_sint;
+ cl_arg_types[16] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1,
+ (void *) 3 /* userdata */, code) == FFI_OK);
+
+ res = (*((closure_test_type1)code))
+ (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
+ 19, 21, 1);
+ /* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 255" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn2.c b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn2.c
new file mode 100644
index 0000000000..08ff9d9227
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn2.c
@@ -0,0 +1,81 @@
+/* Area: closure_call
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void closure_test_fn2(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(double *)args[0] +(int)(*(double *)args[1]) +
+ (int)(*(double *)args[2]) + (int)*(double *)args[3] +
+ (int)(*(signed short *)args[4]) + (int)(*(double *)args[5]) +
+ (int)*(double *)args[6] + (int)(*(int *)args[7]) +
+ (int)(*(double *)args[8]) + (int)*(int *)args[9] +
+ (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+ (int)*(int *)args[12] + (int)(*(float *)args[13]) +
+ (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(double *)args[0], (int)(*(double *)args[1]),
+ (int)(*(double *)args[2]), (int)*(double *)args[3],
+ (int)(*(signed short *)args[4]), (int)(*(double *)args[5]),
+ (int)*(double *)args[6], (int)(*(int *)args[7]),
+ (int)(*(double*)args[8]), (int)*(int *)args[9],
+ (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+ (int)*(int *)args[12], (int)(*(float *)args[13]),
+ (int)(*(int *)args[14]), *(int *)args[15], (int)(intptr_t)userdata,
+ (int)*(ffi_arg *)resp);
+}
+
+typedef int (*closure_test_type2)(double, double, double, double, signed short,
+ double, double, int, double, int, int, float,
+ int, float, int, int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[17];
+ int res;
+
+ cl_arg_types[0] = &ffi_type_double;
+ cl_arg_types[1] = &ffi_type_double;
+ cl_arg_types[2] = &ffi_type_double;
+ cl_arg_types[3] = &ffi_type_double;
+ cl_arg_types[4] = &ffi_type_sshort;
+ cl_arg_types[5] = &ffi_type_double;
+ cl_arg_types[6] = &ffi_type_double;
+ cl_arg_types[7] = &ffi_type_sint;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_sint;
+ cl_arg_types[10] = &ffi_type_sint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_float;
+ cl_arg_types[14] = &ffi_type_sint;
+ cl_arg_types[15] = &ffi_type_sint;
+ cl_arg_types[16] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn2,
+ (void *) 3 /* userdata */, code) == FFI_OK);
+
+ res = (*((closure_test_type2)code))
+ (1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
+ 19.0, 21, 1);
+ /* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 255" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn3.c b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn3.c
new file mode 100644
index 0000000000..9b54d805c8
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn3.c
@@ -0,0 +1,82 @@
+/* Area: closure_call
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void closure_test_fn3(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+ {
+ *(ffi_arg*)resp =
+ (int)*(float *)args[0] +(int)(*(float *)args[1]) +
+ (int)(*(float *)args[2]) + (int)*(float *)args[3] +
+ (int)(*(float *)args[4]) + (int)(*(float *)args[5]) +
+ (int)*(float *)args[6] + (int)(*(float *)args[7]) +
+ (int)(*(double *)args[8]) + (int)*(int *)args[9] +
+ (int)(*(float *)args[10]) + (int)(*(float *)args[11]) +
+ (int)*(int *)args[12] + (int)(*(float *)args[13]) +
+ (int)(*(float *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(float *)args[0], (int)(*(float *)args[1]),
+ (int)(*(float *)args[2]), (int)*(float *)args[3],
+ (int)(*(float *)args[4]), (int)(*(float *)args[5]),
+ (int)*(float *)args[6], (int)(*(float *)args[7]),
+ (int)(*(double *)args[8]), (int)*(int *)args[9],
+ (int)(*(float *)args[10]), (int)(*(float *)args[11]),
+ (int)*(int *)args[12], (int)(*(float *)args[13]),
+ (int)(*(float *)args[14]), *(int *)args[15], (int)(intptr_t)userdata,
+ (int)*(ffi_arg *)resp);
+
+ }
+
+typedef int (*closure_test_type3)(float, float, float, float, float, float,
+ float, float, double, int, float, float, int,
+ float, float, int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[17];
+ int res;
+
+ cl_arg_types[0] = &ffi_type_float;
+ cl_arg_types[1] = &ffi_type_float;
+ cl_arg_types[2] = &ffi_type_float;
+ cl_arg_types[3] = &ffi_type_float;
+ cl_arg_types[4] = &ffi_type_float;
+ cl_arg_types[5] = &ffi_type_float;
+ cl_arg_types[6] = &ffi_type_float;
+ cl_arg_types[7] = &ffi_type_float;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_sint;
+ cl_arg_types[10] = &ffi_type_float;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_float;
+ cl_arg_types[14] = &ffi_type_float;
+ cl_arg_types[15] = &ffi_type_sint;
+ cl_arg_types[16] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn3,
+ (void *) 3 /* userdata */, code) == FFI_OK);
+
+ res = (*((closure_test_type3)code))
+ (1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
+ 19.19, 21.21, 1);
+ /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 19 21 1 3: 135" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 135" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn4.c b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn4.c
new file mode 100644
index 0000000000..d4a1530b06
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn4.c
@@ -0,0 +1,89 @@
+/* Area: closure_call
+ Purpose: Check multiple long long values passing.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20031026 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static void
+closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
+ (int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] +
+ (int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] +
+ (int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] +
+ (int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] +
+ (int)*(unsigned long long *)args[10] +
+ (int)*(unsigned long long *)args[11] +
+ (int)*(unsigned long long *)args[12] +
+ (int)*(unsigned long long *)args[13] +
+ (int)*(unsigned long long *)args[14] +
+ *(int *)args[15] + (intptr_t)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(unsigned long long *)args[0],
+ (int)*(unsigned long long *)args[1],
+ (int)*(unsigned long long *)args[2],
+ (int)*(unsigned long long *)args[3],
+ (int)*(unsigned long long *)args[4],
+ (int)*(unsigned long long *)args[5],
+ (int)*(unsigned long long *)args[6],
+ (int)*(unsigned long long *)args[7],
+ (int)*(unsigned long long *)args[8],
+ (int)*(unsigned long long *)args[9],
+ (int)*(unsigned long long *)args[10],
+ (int)*(unsigned long long *)args[11],
+ (int)*(unsigned long long *)args[12],
+ (int)*(unsigned long long *)args[13],
+ (int)*(unsigned long long *)args[14],
+ *(int *)args[15],
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[17];
+ int i, res;
+
+ for (i = 0; i < 15; i++) {
+ cl_arg_types[i] = &ffi_type_uint64;
+ }
+ cl_arg_types[15] = &ffi_type_sint;
+ cl_arg_types[16] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
+ (void *) 3 /* userdata */, code) == FFI_OK);
+
+ res = (*((closure_test_type0)code))
+ (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11LL, 12LL,
+ 13LL, 19LL, 21LL, 1);
+ /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 680" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn5.c b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn5.c
new file mode 100644
index 0000000000..99074426c6
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn5.c
@@ -0,0 +1,92 @@
+/* Area: closure_call
+ Purpose: Check multiple long long values passing.
+ Exceed the limit of gpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20031026 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_test_fn5(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
+ (int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] +
+ (int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] +
+ (int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] +
+ (int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] +
+ (int)*(int *)args[10] +
+ (int)*(unsigned long long *)args[11] +
+ (int)*(unsigned long long *)args[12] +
+ (int)*(unsigned long long *)args[13] +
+ (int)*(unsigned long long *)args[14] +
+ *(int *)args[15] + (intptr_t)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(unsigned long long *)args[0],
+ (int)*(unsigned long long *)args[1],
+ (int)*(unsigned long long *)args[2],
+ (int)*(unsigned long long *)args[3],
+ (int)*(unsigned long long *)args[4],
+ (int)*(unsigned long long *)args[5],
+ (int)*(unsigned long long *)args[6],
+ (int)*(unsigned long long *)args[7],
+ (int)*(unsigned long long *)args[8],
+ (int)*(unsigned long long *)args[9],
+ (int)*(int *)args[10],
+ (int)*(unsigned long long *)args[11],
+ (int)*(unsigned long long *)args[12],
+ (int)*(unsigned long long *)args[13],
+ (int)*(unsigned long long *)args[14],
+ *(int *)args[15],
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ int, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[17];
+ int i, res;
+
+ for (i = 0; i < 10; i++) {
+ cl_arg_types[i] = &ffi_type_uint64;
+ }
+ cl_arg_types[10] = &ffi_type_sint;
+ for (i = 11; i < 15; i++) {
+ cl_arg_types[i] = &ffi_type_uint64;
+ }
+ cl_arg_types[15] = &ffi_type_sint;
+ cl_arg_types[16] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn5,
+ (void *) 3 /* userdata */, code) == FFI_OK);
+
+ res = (*((closure_test_type0)code))
+ (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11, 12LL,
+ 13LL, 19LL, 21LL, 1);
+ /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 680" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn6.c b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn6.c
new file mode 100644
index 0000000000..73c54fd6b1
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_fn6.c
@@ -0,0 +1,90 @@
+/* Area: closure_call
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC.
+ Limitations: none.
+ PR: PR23404
+ Originator: <andreast@gcc.gnu.org> 20050830 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(unsigned long long *)args[0] +
+ (int)(*(unsigned long long *)args[1]) +
+ (int)(*(unsigned long long *)args[2]) +
+ (int)*(unsigned long long *)args[3] +
+ (int)(*(int *)args[4]) + (int)(*(double *)args[5]) +
+ (int)*(double *)args[6] + (int)(*(float *)args[7]) +
+ (int)(*(double *)args[8]) + (int)*(double *)args[9] +
+ (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+ (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+ (int)(*(double *)args[14]) + (int)*(double *)args[15] +
+ (intptr_t)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(unsigned long long *)args[0],
+ (int)(*(unsigned long long *)args[1]),
+ (int)(*(unsigned long long *)args[2]),
+ (int)*(unsigned long long *)args[3],
+ (int)(*(int *)args[4]), (int)(*(double *)args[5]),
+ (int)*(double *)args[6], (int)(*(float *)args[7]),
+ (int)(*(double *)args[8]), (int)*(double *)args[9],
+ (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+ (int)*(int *)args[12], (int)(*(int *)args[13]),
+ (int)(*(double *)args[14]), (int)(*(double *)args[15]),
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long,
+ unsigned long long,
+ unsigned long long,
+ unsigned long long,
+ int, double, double, float, double, double,
+ int, float, int, int, double, double);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[17];
+ int res;
+
+ cl_arg_types[0] = &ffi_type_uint64;
+ cl_arg_types[1] = &ffi_type_uint64;
+ cl_arg_types[2] = &ffi_type_uint64;
+ cl_arg_types[3] = &ffi_type_uint64;
+ cl_arg_types[4] = &ffi_type_sint;
+ cl_arg_types[5] = &ffi_type_double;
+ cl_arg_types[6] = &ffi_type_double;
+ cl_arg_types[7] = &ffi_type_float;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_double;
+ cl_arg_types[10] = &ffi_type_sint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_sint;
+ cl_arg_types[14] = &ffi_type_double;
+ cl_arg_types[15] = &ffi_type_double;
+ cl_arg_types[16] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
+ (void *) 3 /* userdata */, code) == FFI_OK);
+
+ res = (*((closure_test_type0)code))
+ (1, 2, 3, 4, 127, 429., 7., 8., 9.5, 10., 11, 12., 13,
+ 19, 21., 1.);
+ /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 680" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/closure_loc_fn0.c b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_loc_fn0.c
new file mode 100644
index 0000000000..b3afa0bbdf
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_loc_fn0.c
@@ -0,0 +1,95 @@
+/* Area: closure_call
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_loc_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
+ (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
+ (int)(*(signed short *)args[4]) +
+ (int)(*(unsigned long long *)args[5]) +
+ (int)*(int *)args[6] + (int)(*(int *)args[7]) +
+ (int)(*(double *)args[8]) + (int)*(int *)args[9] +
+ (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+ (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+ (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
+ (int)(*(unsigned long long *)args[2]),
+ (int)*(int *)args[3], (int)(*(signed short *)args[4]),
+ (int)(*(unsigned long long *)args[5]),
+ (int)*(int *)args[6], (int)(*(int *)args[7]),
+ (int)(*(double *)args[8]), (int)*(int *)args[9],
+ (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+ (int)*(int *)args[12], (int)(*(int *)args[13]),
+ (int)(*(int *)args[14]),*(int *)args[15],
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_loc_test_type0)(unsigned long long, int, unsigned long long,
+ int, signed short, unsigned long long, int,
+ int, double, int, int, float, int, int,
+ int, int);
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+ int res;
+ void *codeloc;
+
+ cl_arg_types[0] = &ffi_type_uint64;
+ cl_arg_types[1] = &ffi_type_sint;
+ cl_arg_types[2] = &ffi_type_uint64;
+ cl_arg_types[3] = &ffi_type_sint;
+ cl_arg_types[4] = &ffi_type_sshort;
+ cl_arg_types[5] = &ffi_type_uint64;
+ cl_arg_types[6] = &ffi_type_sint;
+ cl_arg_types[7] = &ffi_type_sint;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_sint;
+ cl_arg_types[10] = &ffi_type_sint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_sint;
+ cl_arg_types[14] = &ffi_type_sint;
+ cl_arg_types[15] = &ffi_type_sint;
+ cl_arg_types[16] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ pcl = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
+ CHECK(pcl != NULL);
+ CHECK(codeloc != NULL);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_loc_test_fn0,
+ (void *) 3 /* userdata */, codeloc) == FFI_OK);
+
+ CHECK(memcmp(pcl, codeloc, sizeof(*pcl)) == 0);
+
+ res = (*((closure_loc_test_type0)codeloc))
+ (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
+ 19, 21, 1);
+ /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 680" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/closure_simple.c b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_simple.c
new file mode 100644
index 0000000000..5a4e728d4a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/closure_simple.c
@@ -0,0 +1,55 @@
+/* Area: closure_call
+ Purpose: Check simple closure handling with all ABIs
+ Limitations: none.
+ PR: none.
+ Originator: <twalljava@dev.java.net> */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_test(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(int *)args[0] + (int)(*(int *)args[1])
+ + (int)(*(int *)args[2]) + (int)(*(int *)args[3])
+ + (int)(intptr_t)userdata;
+
+ printf("%d %d %d %d: %d\n",
+ (int)*(int *)args[0], (int)(*(int *)args[1]),
+ (int)(*(int *)args[2]), (int)(*(int *)args[3]),
+ (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (ABI_ATTR *closure_test_type0)(int, int, int, int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[17];
+ int res;
+
+ cl_arg_types[0] = &ffi_type_uint;
+ cl_arg_types[1] = &ffi_type_uint;
+ cl_arg_types[2] = &ffi_type_uint;
+ cl_arg_types[3] = &ffi_type_uint;
+ cl_arg_types[4] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 4,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test,
+ (void *) 3 /* userdata */, code) == FFI_OK);
+
+ res = (*(closure_test_type0)code)(0, 1, 2, 3);
+ /* { dg-output "0 1 2 3: 9" } */
+
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 9" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_12byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_12byte.c
new file mode 100644
index 0000000000..ea0825d175
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_12byte.c
@@ -0,0 +1,94 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_12byte {
+ int a;
+ int b;
+ int c;
+} cls_struct_12byte;
+
+cls_struct_12byte cls_struct_12byte_fn(struct cls_struct_12byte b1,
+ struct cls_struct_12byte b2)
+{
+ struct cls_struct_12byte result;
+
+ result.a = b1.a + b2.a;
+ result.b = b1.b + b2.b;
+ result.c = b1.c + b2.c;
+
+ printf("%d %d %d %d %d %d: %d %d %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
+ result.a, result.b, result.c);
+
+ return result;
+}
+
+static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args , void* userdata __UNUSED__)
+{
+ struct cls_struct_12byte b1, b2;
+
+ b1 = *(struct cls_struct_12byte*)(args[0]);
+ b2 = *(struct cls_struct_12byte*)(args[1]);
+
+ *(cls_struct_12byte*)resp = cls_struct_12byte_fn(b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_12byte h_dbl = { 7, 4, 9 };
+ struct cls_struct_12byte j_dbl = { 1, 5, 3 };
+ struct cls_struct_12byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_sint;
+ cls_struct_fields[1] = &ffi_type_sint;
+ cls_struct_fields[2] = &ffi_type_sint;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &h_dbl;
+ args_dbl[1] = &j_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_12byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "7 4 9 1 5 3: 8 9 12" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 8 9 12" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_12byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl.a = 0;
+ res_dbl.b = 0;
+ res_dbl.c = 0;
+
+ res_dbl = ((cls_struct_12byte(*)(cls_struct_12byte, cls_struct_12byte))(code))(h_dbl, j_dbl);
+ /* { dg-output "\n7 4 9 1 5 3: 8 9 12" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 8 9 12" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_16byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_16byte.c
new file mode 100644
index 0000000000..89a08a2d97
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_16byte.c
@@ -0,0 +1,95 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_16byte {
+ int a;
+ double b;
+ int c;
+} cls_struct_16byte;
+
+cls_struct_16byte cls_struct_16byte_fn(struct cls_struct_16byte b1,
+ struct cls_struct_16byte b2)
+{
+ struct cls_struct_16byte result;
+
+ result.a = b1.a + b2.a;
+ result.b = b1.b + b2.b;
+ result.c = b1.c + b2.c;
+
+ printf("%d %g %d %d %g %d: %d %g %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
+ result.a, result.b, result.c);
+
+ return result;
+}
+
+static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ struct cls_struct_16byte b1, b2;
+
+ b1 = *(struct cls_struct_16byte*)(args[0]);
+ b2 = *(struct cls_struct_16byte*)(args[1]);
+
+ *(cls_struct_16byte*)resp = cls_struct_16byte_fn(b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
+ struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
+ struct cls_struct_16byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_sint;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_sint;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &h_dbl;
+ args_dbl[1] = &j_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_16byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "7 8 9 1 9 3: 8 17 12" } */
+ printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 8 17 12" } */
+
+ res_dbl.a = 0;
+ res_dbl.b = 0.0;
+ res_dbl.c = 0;
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_16byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(code))(h_dbl, j_dbl);
+ /* { dg-output "\n7 8 9 1 9 3: 8 17 12" } */
+ printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 8 17 12" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_18byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_18byte.c
new file mode 100644
index 0000000000..9f75da80aa
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_18byte.c
@@ -0,0 +1,96 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Double alignment check on darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030915 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_18byte {
+ double a;
+ unsigned char b;
+ unsigned char c;
+ double d;
+} cls_struct_18byte;
+
+cls_struct_18byte cls_struct_18byte_fn(struct cls_struct_18byte a1,
+ struct cls_struct_18byte a2)
+{
+ struct cls_struct_18byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+
+
+ printf("%g %d %d %g %g %d %d %g: %g %d %d %g\n", a1.a, a1.b, a1.c, a1.d,
+ a2.a, a2.b, a2.c, a2.d,
+ result.a, result.b, result.c, result.d);
+ return result;
+}
+
+static void
+cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_18byte a1, a2;
+
+ a1 = *(struct cls_struct_18byte*)(args[0]);
+ a2 = *(struct cls_struct_18byte*)(args[1]);
+
+ *(cls_struct_18byte*)resp = cls_struct_18byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[5];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+ struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
+ struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
+ struct cls_struct_18byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_18byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 127 126 3 4 125 124 5: 5 252 250 8" } */
+ printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 5 252 250 8" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_18byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_18byte(*)(cls_struct_18byte, cls_struct_18byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n1 127 126 3 4 125 124 5: 5 252 250 8" } */
+ printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 5 252 250 8" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_19byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_19byte.c
new file mode 100644
index 0000000000..278794b5b8
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_19byte.c
@@ -0,0 +1,102 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Double alignment check on darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030915 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_19byte {
+ double a;
+ unsigned char b;
+ unsigned char c;
+ double d;
+ unsigned char e;
+} cls_struct_19byte;
+
+cls_struct_19byte cls_struct_19byte_fn(struct cls_struct_19byte a1,
+ struct cls_struct_19byte a2)
+{
+ struct cls_struct_19byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+ result.e = a1.e + a2.e;
+
+
+ printf("%g %d %d %g %d %g %d %d %g %d: %g %d %d %g %d\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e,
+ a2.a, a2.b, a2.c, a2.d, a2.e,
+ result.a, result.b, result.c, result.d, result.e);
+ return result;
+}
+
+static void
+cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_19byte a1, a2;
+
+ a1 = *(struct cls_struct_19byte*)(args[0]);
+ a2 = *(struct cls_struct_19byte*)(args[1]);
+
+ *(cls_struct_19byte*)resp = cls_struct_19byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[6];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+ struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
+ struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
+ struct cls_struct_19byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_uchar;
+ cls_struct_fields[5] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_19byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
+ printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e);
+ /* { dg-output "\nres: 5 252 250 8 239" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_19byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_19byte(*)(cls_struct_19byte, cls_struct_19byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
+ printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e);
+ /* { dg-output "\nres: 5 252 250 8 239" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_1_1byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_1_1byte.c
new file mode 100644
index 0000000000..82492c020e
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_1_1byte.c
@@ -0,0 +1,89 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030902 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_1_1byte {
+ unsigned char a;
+} cls_struct_1_1byte;
+
+cls_struct_1_1byte cls_struct_1_1byte_fn(struct cls_struct_1_1byte a1,
+ struct cls_struct_1_1byte a2)
+{
+ struct cls_struct_1_1byte result;
+
+ result.a = a1.a + a2.a;
+
+ printf("%d %d: %d\n", a1.a, a2.a, result.a);
+
+ return result;
+}
+
+static void
+cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_1_1byte a1, a2;
+
+ a1 = *(struct cls_struct_1_1byte*)(args[0]);
+ a2 = *(struct cls_struct_1_1byte*)(args[1]);
+
+ *(cls_struct_1_1byte*)resp = cls_struct_1_1byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[2];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_1_1byte g_dbl = { 12 };
+ struct cls_struct_1_1byte f_dbl = { 178 };
+ struct cls_struct_1_1byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_1_1byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 178: 190" } */
+ printf("res: %d\n", res_dbl.a);
+ /* { dg-output "\nres: 190" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_1_1byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 178: 190" } */
+ printf("res: %d\n", res_dbl.a);
+ /* { dg-output "\nres: 190" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_20byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_20byte.c
new file mode 100644
index 0000000000..3f8bb28ad2
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_20byte.c
@@ -0,0 +1,91 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_20byte {
+ double a;
+ double b;
+ int c;
+} cls_struct_20byte;
+
+cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
+ struct cls_struct_20byte a2)
+{
+ struct cls_struct_20byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%g %g %d %g %g %d: %g %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
+ result.a, result.b, result.c);
+ return result;
+}
+
+static void
+cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_20byte a1, a2;
+
+ a1 = *(struct cls_struct_20byte*)(args[0]);
+ a2 = *(struct cls_struct_20byte*)(args[1]);
+
+ *(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
+ struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
+ struct cls_struct_20byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_sint;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 3 4 5 7: 5 7 10" } */
+ printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 5 7 10" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
+ printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 5 7 10" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_20byte1.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_20byte1.c
new file mode 100644
index 0000000000..65627273c8
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_20byte1.c
@@ -0,0 +1,93 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_20byte {
+ int a;
+ double b;
+ double c;
+} cls_struct_20byte;
+
+cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
+ struct cls_struct_20byte a2)
+{
+ struct cls_struct_20byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %g %g %d %g %g: %d %g %g\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
+ result.a, result.b, result.c);
+ return result;
+}
+
+static void
+cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_20byte a1, a2;
+
+ a1 = *(struct cls_struct_20byte*)(args[0]);
+ a2 = *(struct cls_struct_20byte*)(args[1]);
+
+ *(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+ struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
+ struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
+ struct cls_struct_20byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_sint;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 3 4 5 7: 5 7 10" } */
+ printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 5 7 10" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
+ printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 5 7 10" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_24byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_24byte.c
new file mode 100644
index 0000000000..1d82f6e4a4
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_24byte.c
@@ -0,0 +1,113 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_24byte {
+ double a;
+ double b;
+ int c;
+ float d;
+} cls_struct_24byte;
+
+cls_struct_24byte cls_struct_24byte_fn(struct cls_struct_24byte b0,
+ struct cls_struct_24byte b1,
+ struct cls_struct_24byte b2,
+ struct cls_struct_24byte b3)
+{
+ struct cls_struct_24byte result;
+
+ result.a = b0.a + b1.a + b2.a + b3.a;
+ result.b = b0.b + b1.b + b2.b + b3.b;
+ result.c = b0.c + b1.c + b2.c + b3.c;
+ result.d = b0.d + b1.d + b2.d + b3.d;
+
+ printf("%g %g %d %g %g %g %d %g %g %g %d %g %g %g %d %g: %g %g %d %g\n",
+ b0.a, b0.b, b0.c, b0.d,
+ b1.a, b1.b, b1.c, b1.d,
+ b2.a, b2.b, b2.c, b2.d,
+ b3.a, b3.b, b3.c, b2.d,
+ result.a, result.b, result.c, result.d);
+
+ return result;
+}
+
+static void
+cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_24byte b0, b1, b2, b3;
+
+ b0 = *(struct cls_struct_24byte*)(args[0]);
+ b1 = *(struct cls_struct_24byte*)(args[1]);
+ b2 = *(struct cls_struct_24byte*)(args[2]);
+ b3 = *(struct cls_struct_24byte*)(args[3]);
+
+ *(cls_struct_24byte*)resp = cls_struct_24byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[5];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 };
+ struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 };
+ struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 };
+ struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 };
+ struct cls_struct_24byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_sint;
+ cls_struct_fields[3] = &ffi_type_float;
+ cls_struct_fields[4] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = &cls_struct_type;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_24byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
+ printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 22 15 17 25" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_24byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_24byte(*)(cls_struct_24byte,
+ cls_struct_24byte,
+ cls_struct_24byte,
+ cls_struct_24byte))
+ (code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
+ printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 22 15 17 25" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_2byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_2byte.c
new file mode 100644
index 0000000000..81bb0a64a3
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_2byte.c
@@ -0,0 +1,90 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_2byte {
+ unsigned char a;
+ unsigned char b;
+} cls_struct_2byte;
+
+cls_struct_2byte cls_struct_2byte_fn(struct cls_struct_2byte a1,
+ struct cls_struct_2byte a2)
+{
+ struct cls_struct_2byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+
+ printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+ return result;
+}
+
+static void
+cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_2byte a1, a2;
+
+ a1 = *(struct cls_struct_2byte*)(args[0]);
+ a2 = *(struct cls_struct_2byte*)(args[1]);
+
+ *(cls_struct_2byte*)resp = cls_struct_2byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_2byte g_dbl = { 12, 127 };
+ struct cls_struct_2byte f_dbl = { 1, 13 };
+ struct cls_struct_2byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_2byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 127 1 13: 13 140" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 13 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_2byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_2byte(*)(cls_struct_2byte, cls_struct_2byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 127 1 13: 13 140" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 13 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3_1byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3_1byte.c
new file mode 100644
index 0000000000..b7827466f6
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3_1byte.c
@@ -0,0 +1,95 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030902 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_3_1byte {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+} cls_struct_3_1byte;
+
+cls_struct_3_1byte cls_struct_3_1byte_fn(struct cls_struct_3_1byte a1,
+ struct cls_struct_3_1byte a2)
+{
+ struct cls_struct_3_1byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
+ a2.a, a2.b, a2.c,
+ result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_3_1byte a1, a2;
+
+ a1 = *(struct cls_struct_3_1byte*)(args[0]);
+ a2 = *(struct cls_struct_3_1byte*)(args[1]);
+
+ *(cls_struct_3_1byte*)resp = cls_struct_3_1byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
+ struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
+ struct cls_struct_3_1byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_3_1byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 13 14 178 179 180: 190 192 194" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 190 192 194" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3_1byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_3_1byte(*)(cls_struct_3_1byte, cls_struct_3_1byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 13 14 178 179 180: 190 192 194" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 190 192 194" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3byte1.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3byte1.c
new file mode 100644
index 0000000000..a02c463af9
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3byte1.c
@@ -0,0 +1,90 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_3byte {
+ unsigned short a;
+ unsigned char b;
+} cls_struct_3byte;
+
+cls_struct_3byte cls_struct_3byte_fn(struct cls_struct_3byte a1,
+ struct cls_struct_3byte a2)
+{
+ struct cls_struct_3byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+
+ printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+ return result;
+}
+
+static void
+cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_3byte a1, a2;
+
+ a1 = *(struct cls_struct_3byte*)(args[0]);
+ a2 = *(struct cls_struct_3byte*)(args[1]);
+
+ *(cls_struct_3byte*)resp = cls_struct_3byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_3byte g_dbl = { 12, 119 };
+ struct cls_struct_3byte f_dbl = { 1, 15 };
+ struct cls_struct_3byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_ushort;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_3byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 119 1 15: 13 134" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 13 134" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 119 1 15: 13 134" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 13 134" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3byte2.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3byte2.c
new file mode 100644
index 0000000000..c7251cead6
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3byte2.c
@@ -0,0 +1,90 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_3byte_1 {
+ unsigned char a;
+ unsigned short b;
+} cls_struct_3byte_1;
+
+cls_struct_3byte_1 cls_struct_3byte_fn1(struct cls_struct_3byte_1 a1,
+ struct cls_struct_3byte_1 a2)
+{
+ struct cls_struct_3byte_1 result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+
+ printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+ return result;
+}
+
+static void
+cls_struct_3byte_gn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_3byte_1 a1, a2;
+
+ a1 = *(struct cls_struct_3byte_1*)(args[0]);
+ a2 = *(struct cls_struct_3byte_1*)(args[1]);
+
+ *(cls_struct_3byte_1*)resp = cls_struct_3byte_fn1(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_3byte_1 g_dbl = { 15, 125 };
+ struct cls_struct_3byte_1 f_dbl = { 9, 19 };
+ struct cls_struct_3byte_1 res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_3byte_fn1), &res_dbl, args_dbl);
+ /* { dg-output "15 125 9 19: 24 144" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 24 144" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn1, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n15 125 9 19: 24 144" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 24 144" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3float.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3float.c
new file mode 100644
index 0000000000..48888f8405
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_3float.c
@@ -0,0 +1,95 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations:>none.
+ PR: none.
+ Originator: <compnerd@compnerd.org> 20171026 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_3float {
+ float f;
+ float g;
+ float h;
+} cls_struct_3float;
+
+cls_struct_3float cls_struct_3float_fn(struct cls_struct_3float a1,
+ struct cls_struct_3float a2)
+{
+ struct cls_struct_3float result;
+
+ result.f = a1.f + a2.f;
+ result.g = a1.g + a2.g;
+ result.h = a1.h + a2.h;
+
+ printf("%g %g %g %g %g %g: %g %g %g\n", a1.f, a1.g, a1.h,
+ a2.f, a2.g, a2.h, result.f, result.g, result.h);
+
+ return result;
+}
+
+static void
+cls_struct_3float_gn(ffi_cif *cif __UNUSED__, void* resp, void **args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_3float a1, a2;
+
+ a1 = *(struct cls_struct_3float*)(args[0]);
+ a2 = *(struct cls_struct_3float*)(args[1]);
+
+ *(cls_struct_3float*)resp = cls_struct_3float_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void *args_dbl[3];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+ struct cls_struct_3float g_dbl = { 1.0f, 2.0f, 3.0f };
+ struct cls_struct_3float f_dbl = { 1.0f, 2.0f, 3.0f };
+ struct cls_struct_3float res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_float;
+ cls_struct_fields[1] = &ffi_type_float;
+ cls_struct_fields[2] = &ffi_type_float;
+ cls_struct_fields[3] = NULL;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_3float_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 3 1 2 3: 2 4 6" } */
+ printf("res: %g %g %g\n", res_dbl.f, res_dbl.g, res_dbl.h);
+ /* { dg-output "\nres: 2 4 6" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3float_gn, NULL, code) ==
+ FFI_OK);
+
+ res_dbl = ((cls_struct_3float(*)(cls_struct_3float,
+ cls_struct_3float))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */
+ printf("res: %g %g %g\n", res_dbl.f, res_dbl.g, res_dbl.h);
+ /* { dg-output "\nres: 2 4 6" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_4_1byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_4_1byte.c
new file mode 100644
index 0000000000..2d6d8b622c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_4_1byte.c
@@ -0,0 +1,98 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030902 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_4_1byte {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+ unsigned char d;
+} cls_struct_4_1byte;
+
+cls_struct_4_1byte cls_struct_4_1byte_fn(struct cls_struct_4_1byte a1,
+ struct cls_struct_4_1byte a2)
+{
+ struct cls_struct_4_1byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+
+ printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
+ a2.a, a2.b, a2.c, a2.d,
+ result.a, result.b, result.c, result.d);
+
+ return result;
+}
+
+static void
+cls_struct_4_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_4_1byte a1, a2;
+
+ a1 = *(struct cls_struct_4_1byte*)(args[0]);
+ a2 = *(struct cls_struct_4_1byte*)(args[1]);
+
+ *(cls_struct_4_1byte*)resp = cls_struct_4_1byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[5];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
+ struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
+ struct cls_struct_4_1byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_uchar;
+ cls_struct_fields[4] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_4_1byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 13 14 15 178 179 180 181: 190 192 194 196" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 190 192 194 196" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4_1byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 13 14 15 178 179 180 181: 190 192 194 196" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 190 192 194 196" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_4byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_4byte.c
new file mode 100644
index 0000000000..4ac378776b
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_4byte.c
@@ -0,0 +1,90 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_4byte {
+ unsigned short a;
+ unsigned short b;
+} cls_struct_4byte;
+
+cls_struct_4byte cls_struct_4byte_fn(struct cls_struct_4byte a1,
+ struct cls_struct_4byte a2)
+{
+ struct cls_struct_4byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+
+ printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+ return result;
+}
+
+static void
+cls_struct_4byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_4byte a1, a2;
+
+ a1 = *(struct cls_struct_4byte*)(args[0]);
+ a2 = *(struct cls_struct_4byte*)(args[1]);
+
+ *(cls_struct_4byte*)resp = cls_struct_4byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_4byte g_dbl = { 127, 120 };
+ struct cls_struct_4byte f_dbl = { 12, 128 };
+ struct cls_struct_4byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_ushort;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_4byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 12 128: 139 248" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 139 248" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_4byte(*)(cls_struct_4byte, cls_struct_4byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 12 128: 139 248" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 139 248" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_5_1_byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_5_1_byte.c
new file mode 100644
index 0000000000..ad9d51c248
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_5_1_byte.c
@@ -0,0 +1,109 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050708 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_5byte {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+ unsigned char d;
+ unsigned char e;
+} cls_struct_5byte;
+
+cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
+ struct cls_struct_5byte a2)
+{
+ struct cls_struct_5byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+ result.e = a1.e + a2.e;
+
+ printf("%d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e,
+ a2.a, a2.b, a2.c, a2.d, a2.e,
+ result.a, result.b, result.c, result.d, result.e);
+
+ return result;
+}
+
+static void
+cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_5byte a1, a2;
+
+ a1 = *(struct cls_struct_5byte*)(args[0]);
+ a2 = *(struct cls_struct_5byte*)(args[1]);
+
+ *(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[6];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 };
+ struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 };
+ struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 };
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_uchar;
+ cls_struct_fields[4] = &ffi_type_uchar;
+ cls_struct_fields[5] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
+ printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e);
+ /* { dg-output "\nres: 139 248 10 6 8" } */
+
+ res_dbl.a = 0;
+ res_dbl.b = 0;
+ res_dbl.c = 0;
+ res_dbl.d = 0;
+ res_dbl.e = 0;
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
+ printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e);
+ /* { dg-output "\nres: 139 248 10 6 8" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_5byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_5byte.c
new file mode 100644
index 0000000000..4e0c0003c0
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_5byte.c
@@ -0,0 +1,98 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_5byte {
+ unsigned short a;
+ unsigned short b;
+ unsigned char c;
+} cls_struct_5byte;
+
+cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
+ struct cls_struct_5byte a2)
+{
+ struct cls_struct_5byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
+ a2.a, a2.b, a2.c,
+ result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_5byte a1, a2;
+
+ a1 = *(struct cls_struct_5byte*)(args[0]);
+ a2 = *(struct cls_struct_5byte*)(args[1]);
+
+ *(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_5byte g_dbl = { 127, 120, 1 };
+ struct cls_struct_5byte f_dbl = { 12, 128, 9 };
+ struct cls_struct_5byte res_dbl = { 0, 0, 0 };
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_ushort;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 12 128 9: 139 248 10" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 139 248 10" } */
+
+ res_dbl.a = 0;
+ res_dbl.b = 0;
+ res_dbl.c = 0;
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 12 128 9: 139 248 10" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 139 248 10" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_64byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_64byte.c
new file mode 100644
index 0000000000..a55edc2c7b
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_64byte.c
@@ -0,0 +1,124 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check bigger struct which overlaps
+ the gp and fp register count on Darwin/AIX/ppc64.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_64byte {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+} cls_struct_64byte;
+
+cls_struct_64byte cls_struct_64byte_fn(struct cls_struct_64byte b0,
+ struct cls_struct_64byte b1,
+ struct cls_struct_64byte b2,
+ struct cls_struct_64byte b3)
+{
+ struct cls_struct_64byte result;
+
+ result.a = b0.a + b1.a + b2.a + b3.a;
+ result.b = b0.b + b1.b + b2.b + b3.b;
+ result.c = b0.c + b1.c + b2.c + b3.c;
+ result.d = b0.d + b1.d + b2.d + b3.d;
+ result.e = b0.e + b1.e + b2.e + b3.e;
+ result.f = b0.f + b1.f + b2.f + b3.f;
+ result.g = b0.g + b1.g + b2.g + b3.g;
+ result.h = b0.h + b1.h + b2.h + b3.h;
+
+ printf("%g %g %g %g %g %g %g %g\n", result.a, result.b, result.c,
+ result.d, result.e, result.f, result.g, result.h);
+
+ return result;
+}
+
+static void
+cls_struct_64byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_64byte b0, b1, b2, b3;
+
+ b0 = *(struct cls_struct_64byte*)(args[0]);
+ b1 = *(struct cls_struct_64byte*)(args[1]);
+ b2 = *(struct cls_struct_64byte*)(args[2]);
+ b3 = *(struct cls_struct_64byte*)(args[3]);
+
+ *(cls_struct_64byte*)resp = cls_struct_64byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[9];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_64byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0 };
+ struct cls_struct_64byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0 };
+ struct cls_struct_64byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0 };
+ struct cls_struct_64byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 };
+ struct cls_struct_64byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_double;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_double;
+ cls_struct_fields[7] = &ffi_type_double;
+ cls_struct_fields[8] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = &cls_struct_type;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_64byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "22 15 17 25 6 13 19 18" } */
+ printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_64byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_64byte(*)(cls_struct_64byte,
+ cls_struct_64byte,
+ cls_struct_64byte,
+ cls_struct_64byte))
+ (code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n22 15 17 25 6 13 19 18" } */
+ printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_6_1_byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_6_1_byte.c
new file mode 100644
index 0000000000..b4dcdba472
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_6_1_byte.c
@@ -0,0 +1,113 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050708 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_6byte {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+ unsigned char d;
+ unsigned char e;
+ unsigned char f;
+} cls_struct_6byte;
+
+cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
+ struct cls_struct_6byte a2)
+{
+ struct cls_struct_6byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+ result.e = a1.e + a2.e;
+ result.f = a1.f + a2.f;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e, a1.f,
+ a2.a, a2.b, a2.c, a2.d, a2.e, a2.f,
+ result.a, result.b, result.c, result.d, result.e, result.f);
+
+ return result;
+}
+
+static void
+cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_6byte a1, a2;
+
+ a1 = *(struct cls_struct_6byte*)(args[0]);
+ a2 = *(struct cls_struct_6byte*)(args[1]);
+
+ *(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[7];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 };
+ struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 };
+ struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 };
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_uchar;
+ cls_struct_fields[4] = &ffi_type_uchar;
+ cls_struct_fields[5] = &ffi_type_uchar;
+ cls_struct_fields[6] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
+ printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f);
+ /* { dg-output "\nres: 139 248 10 6 8 10" } */
+
+ res_dbl.a = 0;
+ res_dbl.b = 0;
+ res_dbl.c = 0;
+ res_dbl.d = 0;
+ res_dbl.e = 0;
+ res_dbl.f = 0;
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
+ printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f);
+ /* { dg-output "\nres: 139 248 10 6 8 10" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_6byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_6byte.c
new file mode 100644
index 0000000000..740678017b
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_6byte.c
@@ -0,0 +1,99 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_6byte {
+ unsigned short a;
+ unsigned short b;
+ unsigned char c;
+ unsigned char d;
+} cls_struct_6byte;
+
+cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
+ struct cls_struct_6byte a2)
+{
+ struct cls_struct_6byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+
+ printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
+ a2.a, a2.b, a2.c, a2.d,
+ result.a, result.b, result.c, result.d);
+
+ return result;
+}
+
+static void
+cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_6byte a1, a2;
+
+ a1 = *(struct cls_struct_6byte*)(args[0]);
+ a2 = *(struct cls_struct_6byte*)(args[1]);
+
+ *(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[5];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 };
+ struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 };
+ struct cls_struct_6byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_ushort;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_uchar;
+ cls_struct_fields[4] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 128 12 128 9 127: 139 248 10 255" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 139 248 10 255" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 128 12 128 9 127: 139 248 10 255" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 139 248 10 255" } */
+
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_7_1_byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_7_1_byte.c
new file mode 100644
index 0000000000..14a7e96f9d
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_7_1_byte.c
@@ -0,0 +1,117 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050708 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_7byte {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+ unsigned char d;
+ unsigned char e;
+ unsigned char f;
+ unsigned char g;
+} cls_struct_7byte;
+
+cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
+ struct cls_struct_7byte a2)
+{
+ struct cls_struct_7byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+ result.e = a1.e + a2.e;
+ result.f = a1.f + a2.f;
+ result.g = a1.g + a2.g;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d %d\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+ a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
+ result.a, result.b, result.c, result.d, result.e, result.f, result.g);
+
+ return result;
+}
+
+static void
+cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_7byte a1, a2;
+
+ a1 = *(struct cls_struct_7byte*)(args[0]);
+ a2 = *(struct cls_struct_7byte*)(args[1]);
+
+ *(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[8];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 };
+ struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 };
+ struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 };
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_uchar;
+ cls_struct_fields[4] = &ffi_type_uchar;
+ cls_struct_fields[5] = &ffi_type_uchar;
+ cls_struct_fields[6] = &ffi_type_uchar;
+ cls_struct_fields[7] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
+ printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 139 248 10 6 8 10 12" } */
+
+ res_dbl.a = 0;
+ res_dbl.b = 0;
+ res_dbl.c = 0;
+ res_dbl.d = 0;
+ res_dbl.e = 0;
+ res_dbl.f = 0;
+ res_dbl.g = 0;
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
+ printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 139 248 10 6 8 10 12" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_7byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_7byte.c
new file mode 100644
index 0000000000..1645cc635f
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_7byte.c
@@ -0,0 +1,97 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_7byte {
+ unsigned short a;
+ unsigned short b;
+ unsigned char c;
+ unsigned short d;
+} cls_struct_7byte;
+
+cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
+ struct cls_struct_7byte a2)
+{
+ struct cls_struct_7byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+
+ printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
+ a2.a, a2.b, a2.c, a2.d,
+ result.a, result.b, result.c, result.d);
+
+ return result;
+}
+
+static void
+cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_7byte a1, a2;
+
+ a1 = *(struct cls_struct_7byte*)(args[0]);
+ a2 = *(struct cls_struct_7byte*)(args[1]);
+
+ *(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[5];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
+ struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
+ struct cls_struct_7byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_ushort;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_ushort;
+ cls_struct_fields[4] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 254 12 128 9 255: 139 248 10 509" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 139 248 10 509" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 254 12 128 9 255: 139 248 10 509" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 139 248 10 509" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_8byte.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_8byte.c
new file mode 100644
index 0000000000..f6c1ea570a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_8byte.c
@@ -0,0 +1,88 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_8byte {
+ int a;
+ float b;
+} cls_struct_8byte;
+
+cls_struct_8byte cls_struct_8byte_fn(struct cls_struct_8byte a1,
+ struct cls_struct_8byte a2)
+{
+ struct cls_struct_8byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+
+ printf("%d %g %d %g: %d %g\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+ return result;
+}
+
+static void
+cls_struct_8byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_8byte a1, a2;
+
+ a1 = *(struct cls_struct_8byte*)(args[0]);
+ a2 = *(struct cls_struct_8byte*)(args[1]);
+
+ *(cls_struct_8byte*)resp = cls_struct_8byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_8byte g_dbl = { 1, 2.0 };
+ struct cls_struct_8byte f_dbl = { 4, 5.0 };
+ struct cls_struct_8byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_sint;
+ cls_struct_fields[1] = &ffi_type_float;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_8byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 4 5: 5 7" } */
+ printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 5 7" } */
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_8byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_8byte(*)(cls_struct_8byte, cls_struct_8byte))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 4 5: 5 7" } */
+ printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 5 7" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_9byte1.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_9byte1.c
new file mode 100644
index 0000000000..0b8572223c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_9byte1.c
@@ -0,0 +1,90 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Darwin/AIX do double-word
+ alignment of the struct if the first element is a double.
+ Check that it does not here.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030914 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_9byte {
+ int a;
+ double b;
+} cls_struct_9byte;
+
+cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
+ struct cls_struct_9byte b2)
+{
+ struct cls_struct_9byte result;
+
+ result.a = b1.a + b2.a;
+ result.b = b1.b + b2.b;
+
+ printf("%d %g %d %g: %d %g\n", b1.a, b1.b, b2.a, b2.b,
+ result.a, result.b);
+
+ return result;
+}
+
+static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ struct cls_struct_9byte b1, b2;
+
+ b1 = *(struct cls_struct_9byte*)(args[0]);
+ b2 = *(struct cls_struct_9byte*)(args[1]);
+
+ *(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[3];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+ struct cls_struct_9byte h_dbl = { 7, 8.0};
+ struct cls_struct_9byte j_dbl = { 1, 9.0};
+ struct cls_struct_9byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_sint;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &h_dbl;
+ args_dbl[1] = &j_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "7 8 1 9: 8 17" } */
+ printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 8 17" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
+ /* { dg-output "\n7 8 1 9: 8 17" } */
+ printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 8 17" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_9byte2.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_9byte2.c
new file mode 100644
index 0000000000..edf991de73
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_9byte2.c
@@ -0,0 +1,91 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Darwin/AIX do double-word
+ alignment of the struct if the first element is a double.
+ Check that it does here.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030914 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_9byte {
+ double a;
+ int b;
+} cls_struct_9byte;
+
+cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
+ struct cls_struct_9byte b2)
+{
+ struct cls_struct_9byte result;
+
+ result.a = b1.a + b2.a;
+ result.b = b1.b + b2.b;
+
+ printf("%g %d %g %d: %g %d\n", b1.a, b1.b, b2.a, b2.b,
+ result.a, result.b);
+
+ return result;
+}
+
+static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ struct cls_struct_9byte b1, b2;
+
+ b1 = *(struct cls_struct_9byte*)(args[0]);
+ b2 = *(struct cls_struct_9byte*)(args[1]);
+
+ *(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[3];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+ struct cls_struct_9byte h_dbl = { 7.0, 8};
+ struct cls_struct_9byte j_dbl = { 1.0, 9};
+ struct cls_struct_9byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_sint;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &h_dbl;
+ args_dbl[1] = &j_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "7 8 1 9: 8 17" } */
+ printf("res: %g %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 8 17" } */
+
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
+ /* { dg-output "\n7 8 1 9: 8 17" } */
+ printf("res: %g %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 8 17" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_double.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_double.c
new file mode 100644
index 0000000000..aad5f3ced6
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_double.c
@@ -0,0 +1,93 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of double.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ double b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+ struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_float.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_float.c
new file mode 100644
index 0000000000..37e085529e
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_float.c
@@ -0,0 +1,91 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of float.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ float b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+ struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_float;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble.c
new file mode 100644
index 0000000000..b3322d8615
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble.c
@@ -0,0 +1,92 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of long double.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ long double b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+ struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_longdouble;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble_split.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble_split.c
new file mode 100644
index 0000000000..cc1c43b8ca
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble_split.c
@@ -0,0 +1,132 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of long double.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ long double a;
+ long double b;
+ long double c;
+ long double d;
+ long double e;
+ long double f;
+ long double g;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(
+ cls_struct_align a1,
+ cls_struct_align a2)
+{
+ struct cls_struct_align r;
+
+ r.a = a1.a + a2.a;
+ r.b = a1.b + a2.b;
+ r.c = a1.c + a2.c;
+ r.d = a1.d + a2.d;
+ r.e = a1.e + a2.e;
+ r.f = a1.f + a2.f;
+ r.g = a1.g + a2.g;
+
+ printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
+ "%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+ a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
+ r.a, r.b, r.c, r.d, r.e, r.f, r.g);
+
+ return r;
+}
+
+cls_struct_align cls_struct_align_fn2(
+ cls_struct_align a1)
+{
+ struct cls_struct_align r;
+
+ r.a = a1.a + 1;
+ r.b = a1.b + 1;
+ r.c = a1.c + 1;
+ r.d = a1.d + 1;
+ r.e = a1.e + 1;
+ r.f = a1.f + 1;
+ r.g = a1.g + 1;
+
+ printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
+ "%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+ r.a, r.b, r.c, r.d, r.e, r.f, r.g);
+
+ return r;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[8];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+ struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
+ struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_longdouble;
+ cls_struct_fields[1] = &ffi_type_longdouble;
+ cls_struct_fields[2] = &ffi_type_longdouble;
+ cls_struct_fields[3] = &ffi_type_longdouble;
+ cls_struct_fields[4] = &ffi_type_longdouble;
+ cls_struct_fields[5] = &ffi_type_longdouble;
+ cls_struct_fields[6] = &ffi_type_longdouble;
+ cls_struct_fields[7] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+ printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+ printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble_split2.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble_split2.c
new file mode 100644
index 0000000000..5d3bec0719
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_longdouble_split2.c
@@ -0,0 +1,115 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of long double.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/18/2007
+*/
+
+/* { dg-do run { xfail strongarm*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ long double a;
+ long double b;
+ long double c;
+ long double d;
+ long double e;
+ double f;
+ long double g;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(
+ cls_struct_align a1,
+ cls_struct_align a2)
+{
+ struct cls_struct_align r;
+
+ r.a = a1.a + a2.a;
+ r.b = a1.b + a2.b;
+ r.c = a1.c + a2.c;
+ r.d = a1.d + a2.d;
+ r.e = a1.e + a2.e;
+ r.f = a1.f + a2.f;
+ r.g = a1.g + a2.g;
+
+ printf("%Lg %Lg %Lg %Lg %Lg %g %Lg %Lg %Lg %Lg %Lg %Lg %g %Lg: "
+ "%Lg %Lg %Lg %Lg %Lg %g %Lg\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+ a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
+ r.a, r.b, r.c, r.d, r.e, r.f, r.g);
+
+ return r;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[8];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+ struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
+ struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_longdouble;
+ cls_struct_fields[1] = &ffi_type_longdouble;
+ cls_struct_fields[2] = &ffi_type_longdouble;
+ cls_struct_fields[3] = &ffi_type_longdouble;
+ cls_struct_fields[4] = &ffi_type_longdouble;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_longdouble;
+ cls_struct_fields[7] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+ printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+ printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+ exit(0);
+}
+
+
+
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_pointer.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_pointer.c
new file mode 100644
index 0000000000..8fbf36a5c1
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_pointer.c
@@ -0,0 +1,95 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of pointer.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ void *b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+ struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = (void *)((uintptr_t)a1.b + (uintptr_t)a2.b);
+ result.c = a1.c + a2.c;
+
+ printf("%d %" PRIuPTR " %d %d %" PRIuPTR " %d: %d %" PRIuPTR " %d\n",
+ a1.a, (uintptr_t)a1.b, a1.c,
+ a2.a, (uintptr_t)a2.b, a2.c,
+ result.a, (uintptr_t)result.b,
+ result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
+ struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_pointer;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint16.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint16.c
new file mode 100644
index 0000000000..039b874732
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint16.c
@@ -0,0 +1,91 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of sint16.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ signed short b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+ struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_sshort;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint32.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint32.c
new file mode 100644
index 0000000000..c96c6d136d
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint32.c
@@ -0,0 +1,91 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of sint32.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ signed int b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+ struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_sint;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint64.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint64.c
new file mode 100644
index 0000000000..9aa7bdddff
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_sint64.c
@@ -0,0 +1,92 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of sint64.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ signed long long b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+ struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_sint64;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint16.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint16.c
new file mode 100644
index 0000000000..97620b79d1
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint16.c
@@ -0,0 +1,91 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of uint16.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ unsigned short b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+ struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint32.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint32.c
new file mode 100644
index 0000000000..5766fadf0d
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint32.c
@@ -0,0 +1,91 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of uint32.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ unsigned int b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+ struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uint;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint64.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint64.c
new file mode 100644
index 0000000000..a52cb8939c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_align_uint64.c
@@ -0,0 +1,93 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of uint64.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+
+/* { dg-do run } */
+/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ unsigned long long b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+ struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uint64;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_dbls_struct.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_dbls_struct.c
new file mode 100644
index 0000000000..e451dea51b
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_dbls_struct.c
@@ -0,0 +1,66 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check double arguments in structs.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/23/2007 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef struct Dbls {
+ double x;
+ double y;
+} Dbls;
+
+void
+closure_test_fn(Dbls p)
+{
+ printf("%.1f %.1f\n", p.x, p.y);
+}
+
+void
+closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
+ void** args, void* userdata __UNUSED__)
+{
+ closure_test_fn(*(Dbls*)args[0]);
+}
+
+int main(int argc __UNUSED__, char** argv __UNUSED__)
+{
+ ffi_cif cif;
+
+ void *code;
+ ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type* cl_arg_types[1];
+
+ ffi_type ts1_type;
+ ffi_type* ts1_type_elements[4];
+
+ Dbls arg = { 1.0, 2.0 };
+
+ ts1_type.size = 0;
+ ts1_type.alignment = 0;
+ ts1_type.type = FFI_TYPE_STRUCT;
+ ts1_type.elements = ts1_type_elements;
+
+ ts1_type_elements[0] = &ffi_type_double;
+ ts1_type_elements[1] = &ffi_type_double;
+ ts1_type_elements[2] = NULL;
+
+ cl_arg_types[0] = &ts1_type;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_void, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
+
+ ((void*(*)(Dbls))(code))(arg);
+ /* { dg-output "1.0 2.0" } */
+
+ closure_test_fn(arg);
+ /* { dg-output "\n1.0 2.0" } */
+
+ return 0;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_double.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_double.c
new file mode 100644
index 0000000000..84ad4cb7d9
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_double.c
@@ -0,0 +1,43 @@
+/* Area: closure_call
+ Purpose: Check return value double.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+ {
+ *(double *)resp = *(double *)args[0];
+
+ printf("%f: %f\n",*(double *)args[0],
+ *(double *)resp);
+ }
+typedef double (*cls_ret_double)(double);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[2];
+ double res;
+
+ cl_arg_types[0] = &ffi_type_double;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_double, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK);
+
+ res = (*((cls_ret_double)code))(21474.789);
+ /* { dg-output "21474.789000: 21474.789000" } */
+ printf("res: %.6f\n", res);
+ /* { dg-output "\nres: 21474.789000" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_double_va.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_double_va.c
new file mode 100644
index 0000000000..e077f92b86
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_double_va.c
@@ -0,0 +1,61 @@
+/* Area: ffi_call, closure_call
+ Purpose: Test doubles passed in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+/* { dg-output "" { xfail avr32*-*-* } } */
+/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
+
+#include "ffitest.h"
+
+static void
+cls_double_va_fn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ char* format = *(char**)args[0];
+ double doubleValue = *(double*)args[1];
+
+ *(ffi_arg*)resp = printf(format, doubleValue);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[3];
+ ffi_type* arg_types[3];
+
+ char* format = "%.1f\n";
+ double doubleArg = 7;
+ ffi_arg res = 0;
+
+ arg_types[0] = &ffi_type_pointer;
+ arg_types[1] = &ffi_type_double;
+ arg_types[2] = NULL;
+
+ /* This printf call is variadic */
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
+ arg_types) == FFI_OK);
+
+ args[0] = &format;
+ args[1] = &doubleArg;
+ args[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(printf), &res, args);
+ /* { dg-output "7.0" } */
+ printf("res: %d\n", (int) res);
+ /* { dg-output "\nres: 4" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL,
+ code) == FFI_OK);
+
+ res = ((int(*)(char*, ...))(code))(format, doubleArg);
+ /* { dg-output "\n7.0" } */
+ printf("res: %d\n", (int) res);
+ /* { dg-output "\nres: 4" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_float.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_float.c
new file mode 100644
index 0000000000..0090fed906
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_float.c
@@ -0,0 +1,42 @@
+/* Area: closure_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_float_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+ {
+ *(float *)resp = *(float *)args[0];
+
+ printf("%g: %g\n",*(float *)args[0],
+ *(float *)resp);
+ }
+
+typedef float (*cls_ret_float)(float);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[2];
+ float res;
+
+ cl_arg_types[0] = &ffi_type_float;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_float, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_float_fn, NULL, code) == FFI_OK);
+ res = ((((cls_ret_float)code)(-2122.12)));
+ /* { dg-output "\\-2122.12: \\-2122.12" } */
+ printf("res: %.6f\n", res);
+ /* { dg-output "\nres: \-2122.120117" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_longdouble.c
new file mode 100644
index 0000000000..d24e72e4ae
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_longdouble.c
@@ -0,0 +1,105 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check long double arguments.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin */
+
+/* This test is known to PASS on armv7l-unknown-linux-gnueabihf, so I have
+ remove the xfail for arm*-*-* below, until we know more. */
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
+
+#include "ffitest.h"
+
+long double cls_ldouble_fn(
+ long double a1,
+ long double a2,
+ long double a3,
+ long double a4,
+ long double a5,
+ long double a6,
+ long double a7,
+ long double a8)
+{
+ long double r = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
+
+ printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: %Lg\n",
+ a1, a2, a3, a4, a5, a6, a7, a8, r);
+
+ return r;
+}
+
+static void
+cls_ldouble_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ long double a1 = *(long double*)args[0];
+ long double a2 = *(long double*)args[1];
+ long double a3 = *(long double*)args[2];
+ long double a4 = *(long double*)args[3];
+ long double a5 = *(long double*)args[4];
+ long double a6 = *(long double*)args[5];
+ long double a7 = *(long double*)args[6];
+ long double a8 = *(long double*)args[7];
+
+ *(long double*)resp = cls_ldouble_fn(
+ a1, a2, a3, a4, a5, a6, a7, a8);
+}
+
+int main(void)
+{
+ ffi_cif cif;
+ void* code;
+ ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[9];
+ ffi_type* arg_types[9];
+ long double res = 0;
+
+ long double arg1 = 1;
+ long double arg2 = 2;
+ long double arg3 = 3;
+ long double arg4 = 4;
+ long double arg5 = 5;
+ long double arg6 = 6;
+ long double arg7 = 7;
+ long double arg8 = 8;
+
+ arg_types[0] = &ffi_type_longdouble;
+ arg_types[1] = &ffi_type_longdouble;
+ arg_types[2] = &ffi_type_longdouble;
+ arg_types[3] = &ffi_type_longdouble;
+ arg_types[4] = &ffi_type_longdouble;
+ arg_types[5] = &ffi_type_longdouble;
+ arg_types[6] = &ffi_type_longdouble;
+ arg_types[7] = &ffi_type_longdouble;
+ arg_types[8] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 8, &ffi_type_longdouble,
+ arg_types) == FFI_OK);
+
+ args[0] = &arg1;
+ args[1] = &arg2;
+ args[2] = &arg3;
+ args[3] = &arg4;
+ args[4] = &arg5;
+ args[5] = &arg6;
+ args[6] = &arg7;
+ args[7] = &arg8;
+ args[8] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_ldouble_fn), &res, args);
+ /* { dg-output "1 2 3 4 5 6 7 8: 36" } */
+ printf("res: %Lg\n", res);
+ /* { dg-output "\nres: 36" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ldouble_gn, NULL, code) == FFI_OK);
+
+ res = ((long double(*)(long double, long double, long double, long double,
+ long double, long double, long double, long double))(code))(arg1, arg2,
+ arg3, arg4, arg5, arg6, arg7, arg8);
+ /* { dg-output "\n1 2 3 4 5 6 7 8: 36" } */
+ printf("res: %Lg\n", res);
+ /* { dg-output "\nres: 36" } */
+
+ return 0;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_longdouble_va.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_longdouble_va.c
new file mode 100644
index 0000000000..39b438b289
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_longdouble_va.c
@@ -0,0 +1,61 @@
+/* Area: ffi_call, closure_call
+ Purpose: Test long doubles passed in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+/* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */
+/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
+
+#include "ffitest.h"
+
+static void
+cls_longdouble_va_fn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ char* format = *(char**)args[0];
+ long double ldValue = *(long double*)args[1];
+
+ *(ffi_arg*)resp = printf(format, ldValue);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[3];
+ ffi_type* arg_types[3];
+
+ char* format = "%.1Lf\n";
+ long double ldArg = 7;
+ ffi_arg res = 0;
+
+ arg_types[0] = &ffi_type_pointer;
+ arg_types[1] = &ffi_type_longdouble;
+ arg_types[2] = NULL;
+
+ /* This printf call is variadic */
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
+ arg_types) == FFI_OK);
+
+ args[0] = &format;
+ args[1] = &ldArg;
+ args[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(printf), &res, args);
+ /* { dg-output "7.0" } */
+ printf("res: %d\n", (int) res);
+ /* { dg-output "\nres: 4" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL,
+ code) == FFI_OK);
+
+ res = ((int(*)(char*, ...))(code))(format, ldArg);
+ /* { dg-output "\n7.0" } */
+ printf("res: %d\n", (int) res);
+ /* { dg-output "\nres: 4" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_many_mixed_args.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_many_mixed_args.c
new file mode 100644
index 0000000000..7fd6c8207a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_many_mixed_args.c
@@ -0,0 +1,70 @@
+/* Area: closure_call
+ Purpose: Check closures called with many args of mixed types
+ Limitations: none.
+ PR: none.
+ Originator: <david.schneider@picle.org> */
+
+/* { dg-do run } */
+#include "ffitest.h"
+#include <float.h>
+#include <math.h>
+
+#define NARGS 16
+
+static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ int i;
+ double r = 0;
+ double t;
+ for(i = 0; i < NARGS; i++)
+ {
+ if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
+ {
+ t = *(long int *)args[i];
+ CHECK(t == i+1);
+ }
+ else
+ {
+ t = *(double *)args[i];
+ CHECK(fabs(t - ((i+1) * 0.1)) < FLT_EPSILON);
+ }
+ r += t;
+ }
+ *(double *)resp = r;
+}
+typedef double (*cls_ret_double)(double, double, double, double, long int,
+double, double, double, double, long int, double, long int, double, long int,
+double, long int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[NARGS];
+ double res;
+ int i;
+ double expected = 64.9;
+
+ for(i = 0; i < NARGS; i++)
+ {
+ if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
+ cl_arg_types[i] = &ffi_type_slong;
+ else
+ cl_arg_types[i] = &ffi_type_double;
+ }
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NARGS,
+ &ffi_type_double, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK);
+
+ res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10,
+ 1.1, 12, 1.3, 14, 1.5, 16);
+ if (fabs(res - expected) < FLT_EPSILON)
+ exit(0);
+ else
+ abort();
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_many_mixed_float_double.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_many_mixed_float_double.c
new file mode 100644
index 0000000000..62b0697ac0
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_many_mixed_float_double.c
@@ -0,0 +1,55 @@
+/* Area: closure_call
+ Purpose: Check register allocation for closure calls with many float and double arguments
+ Limitations: none.
+ PR: none.
+ Originator: <david.schneider@picle.org> */
+
+/* { dg-do run } */
+#include "ffitest.h"
+#include <float.h>
+#include <math.h>
+
+#define NARGS 16
+
+static void cls_mixed_float_double_fn(ffi_cif* cif , void* ret, void** args,
+ void* userdata __UNUSED__)
+{
+ double r = 0;
+ unsigned int i;
+ double t;
+ for(i=0; i < cif->nargs; i++)
+ {
+ if(cif->arg_types[i] == &ffi_type_double) {
+ t = *(((double**)(args))[i]);
+ } else {
+ t = *(((float**)(args))[i]);
+ }
+ r += t;
+ }
+ *((double*)ret) = r;
+}
+typedef double (*cls_mixed)(double, float, double, double, double, double, double, float, float, double, float, float);
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_closure *closure;
+ void* code;
+ ffi_type *argtypes[12] = {&ffi_type_double, &ffi_type_float, &ffi_type_double,
+ &ffi_type_double, &ffi_type_double, &ffi_type_double,
+ &ffi_type_double, &ffi_type_float, &ffi_type_float,
+ &ffi_type_double, &ffi_type_float, &ffi_type_float};
+
+
+ closure = ffi_closure_alloc(sizeof(ffi_closure), (void**)&code);
+ if(closure ==NULL)
+ abort();
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 12, &ffi_type_double, argtypes) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(closure, &cif, cls_mixed_float_double_fn, NULL, code) == FFI_OK);
+ double ret = ((cls_mixed)code)(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2);
+ ffi_closure_free(closure);
+ if(fabs(ret - 7.8) < FLT_EPSILON)
+ exit(0);
+ else
+ abort();
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_schar.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_schar.c
new file mode 100644
index 0000000000..71df7b6516
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_schar.c
@@ -0,0 +1,74 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple signed char values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <hos@tamanegi.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+signed char test_func_fn(signed char a1, signed char a2)
+{
+ signed char result;
+
+ result = a1 + a2;
+
+ printf("%d %d: %d\n", a1, a2, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ signed char a1, a2;
+
+ a1 = *(signed char *)avals[0];
+ a2 = *(signed char *)avals[1];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2);
+
+}
+
+typedef signed char (*test_type)(signed char, signed char);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void * args_dbl[3];
+ ffi_type * cl_arg_types[3];
+ ffi_arg res_call;
+ signed char a, b, res_closure;
+
+ a = 2;
+ b = 125;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = NULL;
+
+ cl_arg_types[0] = &ffi_type_schar;
+ cl_arg_types[1] = &ffi_type_schar;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_schar, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "2 125: 127" } */
+ printf("res: %d\n", (signed char)res_call);
+ /* { dg-output "\nres: 127" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
+
+ res_closure = (*((test_type)code))(2, 125);
+ /* { dg-output "\n2 125: 127" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 127" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_sshort.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_sshort.c
new file mode 100644
index 0000000000..4c39153266
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_sshort.c
@@ -0,0 +1,74 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple signed short values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <andreast@gcc.gnu.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+signed short test_func_fn(signed short a1, signed short a2)
+{
+ signed short result;
+
+ result = a1 + a2;
+
+ printf("%d %d: %d\n", a1, a2, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ signed short a1, a2;
+
+ a1 = *(signed short *)avals[0];
+ a2 = *(signed short *)avals[1];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2);
+
+}
+
+typedef signed short (*test_type)(signed short, signed short);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void * args_dbl[3];
+ ffi_type * cl_arg_types[3];
+ ffi_arg res_call;
+ unsigned short a, b, res_closure;
+
+ a = 2;
+ b = 32765;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = NULL;
+
+ cl_arg_types[0] = &ffi_type_sshort;
+ cl_arg_types[1] = &ffi_type_sshort;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_sshort, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "2 32765: 32767" } */
+ printf("res: %d\n", (unsigned short)res_call);
+ /* { dg-output "\nres: 32767" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
+
+ res_closure = (*((test_type)code))(2, 32765);
+ /* { dg-output "\n2 32765: 32767" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 32767" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c
new file mode 100644
index 0000000000..1c3aeb5a66
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c
@@ -0,0 +1,86 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple signed short/char values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <andreast@gcc.gnu.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+signed short test_func_fn(signed char a1, signed short a2,
+ signed char a3, signed short a4)
+{
+ signed short result;
+
+ result = a1 + a2 + a3 + a4;
+
+ printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ signed char a1, a3;
+ signed short a2, a4;
+
+ a1 = *(signed char *)avals[0];
+ a2 = *(signed short *)avals[1];
+ a3 = *(signed char *)avals[2];
+ a4 = *(signed short *)avals[3];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
+
+}
+
+typedef signed short (*test_type)(signed char, signed short,
+ signed char, signed short);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void * args_dbl[5];
+ ffi_type * cl_arg_types[5];
+ ffi_arg res_call;
+ signed char a, c;
+ signed short b, d, res_closure;
+
+ a = 1;
+ b = 32765;
+ c = 127;
+ d = -128;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = &c;
+ args_dbl[3] = &d;
+ args_dbl[4] = NULL;
+
+ cl_arg_types[0] = &ffi_type_schar;
+ cl_arg_types[1] = &ffi_type_sshort;
+ cl_arg_types[2] = &ffi_type_schar;
+ cl_arg_types[3] = &ffi_type_sshort;
+ cl_arg_types[4] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_sshort, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "1 32765 127 -128: 32765" } */
+ printf("res: %d\n", (signed short)res_call);
+ /* { dg-output "\nres: 32765" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
+
+ res_closure = (*((test_type)code))(1, 32765, 127, -128);
+ /* { dg-output "\n1 32765 127 -128: 32765" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 32765" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_uchar.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_uchar.c
new file mode 100644
index 0000000000..009c02c72b
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_uchar.c
@@ -0,0 +1,91 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple unsigned char values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <andreast@gcc.gnu.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+unsigned char test_func_fn(unsigned char a1, unsigned char a2,
+ unsigned char a3, unsigned char a4)
+{
+ unsigned char result;
+
+ result = a1 + a2 + a3 + a4;
+
+ printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ unsigned char a1, a2, a3, a4;
+
+ a1 = *(unsigned char *)avals[0];
+ a2 = *(unsigned char *)avals[1];
+ a3 = *(unsigned char *)avals[2];
+ a4 = *(unsigned char *)avals[3];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
+
+}
+
+typedef unsigned char (*test_type)(unsigned char, unsigned char,
+ unsigned char, unsigned char);
+
+void test_func(ffi_cif *cif __UNUSED__, void *rval __UNUSED__, void **avals,
+ void *data __UNUSED__)
+{
+ printf("%d %d %d %d\n", *(unsigned char *)avals[0],
+ *(unsigned char *)avals[1], *(unsigned char *)avals[2],
+ *(unsigned char *)avals[3]);
+}
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void * args_dbl[5];
+ ffi_type * cl_arg_types[5];
+ ffi_arg res_call;
+ unsigned char a, b, c, d, res_closure;
+
+ a = 1;
+ b = 2;
+ c = 127;
+ d = 125;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = &c;
+ args_dbl[3] = &d;
+ args_dbl[4] = NULL;
+
+ cl_arg_types[0] = &ffi_type_uchar;
+ cl_arg_types[1] = &ffi_type_uchar;
+ cl_arg_types[2] = &ffi_type_uchar;
+ cl_arg_types[3] = &ffi_type_uchar;
+ cl_arg_types[4] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_uchar, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "1 2 127 125: 255" } */
+ printf("res: %d\n", (unsigned char)res_call);
+ /* { dg-output "\nres: 255" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
+
+ res_closure = (*((test_type)code))(1, 2, 127, 125);
+ /* { dg-output "\n1 2 127 125: 255" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 255" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_ushort.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_ushort.c
new file mode 100644
index 0000000000..dd10ca7346
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_ushort.c
@@ -0,0 +1,74 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple unsigned short values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <andreast@gcc.gnu.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+unsigned short test_func_fn(unsigned short a1, unsigned short a2)
+{
+ unsigned short result;
+
+ result = a1 + a2;
+
+ printf("%d %d: %d\n", a1, a2, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ unsigned short a1, a2;
+
+ a1 = *(unsigned short *)avals[0];
+ a2 = *(unsigned short *)avals[1];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2);
+
+}
+
+typedef unsigned short (*test_type)(unsigned short, unsigned short);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void * args_dbl[3];
+ ffi_type * cl_arg_types[3];
+ ffi_arg res_call;
+ unsigned short a, b, res_closure;
+
+ a = 2;
+ b = 32765;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = NULL;
+
+ cl_arg_types[0] = &ffi_type_ushort;
+ cl_arg_types[1] = &ffi_type_ushort;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "2 32765: 32767" } */
+ printf("res: %d\n", (unsigned short)res_call);
+ /* { dg-output "\nres: 32767" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
+
+ res_closure = (*((test_type)code))(2, 32765);
+ /* { dg-output "\n2 32765: 32767" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 32767" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c
new file mode 100644
index 0000000000..2588e97f98
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c
@@ -0,0 +1,86 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple unsigned short/char values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <andreast@gcc.gnu.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+unsigned short test_func_fn(unsigned char a1, unsigned short a2,
+ unsigned char a3, unsigned short a4)
+{
+ unsigned short result;
+
+ result = a1 + a2 + a3 + a4;
+
+ printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ unsigned char a1, a3;
+ unsigned short a2, a4;
+
+ a1 = *(unsigned char *)avals[0];
+ a2 = *(unsigned short *)avals[1];
+ a3 = *(unsigned char *)avals[2];
+ a4 = *(unsigned short *)avals[3];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
+
+}
+
+typedef unsigned short (*test_type)(unsigned char, unsigned short,
+ unsigned char, unsigned short);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void * args_dbl[5];
+ ffi_type * cl_arg_types[5];
+ ffi_arg res_call;
+ unsigned char a, c;
+ unsigned short b, d, res_closure;
+
+ a = 1;
+ b = 2;
+ c = 127;
+ d = 128;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = &c;
+ args_dbl[3] = &d;
+ args_dbl[4] = NULL;
+
+ cl_arg_types[0] = &ffi_type_uchar;
+ cl_arg_types[1] = &ffi_type_ushort;
+ cl_arg_types[2] = &ffi_type_uchar;
+ cl_arg_types[3] = &ffi_type_ushort;
+ cl_arg_types[4] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "1 2 127 128: 258" } */
+ printf("res: %d\n", (unsigned short)res_call);
+ /* { dg-output "\nres: 258" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
+
+ res_closure = (*((test_type)code))(1, 2, 127, 128);
+ /* { dg-output "\n1 2 127 128: 258" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 258" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_pointer.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_pointer.c
new file mode 100644
index 0000000000..d82a87a71b
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_pointer.c
@@ -0,0 +1,74 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check pointer arguments.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+void* cls_pointer_fn(void* a1, void* a2)
+{
+ void* result = (void*)((intptr_t)a1 + (intptr_t)a2);
+
+ printf("0x%08x 0x%08x: 0x%08x\n",
+ (unsigned int)(uintptr_t) a1,
+ (unsigned int)(uintptr_t) a2,
+ (unsigned int)(uintptr_t) result);
+
+ return result;
+}
+
+static void
+cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ void* a1 = *(void**)(args[0]);
+ void* a2 = *(void**)(args[1]);
+
+ *(void**)resp = cls_pointer_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[3];
+ /* ffi_type cls_pointer_type; */
+ ffi_type* arg_types[3];
+
+/* cls_pointer_type.size = sizeof(void*);
+ cls_pointer_type.alignment = 0;
+ cls_pointer_type.type = FFI_TYPE_POINTER;
+ cls_pointer_type.elements = NULL;*/
+
+ void* arg1 = (void*)0x12345678;
+ void* arg2 = (void*)0x89abcdef;
+ ffi_arg res = 0;
+
+ arg_types[0] = &ffi_type_pointer;
+ arg_types[1] = &ffi_type_pointer;
+ arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
+ arg_types) == FFI_OK);
+
+ args[0] = &arg1;
+ args[1] = &arg2;
+ args[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_pointer_fn), &res, args);
+ /* { dg-output "0x12345678 0x89abcdef: 0x9be02467" } */
+ printf("res: 0x%08x\n", (unsigned int) res);
+ /* { dg-output "\nres: 0x9be02467" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
+
+ res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
+ /* { dg-output "\n0x12345678 0x89abcdef: 0x9be02467" } */
+ printf("res: 0x%08x\n", (unsigned int) res);
+ /* { dg-output "\nres: 0x9be02467" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_pointer_stack.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_pointer_stack.c
new file mode 100644
index 0000000000..1f1d9157b9
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_pointer_stack.c
@@ -0,0 +1,142 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check pointer arguments across multiple hideous stack frames.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/7/2007 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+static long dummyVar;
+
+long dummy_func(
+ long double a1, char b1,
+ long double a2, char b2,
+ long double a3, char b3,
+ long double a4, char b4)
+{
+ return a1 + b1 + a2 + b2 + a3 + b3 + a4 + b4;
+}
+
+void* cls_pointer_fn2(void* a1, void* a2)
+{
+ long double trample1 = (intptr_t)a1 + (intptr_t)a2;
+ char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
+ long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
+ char trample4 = trample2 + ((char*)&a1)[1];
+ long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
+ char trample6 = trample4 + ((char*)&a2)[1];
+ long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
+ char trample8 = trample6 + trample2;
+ void* result;
+
+ dummyVar = dummy_func(trample1, trample2, trample3, trample4,
+ trample5, trample6, trample7, trample8);
+
+ result = (void*)((intptr_t)a1 + (intptr_t)a2);
+
+ printf("0x%08x 0x%08x: 0x%08x\n",
+ (unsigned int)(uintptr_t) a1,
+ (unsigned int)(uintptr_t) a2,
+ (unsigned int)(uintptr_t) result);
+
+ return result;
+}
+
+void* cls_pointer_fn1(void* a1, void* a2)
+{
+ long double trample1 = (intptr_t)a1 + (intptr_t)a2;
+ char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
+ long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
+ char trample4 = trample2 + ((char*)&a1)[1];
+ long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
+ char trample6 = trample4 + ((char*)&a2)[1];
+ long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
+ char trample8 = trample6 + trample2;
+ void* result;
+
+ dummyVar = dummy_func(trample1, trample2, trample3, trample4,
+ trample5, trample6, trample7, trample8);
+
+ result = (void*)((intptr_t)a1 + (intptr_t)a2);
+
+ printf("0x%08x 0x%08x: 0x%08x\n",
+ (unsigned int)(intptr_t) a1,
+ (unsigned int)(intptr_t) a2,
+ (unsigned int)(intptr_t) result);
+
+ result = cls_pointer_fn2(result, a1);
+
+ return result;
+}
+
+static void
+cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ void* a1 = *(void**)(args[0]);
+ void* a2 = *(void**)(args[1]);
+
+ long double trample1 = (intptr_t)a1 + (intptr_t)a2;
+ char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
+ long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
+ char trample4 = trample2 + ((char*)&a1)[1];
+ long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
+ char trample6 = trample4 + ((char*)&a2)[1];
+ long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
+ char trample8 = trample6 + trample2;
+
+ dummyVar = dummy_func(trample1, trample2, trample3, trample4,
+ trample5, trample6, trample7, trample8);
+
+ *(void**)resp = cls_pointer_fn1(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[3];
+ /* ffi_type cls_pointer_type; */
+ ffi_type* arg_types[3];
+
+/* cls_pointer_type.size = sizeof(void*);
+ cls_pointer_type.alignment = 0;
+ cls_pointer_type.type = FFI_TYPE_POINTER;
+ cls_pointer_type.elements = NULL;*/
+
+ void* arg1 = (void*)0x01234567;
+ void* arg2 = (void*)0x89abcdef;
+ ffi_arg res = 0;
+
+ arg_types[0] = &ffi_type_pointer;
+ arg_types[1] = &ffi_type_pointer;
+ arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
+ arg_types) == FFI_OK);
+
+ args[0] = &arg1;
+ args[1] = &arg2;
+ args[2] = NULL;
+
+ printf("\n");
+ ffi_call(&cif, FFI_FN(cls_pointer_fn1), &res, args);
+
+ printf("res: 0x%08x\n", (unsigned int) res);
+ /* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */
+ /* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */
+ /* { dg-output "\nres: 0x8bf258bd" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
+
+ res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
+
+ printf("res: 0x%08x\n", (unsigned int) res);
+ /* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */
+ /* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */
+ /* { dg-output "\nres: 0x8bf258bd" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_schar.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_schar.c
new file mode 100644
index 0000000000..82986b172c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_schar.c
@@ -0,0 +1,44 @@
+/* Area: closure_call
+ Purpose: Check return value schar.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20031108 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_schar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg*)resp = *(signed char *)args[0];
+ printf("%d: %d\n",*(signed char *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef signed char (*cls_ret_schar)(signed char);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[2];
+ signed char res;
+
+ cl_arg_types[0] = &ffi_type_schar;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_schar, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_schar_fn, NULL, code) == FFI_OK);
+
+ res = (*((cls_ret_schar)code))(127);
+ /* { dg-output "127: 127" } */
+ printf("res: %d\n", res);
+ /* { dg-output "\nres: 127" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_sint.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_sint.c
new file mode 100644
index 0000000000..c7e13b73a3
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_sint.c
@@ -0,0 +1,42 @@
+/* Area: closure_call
+ Purpose: Check return value sint32.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20031108 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_sint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg*)resp = *(signed int *)args[0];
+ printf("%d: %d\n",*(signed int *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef signed int (*cls_ret_sint)(signed int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[2];
+ signed int res;
+
+ cl_arg_types[0] = &ffi_type_sint;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sint_fn, NULL, code) == FFI_OK);
+
+ res = (*((cls_ret_sint)code))(65534);
+ /* { dg-output "65534: 65534" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 65534" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_sshort.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_sshort.c
new file mode 100644
index 0000000000..846d57ed1b
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_sshort.c
@@ -0,0 +1,42 @@
+/* Area: closure_call
+ Purpose: Check return value sshort.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20031108 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_sshort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg*)resp = *(signed short *)args[0];
+ printf("%d: %d\n",*(signed short *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef signed short (*cls_ret_sshort)(signed short);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[2];
+ signed short res;
+
+ cl_arg_types[0] = &ffi_type_sshort;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_sshort, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sshort_fn, NULL, code) == FFI_OK);
+
+ res = (*((cls_ret_sshort)code))(255);
+ /* { dg-output "255: 255" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 255" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_struct_va1.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_struct_va1.c
new file mode 100644
index 0000000000..6d1fdaeb60
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_struct_va1.c
@@ -0,0 +1,114 @@
+/* Area: ffi_call, closure_call
+ Purpose: Test doubles passed in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run } */
+/* { dg-output "" { xfail avr32*-*-* } } */
+#include "ffitest.h"
+
+struct small_tag
+{
+ unsigned char a;
+ unsigned char b;
+};
+
+struct large_tag
+{
+ unsigned a;
+ unsigned b;
+ unsigned c;
+ unsigned d;
+ unsigned e;
+};
+
+static void
+test_fn (ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ int n = *(int*)args[0];
+ struct small_tag s1 = * (struct small_tag *) args[1];
+ struct large_tag l1 = * (struct large_tag *) args[2];
+ struct small_tag s2 = * (struct small_tag *) args[3];
+
+ printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b,
+ l1.a, l1.b, l1.c, l1.d, l1.e,
+ s2.a, s2.b);
+ * (ffi_arg*) resp = 42;
+}
+
+int
+main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc (sizeof (ffi_closure), &code);
+ ffi_type* arg_types[5];
+
+ ffi_arg res = 0;
+
+ ffi_type s_type;
+ ffi_type *s_type_elements[3];
+
+ ffi_type l_type;
+ ffi_type *l_type_elements[6];
+
+ struct small_tag s1;
+ struct small_tag s2;
+ struct large_tag l1;
+
+ int si;
+
+ s_type.size = 0;
+ s_type.alignment = 0;
+ s_type.type = FFI_TYPE_STRUCT;
+ s_type.elements = s_type_elements;
+
+ s_type_elements[0] = &ffi_type_uchar;
+ s_type_elements[1] = &ffi_type_uchar;
+ s_type_elements[2] = NULL;
+
+ l_type.size = 0;
+ l_type.alignment = 0;
+ l_type.type = FFI_TYPE_STRUCT;
+ l_type.elements = l_type_elements;
+
+ l_type_elements[0] = &ffi_type_uint;
+ l_type_elements[1] = &ffi_type_uint;
+ l_type_elements[2] = &ffi_type_uint;
+ l_type_elements[3] = &ffi_type_uint;
+ l_type_elements[4] = &ffi_type_uint;
+ l_type_elements[5] = NULL;
+
+ arg_types[0] = &ffi_type_sint;
+ arg_types[1] = &s_type;
+ arg_types[2] = &l_type;
+ arg_types[3] = &s_type;
+ arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint,
+ arg_types) == FFI_OK);
+
+ si = 4;
+ s1.a = 5;
+ s1.b = 6;
+
+ s2.a = 20;
+ s2.b = 21;
+
+ l1.a = 10;
+ l1.b = 11;
+ l1.c = 12;
+ l1.d = 13;
+ l1.e = 14;
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_fn, NULL, code) == FFI_OK);
+
+ res = ((int (*)(int, ...))(code))(si, s1, l1, s2);
+ /* { dg-output "4 5 6 10 11 12 13 14 20 21" } */
+ printf("res: %d\n", (int) res);
+ /* { dg-output "\nres: 42" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uchar.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uchar.c
new file mode 100644
index 0000000000..c1317e795f
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uchar.c
@@ -0,0 +1,42 @@
+/* Area: closure_call
+ Purpose: Check return value uchar.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_uchar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg*)resp = *(unsigned char *)args[0];
+ printf("%d: %d\n",*(unsigned char *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef unsigned char (*cls_ret_uchar)(unsigned char);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[2];
+ unsigned char res;
+
+ cl_arg_types[0] = &ffi_type_uchar;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uchar, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uchar_fn, NULL, code) == FFI_OK);
+
+ res = (*((cls_ret_uchar)code))(127);
+ /* { dg-output "127: 127" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 127" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uchar_va.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uchar_va.c
new file mode 100644
index 0000000000..6491c5b3df
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uchar_va.c
@@ -0,0 +1,44 @@
+/* Area: closure_call
+ Purpose: Test anonymous unsigned char argument.
+ Limitations: none.
+ PR: none.
+ Originator: ARM Ltd. */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef unsigned char T;
+
+static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+ {
+ *(ffi_arg *)resp = *(T *)args[0];
+
+ printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]);
+ }
+
+typedef T (*cls_ret_T)(T, ...);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[3];
+ T res;
+
+ cl_arg_types[0] = &ffi_type_uchar;
+ cl_arg_types[1] = &ffi_type_uchar;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
+ &ffi_type_uchar, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
+ res = ((((cls_ret_T)code)(67, 4)));
+ /* { dg-output "67: 67 4" } */
+ printf("res: %d\n", res);
+ /* { dg-output "\nres: 67" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uint.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uint.c
new file mode 100644
index 0000000000..885cff5c31
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uint.c
@@ -0,0 +1,43 @@
+/* Area: closure_call
+ Purpose: Check return value uint.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_uint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg *)resp = *(unsigned int *)args[0];
+
+ printf("%d: %d\n",*(unsigned int *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef unsigned int (*cls_ret_uint)(unsigned int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[2];
+ unsigned int res;
+
+ cl_arg_types[0] = &ffi_type_uint;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uint_fn, NULL, code) == FFI_OK);
+
+ res = (*((cls_ret_uint)code))(2147483647);
+ /* { dg-output "2147483647: 2147483647" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 2147483647" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uint_va.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uint_va.c
new file mode 100644
index 0000000000..b04cfd19c2
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_uint_va.c
@@ -0,0 +1,45 @@
+/* Area: closure_call
+ Purpose: Test anonymous unsigned int argument.
+ Limitations: none.
+ PR: none.
+ Originator: ARM Ltd. */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef unsigned int T;
+
+static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+ {
+ *(ffi_arg *)resp = *(T *)args[0];
+
+ printf("%d: %d %d\n", (int)*(ffi_arg *)resp, *(T *)args[0], *(T *)args[1]);
+ }
+
+typedef T (*cls_ret_T)(T, ...);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[3];
+ T res;
+
+ cl_arg_types[0] = &ffi_type_uint;
+ cl_arg_types[1] = &ffi_type_uint;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
+ &ffi_type_uint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
+ res = ((((cls_ret_T)code)(67, 4)));
+ /* { dg-output "67: 67 4" } */
+ printf("res: %d\n", res);
+ /* { dg-output "\nres: 67" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ulong_va.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ulong_va.c
new file mode 100644
index 0000000000..0315082e09
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ulong_va.c
@@ -0,0 +1,45 @@
+/* Area: closure_call
+ Purpose: Test anonymous unsigned long argument.
+ Limitations: none.
+ PR: none.
+ Originator: ARM Ltd. */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef unsigned long T;
+
+static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+ {
+ *(T *)resp = *(T *)args[0];
+
+ printf("%ld: %ld %ld\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
+ }
+
+typedef T (*cls_ret_T)(T, ...);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[3];
+ T res;
+
+ cl_arg_types[0] = &ffi_type_ulong;
+ cl_arg_types[1] = &ffi_type_ulong;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
+ &ffi_type_ulong, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
+ res = ((((cls_ret_T)code)(67, 4)));
+ /* { dg-output "67: 67 4" } */
+ printf("res: %ld\n", res);
+ /* { dg-output "\nres: 67" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ulonglong.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ulonglong.c
new file mode 100644
index 0000000000..62f2cae63a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ulonglong.c
@@ -0,0 +1,47 @@
+/* Area: closure_call
+ Purpose: Check return value long long.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
+#include "ffitest.h"
+
+static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ *(unsigned long long *)resp= 0xfffffffffffffffLL ^ *(unsigned long long *)args[0];
+
+ printf("%" PRIuLL ": %" PRIuLL "\n",*(unsigned long long *)args[0],
+ *(unsigned long long *)(resp));
+}
+typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[2];
+ unsigned long long res;
+
+ cl_arg_types[0] = &ffi_type_uint64;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uint64, cl_arg_types) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ulonglong_fn, NULL, code) == FFI_OK);
+ res = (*((cls_ret_ulonglong)code))(214LL);
+ /* { dg-output "214: 1152921504606846761" } */
+ printf("res: %" PRIdLL "\n", res);
+ /* { dg-output "\nres: 1152921504606846761" } */
+
+ res = (*((cls_ret_ulonglong)code))(9223372035854775808LL);
+ /* { dg-output "\n9223372035854775808: 8070450533247928831" } */
+ printf("res: %" PRIdLL "\n", res);
+ /* { dg-output "\nres: 8070450533247928831" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ushort.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ushort.c
new file mode 100644
index 0000000000..a00100e07f
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ushort.c
@@ -0,0 +1,43 @@
+/* Area: closure_call
+ Purpose: Check return value ushort.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_ushort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg*)resp = *(unsigned short *)args[0];
+
+ printf("%d: %d\n",*(unsigned short *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef unsigned short (*cls_ret_ushort)(unsigned short);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[2];
+ unsigned short res;
+
+ cl_arg_types[0] = &ffi_type_ushort;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ushort_fn, NULL, code) == FFI_OK);
+
+ res = (*((cls_ret_ushort)code))(65535);
+ /* { dg-output "65535: 65535" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 65535" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ushort_va.c b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ushort_va.c
new file mode 100644
index 0000000000..37aa1064ea
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/cls_ushort_va.c
@@ -0,0 +1,44 @@
+/* Area: closure_call
+ Purpose: Test anonymous unsigned short argument.
+ Limitations: none.
+ PR: none.
+ Originator: ARM Ltd. */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef unsigned short T;
+
+static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+ {
+ *(ffi_arg *)resp = *(T *)args[0];
+
+ printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]);
+ }
+
+typedef T (*cls_ret_T)(T, ...);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[3];
+ T res;
+
+ cl_arg_types[0] = &ffi_type_ushort;
+ cl_arg_types[1] = &ffi_type_ushort;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
+ &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
+ res = ((((cls_ret_T)code)(67, 4)));
+ /* { dg-output "67: 67 4" } */
+ printf("res: %d\n", res);
+ /* { dg-output "\nres: 67" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/err_bad_abi.c b/js/src/ctypes/libffi/testsuite/libffi.closures/err_bad_abi.c
new file mode 100644
index 0000000000..f5a73179ec
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/err_bad_abi.c
@@ -0,0 +1,36 @@
+/* Area: ffi_prep_cif, ffi_prep_closure
+ Purpose: Test error return for bad ABIs.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static void
+dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
+ void** args __UNUSED__, void* userdata __UNUSED__)
+{}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type* arg_types[1];
+
+ arg_types[0] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void,
+ arg_types) == FFI_BAD_ABI);
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void,
+ arg_types) == FFI_OK);
+
+ cif.abi= 255;
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI);
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/ffitest.h b/js/src/ctypes/libffi/testsuite/libffi.closures/ffitest.h
new file mode 100644
index 0000000000..cfce1ad589
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/ffitest.h
@@ -0,0 +1,138 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <ffi.h>
+#include "fficonfig.h"
+
+#if defined HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#if defined HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#define MAX_ARGS 256
+
+#define CHECK(x) (void)(!(x) ? (abort(), 1) : 0)
+
+/* Define macros so that compilers other than gcc can run the tests. */
+#undef __UNUSED__
+#if defined(__GNUC__)
+#define __UNUSED__ __attribute__((__unused__))
+#define __STDCALL__ __attribute__((stdcall))
+#define __THISCALL__ __attribute__((thiscall))
+#define __FASTCALL__ __attribute__((fastcall))
+#define __MSABI__ __attribute__((ms_abi))
+#else
+#define __UNUSED__
+#define __STDCALL__ __stdcall
+#define __THISCALL__ __thiscall
+#define __FASTCALL__ __fastcall
+#endif
+
+#ifndef ABI_NUM
+#define ABI_NUM FFI_DEFAULT_ABI
+#define ABI_ATTR
+#endif
+
+/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
+ file open. */
+#ifdef HAVE_MMAP_ANON
+# undef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED -1
+# endif
+# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+# endif
+# define USING_MMAP
+
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED -1
+# endif
+# define USING_MMAP
+
+#endif
+
+/* MinGW kludge. */
+#if defined(_WIN64) | defined(_WIN32)
+#define PRIdLL "I64d"
+#define PRIuLL "I64u"
+#else
+#define PRIdLL "lld"
+#define PRIuLL "llu"
+#endif
+
+/* Tru64 UNIX kludge. */
+#if defined(__alpha__) && defined(__osf__)
+/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit. */
+#undef PRIdLL
+#define PRIdLL "ld"
+#undef PRIuLL
+#define PRIuLL "lu"
+#define PRId8 "hd"
+#define PRIu8 "hu"
+#define PRId64 "ld"
+#define PRIu64 "lu"
+#define PRIuPTR "lu"
+#endif
+
+/* PA HP-UX kludge. */
+#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR)
+#define PRIuPTR "lu"
+#endif
+
+/* IRIX kludge. */
+#if defined(__sgi)
+/* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99
+ compilations. */
+#define PRId8 "hhd"
+#define PRIu8 "hhu"
+#if (_MIPS_SZLONG == 32)
+#define PRId64 "lld"
+#define PRIu64 "llu"
+#endif
+/* This doesn't match <inttypes.h>, which always has "lld" here, but the
+ arguments are uint64_t, int64_t, which are unsigned long, long for
+ 64-bit in <sgidefs.h>. */
+#if (_MIPS_SZLONG == 64)
+#define PRId64 "ld"
+#define PRIu64 "lu"
+#endif
+/* This doesn't match <inttypes.h>, which has "u" here, but the arguments
+ are uintptr_t, which is always unsigned long. */
+#define PRIuPTR "lu"
+#endif
+
+/* Solaris < 10 kludge. */
+#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR)
+#if defined(__arch64__) || defined (__x86_64__)
+#define PRIuPTR "lu"
+#else
+#define PRIuPTR "u"
+#endif
+#endif
+
+/* MSVC kludge. */
+#if defined _MSC_VER
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
+#define PRIuPTR "lu"
+#define PRIu8 "u"
+#define PRId8 "d"
+#define PRIu64 "I64u"
+#define PRId64 "I64d"
+#endif
+#endif
+
+#ifndef PRIuPTR
+#define PRIuPTR "u"
+#endif
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/huge_struct.c b/js/src/ctypes/libffi/testsuite/libffi.closures/huge_struct.c
new file mode 100644
index 0000000000..1915c3f1e8
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/huge_struct.c
@@ -0,0 +1,341 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check large structure returns.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/18/2007
+*/
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
+/* { dg-options -Wformat=0 { target moxie*-*-elf or1k-*-* } } */
+
+#include "ffitest.h"
+
+typedef struct BigStruct{
+ uint8_t a;
+ int8_t b;
+ uint16_t c;
+ int16_t d;
+ uint32_t e;
+ int32_t f;
+ uint64_t g;
+ int64_t h;
+ float i;
+ double j;
+ long double k;
+ char* l;
+ uint8_t m;
+ int8_t n;
+ uint16_t o;
+ int16_t p;
+ uint32_t q;
+ int32_t r;
+ uint64_t s;
+ int64_t t;
+ float u;
+ double v;
+ long double w;
+ char* x;
+ uint8_t y;
+ int8_t z;
+ uint16_t aa;
+ int16_t bb;
+ uint32_t cc;
+ int32_t dd;
+ uint64_t ee;
+ int64_t ff;
+ float gg;
+ double hh;
+ long double ii;
+ char* jj;
+ uint8_t kk;
+ int8_t ll;
+ uint16_t mm;
+ int16_t nn;
+ uint32_t oo;
+ int32_t pp;
+ uint64_t qq;
+ int64_t rr;
+ float ss;
+ double tt;
+ long double uu;
+ char* vv;
+ uint8_t ww;
+ int8_t xx;
+} BigStruct;
+
+BigStruct
+test_large_fn(
+ uint8_t ui8_1,
+ int8_t si8_1,
+ uint16_t ui16_1,
+ int16_t si16_1,
+ uint32_t ui32_1,
+ int32_t si32_1,
+ uint64_t ui64_1,
+ int64_t si64_1,
+ float f_1,
+ double d_1,
+ long double ld_1,
+ char* p_1,
+ uint8_t ui8_2,
+ int8_t si8_2,
+ uint16_t ui16_2,
+ int16_t si16_2,
+ uint32_t ui32_2,
+ int32_t si32_2,
+ uint64_t ui64_2,
+ int64_t si64_2,
+ float f_2,
+ double d_2,
+ long double ld_2,
+ char* p_2,
+ uint8_t ui8_3,
+ int8_t si8_3,
+ uint16_t ui16_3,
+ int16_t si16_3,
+ uint32_t ui32_3,
+ int32_t si32_3,
+ uint64_t ui64_3,
+ int64_t si64_3,
+ float f_3,
+ double d_3,
+ long double ld_3,
+ char* p_3,
+ uint8_t ui8_4,
+ int8_t si8_4,
+ uint16_t ui16_4,
+ int16_t si16_4,
+ uint32_t ui32_4,
+ int32_t si32_4,
+ uint64_t ui64_4,
+ int64_t si64_4,
+ float f_4,
+ double d_4,
+ long double ld_4,
+ char* p_4,
+ uint8_t ui8_5,
+ int8_t si8_5)
+{
+ BigStruct retVal = {
+ ui8_1 + 1, si8_1 + 1, ui16_1 + 1, si16_1 + 1, ui32_1 + 1, si32_1 + 1,
+ ui64_1 + 1, si64_1 + 1, f_1 + 1, d_1 + 1, ld_1 + 1, (char*)((intptr_t)p_1 + 1),
+ ui8_2 + 2, si8_2 + 2, ui16_2 + 2, si16_2 + 2, ui32_2 + 2, si32_2 + 2,
+ ui64_2 + 2, si64_2 + 2, f_2 + 2, d_2 + 2, ld_2 + 2, (char*)((intptr_t)p_2 + 2),
+ ui8_3 + 3, si8_3 + 3, ui16_3 + 3, si16_3 + 3, ui32_3 + 3, si32_3 + 3,
+ ui64_3 + 3, si64_3 + 3, f_3 + 3, d_3 + 3, ld_3 + 3, (char*)((intptr_t)p_3 + 3),
+ ui8_4 + 4, si8_4 + 4, ui16_4 + 4, si16_4 + 4, ui32_4 + 4, si32_4 + 4,
+ ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((intptr_t)p_4 + 4),
+ ui8_5 + 5, si8_5 + 5};
+
+ printf("%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 ": "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
+ ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, (unsigned long)p_1,
+ ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, (unsigned long)p_2,
+ ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, (unsigned long)p_3,
+ ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, (unsigned long)p_4, ui8_5, si8_5,
+ retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
+ retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
+ retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
+ retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
+ retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
+ retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
+ retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
+ retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
+
+ return retVal;
+}
+
+static void
+cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+ uint8_t ui8_1 = *(uint8_t*)args[0];
+ int8_t si8_1 = *(int8_t*)args[1];
+ uint16_t ui16_1 = *(uint16_t*)args[2];
+ int16_t si16_1 = *(int16_t*)args[3];
+ uint32_t ui32_1 = *(uint32_t*)args[4];
+ int32_t si32_1 = *(int32_t*)args[5];
+ uint64_t ui64_1 = *(uint64_t*)args[6];
+ int64_t si64_1 = *(int64_t*)args[7];
+ float f_1 = *(float*)args[8];
+ double d_1 = *(double*)args[9];
+ long double ld_1 = *(long double*)args[10];
+ char* p_1 = *(char**)args[11];
+ uint8_t ui8_2 = *(uint8_t*)args[12];
+ int8_t si8_2 = *(int8_t*)args[13];
+ uint16_t ui16_2 = *(uint16_t*)args[14];
+ int16_t si16_2 = *(int16_t*)args[15];
+ uint32_t ui32_2 = *(uint32_t*)args[16];
+ int32_t si32_2 = *(int32_t*)args[17];
+ uint64_t ui64_2 = *(uint64_t*)args[18];
+ int64_t si64_2 = *(int64_t*)args[19];
+ float f_2 = *(float*)args[20];
+ double d_2 = *(double*)args[21];
+ long double ld_2 = *(long double*)args[22];
+ char* p_2 = *(char**)args[23];
+ uint8_t ui8_3 = *(uint8_t*)args[24];
+ int8_t si8_3 = *(int8_t*)args[25];
+ uint16_t ui16_3 = *(uint16_t*)args[26];
+ int16_t si16_3 = *(int16_t*)args[27];
+ uint32_t ui32_3 = *(uint32_t*)args[28];
+ int32_t si32_3 = *(int32_t*)args[29];
+ uint64_t ui64_3 = *(uint64_t*)args[30];
+ int64_t si64_3 = *(int64_t*)args[31];
+ float f_3 = *(float*)args[32];
+ double d_3 = *(double*)args[33];
+ long double ld_3 = *(long double*)args[34];
+ char* p_3 = *(char**)args[35];
+ uint8_t ui8_4 = *(uint8_t*)args[36];
+ int8_t si8_4 = *(int8_t*)args[37];
+ uint16_t ui16_4 = *(uint16_t*)args[38];
+ int16_t si16_4 = *(int16_t*)args[39];
+ uint32_t ui32_4 = *(uint32_t*)args[40];
+ int32_t si32_4 = *(int32_t*)args[41];
+ uint64_t ui64_4 = *(uint64_t*)args[42];
+ int64_t si64_4 = *(int64_t*)args[43];
+ float f_4 = *(float*)args[44];
+ double d_4 = *(double*)args[45];
+ long double ld_4 = *(long double*)args[46];
+ char* p_4 = *(char**)args[47];
+ uint8_t ui8_5 = *(uint8_t*)args[48];
+ int8_t si8_5 = *(int8_t*)args[49];
+
+ *(BigStruct*)resp = test_large_fn(
+ ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, p_1,
+ ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, p_2,
+ ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, p_3,
+ ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, p_4,
+ ui8_5, si8_5);
+}
+
+int
+main(int argc __UNUSED__, const char** argv __UNUSED__)
+{
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+
+ ffi_cif cif;
+ ffi_type* argTypes[51];
+ void* argValues[51];
+
+ ffi_type ret_struct_type;
+ ffi_type* st_fields[51];
+ BigStruct retVal;
+
+ uint8_t ui8 = 1;
+ int8_t si8 = 2;
+ uint16_t ui16 = 3;
+ int16_t si16 = 4;
+ uint32_t ui32 = 5;
+ int32_t si32 = 6;
+ uint64_t ui64 = 7;
+ int64_t si64 = 8;
+ float f = 9;
+ double d = 10;
+ long double ld = 11;
+ char* p = (char*)0x12345678;
+
+ memset (&retVal, 0, sizeof(retVal));
+
+ ret_struct_type.size = 0;
+ ret_struct_type.alignment = 0;
+ ret_struct_type.type = FFI_TYPE_STRUCT;
+ ret_struct_type.elements = st_fields;
+
+ st_fields[0] = st_fields[12] = st_fields[24] = st_fields[36] = st_fields[48] = &ffi_type_uint8;
+ st_fields[1] = st_fields[13] = st_fields[25] = st_fields[37] = st_fields[49] = &ffi_type_sint8;
+ st_fields[2] = st_fields[14] = st_fields[26] = st_fields[38] = &ffi_type_uint16;
+ st_fields[3] = st_fields[15] = st_fields[27] = st_fields[39] = &ffi_type_sint16;
+ st_fields[4] = st_fields[16] = st_fields[28] = st_fields[40] = &ffi_type_uint32;
+ st_fields[5] = st_fields[17] = st_fields[29] = st_fields[41] = &ffi_type_sint32;
+ st_fields[6] = st_fields[18] = st_fields[30] = st_fields[42] = &ffi_type_uint64;
+ st_fields[7] = st_fields[19] = st_fields[31] = st_fields[43] = &ffi_type_sint64;
+ st_fields[8] = st_fields[20] = st_fields[32] = st_fields[44] = &ffi_type_float;
+ st_fields[9] = st_fields[21] = st_fields[33] = st_fields[45] = &ffi_type_double;
+ st_fields[10] = st_fields[22] = st_fields[34] = st_fields[46] = &ffi_type_longdouble;
+ st_fields[11] = st_fields[23] = st_fields[35] = st_fields[47] = &ffi_type_pointer;
+
+ st_fields[50] = NULL;
+
+ argTypes[0] = argTypes[12] = argTypes[24] = argTypes[36] = argTypes[48] = &ffi_type_uint8;
+ argValues[0] = argValues[12] = argValues[24] = argValues[36] = argValues[48] = &ui8;
+ argTypes[1] = argTypes[13] = argTypes[25] = argTypes[37] = argTypes[49] = &ffi_type_sint8;
+ argValues[1] = argValues[13] = argValues[25] = argValues[37] = argValues[49] = &si8;
+ argTypes[2] = argTypes[14] = argTypes[26] = argTypes[38] = &ffi_type_uint16;
+ argValues[2] = argValues[14] = argValues[26] = argValues[38] = &ui16;
+ argTypes[3] = argTypes[15] = argTypes[27] = argTypes[39] = &ffi_type_sint16;
+ argValues[3] = argValues[15] = argValues[27] = argValues[39] = &si16;
+ argTypes[4] = argTypes[16] = argTypes[28] = argTypes[40] = &ffi_type_uint32;
+ argValues[4] = argValues[16] = argValues[28] = argValues[40] = &ui32;
+ argTypes[5] = argTypes[17] = argTypes[29] = argTypes[41] = &ffi_type_sint32;
+ argValues[5] = argValues[17] = argValues[29] = argValues[41] = &si32;
+ argTypes[6] = argTypes[18] = argTypes[30] = argTypes[42] = &ffi_type_uint64;
+ argValues[6] = argValues[18] = argValues[30] = argValues[42] = &ui64;
+ argTypes[7] = argTypes[19] = argTypes[31] = argTypes[43] = &ffi_type_sint64;
+ argValues[7] = argValues[19] = argValues[31] = argValues[43] = &si64;
+ argTypes[8] = argTypes[20] = argTypes[32] = argTypes[44] = &ffi_type_float;
+ argValues[8] = argValues[20] = argValues[32] = argValues[44] = &f;
+ argTypes[9] = argTypes[21] = argTypes[33] = argTypes[45] = &ffi_type_double;
+ argValues[9] = argValues[21] = argValues[33] = argValues[45] = &d;
+ argTypes[10] = argTypes[22] = argTypes[34] = argTypes[46] = &ffi_type_longdouble;
+ argValues[10] = argValues[22] = argValues[34] = argValues[46] = &ld;
+ argTypes[11] = argTypes[23] = argTypes[35] = argTypes[47] = &ffi_type_pointer;
+ argValues[11] = argValues[23] = argValues[35] = argValues[47] = &p;
+
+ argTypes[50] = NULL;
+ argValues[50] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues);
+ /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
+ printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
+ retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
+ retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
+ retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
+ retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
+ retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
+ retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
+ retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
+ retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
+ /* { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_large_fn, NULL, code) == FFI_OK);
+
+ retVal = ((BigStruct(*)(
+ uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
+ uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
+ uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
+ uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
+ uint8_t, int8_t))(code))(
+ ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
+ ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
+ ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
+ ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
+ ui8, si8);
+ /* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
+ printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+ "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
+ retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
+ retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
+ retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
+ retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
+ retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
+ retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
+ retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
+ retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
+ /* { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
+
+ return 0;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct.c
new file mode 100644
index 0000000000..c15e3a0338
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct.c
@@ -0,0 +1,152 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_16byte1 {
+ double a;
+ float b;
+ int c;
+} cls_struct_16byte1;
+
+typedef struct cls_struct_16byte2 {
+ int ii;
+ double dd;
+ float ff;
+} cls_struct_16byte2;
+
+typedef struct cls_struct_combined {
+ cls_struct_16byte1 d;
+ cls_struct_16byte2 e;
+} cls_struct_combined;
+
+cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
+ struct cls_struct_16byte2 b1,
+ struct cls_struct_combined b2)
+{
+ struct cls_struct_combined result;
+
+ result.d.a = b0.a + b1.dd + b2.d.a;
+ result.d.b = b0.b + b1.ff + b2.d.b;
+ result.d.c = b0.c + b1.ii + b2.d.c;
+ result.e.ii = b0.c + b1.ii + b2.e.ii;
+ result.e.dd = b0.a + b1.dd + b2.e.dd;
+ result.e.ff = b0.b + b1.ff + b2.e.ff;
+
+ printf("%g %g %d %d %g %g %g %g %d %d %g %g: %g %g %d %d %g %g\n",
+ b0.a, b0.b, b0.c,
+ b1.ii, b1.dd, b1.ff,
+ b2.d.a, b2.d.b, b2.d.c,
+ b2.e.ii, b2.e.dd, b2.e.ff,
+ result.d.a, result.d.b, result.d.c,
+ result.e.ii, result.e.dd, result.e.ff);
+
+ return result;
+}
+
+static void
+cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_16byte1 b0;
+ struct cls_struct_16byte2 b1;
+ struct cls_struct_combined b2;
+
+ b0 = *(struct cls_struct_16byte1*)(args[0]);
+ b1 = *(struct cls_struct_16byte2*)(args[1]);
+ b2 = *(struct cls_struct_combined*)(args[2]);
+
+
+ *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[5];
+ ffi_type* cls_struct_fields1[5];
+ ffi_type* cls_struct_fields2[5];
+ ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
+ struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
+ struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
+ {3, 1.0, 8.0}};
+ struct cls_struct_combined res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_type2.size = 0;
+ cls_struct_type2.alignment = 0;
+ cls_struct_type2.type = FFI_TYPE_STRUCT;
+ cls_struct_type2.elements = cls_struct_fields2;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_float;
+ cls_struct_fields[2] = &ffi_type_sint;
+ cls_struct_fields[3] = NULL;
+
+ cls_struct_fields1[0] = &ffi_type_sint;
+ cls_struct_fields1[1] = &ffi_type_double;
+ cls_struct_fields1[2] = &ffi_type_float;
+ cls_struct_fields1[3] = NULL;
+
+ cls_struct_fields2[0] = &cls_struct_type;
+ cls_struct_fields2[1] = &cls_struct_type1;
+ cls_struct_fields2[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = &cls_struct_type2;
+ dbl_arg_types[3] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type2,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
+ /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
+ CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
+ CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
+ CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
+ CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
+ CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
+ CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
+ cls_struct_16byte2,
+ cls_struct_combined))
+ (code))(e_dbl, f_dbl, g_dbl);
+ /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
+ CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
+ CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
+ CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
+ CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
+ CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
+ CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct1.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct1.c
new file mode 100644
index 0000000000..477a6b9bde
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct1.c
@@ -0,0 +1,161 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_16byte1 {
+ double a;
+ float b;
+ int c;
+} cls_struct_16byte1;
+
+typedef struct cls_struct_16byte2 {
+ int ii;
+ double dd;
+ float ff;
+} cls_struct_16byte2;
+
+typedef struct cls_struct_combined {
+ cls_struct_16byte1 d;
+ cls_struct_16byte2 e;
+} cls_struct_combined;
+
+cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
+ struct cls_struct_16byte2 b1,
+ struct cls_struct_combined b2,
+ struct cls_struct_16byte1 b3)
+{
+ struct cls_struct_combined result;
+
+ result.d.a = b0.a + b1.dd + b2.d.a;
+ result.d.b = b0.b + b1.ff + b2.d.b;
+ result.d.c = b0.c + b1.ii + b2.d.c;
+ result.e.ii = b0.c + b1.ii + b2.e.ii;
+ result.e.dd = b0.a + b1.dd + b2.e.dd;
+ result.e.ff = b0.b + b1.ff + b2.e.ff;
+
+ printf("%g %g %d %d %g %g %g %g %d %d %g %g %g %g %d: %g %g %d %d %g %g\n",
+ b0.a, b0.b, b0.c,
+ b1.ii, b1.dd, b1.ff,
+ b2.d.a, b2.d.b, b2.d.c,
+ b2.e.ii, b2.e.dd, b2.e.ff,
+ b3.a, b3.b, b3.c,
+ result.d.a, result.d.b, result.d.c,
+ result.e.ii, result.e.dd, result.e.ff);
+
+ return result;
+}
+
+static void
+cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_16byte1 b0;
+ struct cls_struct_16byte2 b1;
+ struct cls_struct_combined b2;
+ struct cls_struct_16byte1 b3;
+
+ b0 = *(struct cls_struct_16byte1*)(args[0]);
+ b1 = *(struct cls_struct_16byte2*)(args[1]);
+ b2 = *(struct cls_struct_combined*)(args[2]);
+ b3 = *(struct cls_struct_16byte1*)(args[3]);
+
+
+ *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[5];
+ ffi_type* cls_struct_fields1[5];
+ ffi_type* cls_struct_fields2[5];
+ ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
+ struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
+ struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
+ {3, 1.0, 8.0}};
+ struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4};
+ struct cls_struct_combined res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_type2.size = 0;
+ cls_struct_type2.alignment = 0;
+ cls_struct_type2.type = FFI_TYPE_STRUCT;
+ cls_struct_type2.elements = cls_struct_fields2;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_float;
+ cls_struct_fields[2] = &ffi_type_sint;
+ cls_struct_fields[3] = NULL;
+
+ cls_struct_fields1[0] = &ffi_type_sint;
+ cls_struct_fields1[1] = &ffi_type_double;
+ cls_struct_fields1[2] = &ffi_type_float;
+ cls_struct_fields1[3] = NULL;
+
+ cls_struct_fields2[0] = &cls_struct_type;
+ cls_struct_fields2[1] = &cls_struct_type1;
+ cls_struct_fields2[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = &cls_struct_type2;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type2,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
+ /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
+ CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
+ CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
+ CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
+ CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
+ CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
+ CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
+ cls_struct_16byte2,
+ cls_struct_combined,
+ cls_struct_16byte1))
+ (code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
+ CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
+ CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
+ CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
+ CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
+ CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
+ CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
+ /* CHECK( 1 == 0); */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct10.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct10.c
new file mode 100644
index 0000000000..3cf2b44abe
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct10.c
@@ -0,0 +1,134 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Sample taken from Alan Modras patch to src/prep_cif.c.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20051010 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ unsigned long long a;
+ unsigned char b;
+} A;
+
+typedef struct B {
+ unsigned char y;
+ struct A x;
+ unsigned int z;
+} B;
+
+typedef struct C {
+ unsigned long long d;
+ unsigned char e;
+} C;
+
+static B B_fn(struct A b2, struct B b3, struct C b4)
+{
+ struct B result;
+
+ result.x.a = b2.a + b3.x.a + b3.z + b4.d;
+ result.x.b = b2.b + b3.x.b + b3.y + b4.e;
+ result.y = b2.b + b3.x.b + b4.e;
+ result.z = 0;
+
+ printf("%d %d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+ (int)b3.x.a, b3.x.b, b3.y, b3.z, (int)b4.d, b4.e,
+ (int)result.x.a, result.x.b, result.y);
+
+ return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct A b0;
+ struct B b1;
+ struct C b2;
+
+ b0 = *(struct A*)(args[0]);
+ b1 = *(struct B*)(args[1]);
+ b2 = *(struct C*)(args[2]);
+
+ *(B*)resp = B_fn(b0, b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[4];
+ ffi_type* cls_struct_fields[3];
+ ffi_type* cls_struct_fields1[4];
+ ffi_type* cls_struct_fields2[3];
+ ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+ ffi_type* dbl_arg_types[4];
+
+ struct A e_dbl = { 1LL, 7};
+ struct B f_dbl = { 99, {12LL , 127}, 255};
+ struct C g_dbl = { 2LL, 9};
+
+ struct B res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_type2.size = 0;
+ cls_struct_type2.alignment = 0;
+ cls_struct_type2.type = FFI_TYPE_STRUCT;
+ cls_struct_type2.elements = cls_struct_fields2;
+
+ cls_struct_fields[0] = &ffi_type_uint64;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ cls_struct_fields1[0] = &ffi_type_uchar;
+ cls_struct_fields1[1] = &cls_struct_type;
+ cls_struct_fields1[2] = &ffi_type_uint;
+ cls_struct_fields1[3] = NULL;
+
+ cls_struct_fields2[0] = &ffi_type_uint64;
+ cls_struct_fields2[1] = &ffi_type_uchar;
+ cls_struct_fields2[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = &cls_struct_type2;
+ dbl_arg_types[3] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = NULL;
+
+ ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 7 12 127 99 255 2 9: 270 242 143" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
+ /* { dg-output "\n1 7 12 127 99 255 2 9: 270 242 143" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct11.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct11.c
new file mode 100644
index 0000000000..351049382c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct11.c
@@ -0,0 +1,121 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check parameter passing with nested structs
+ of a single type. This tests the special cases
+ for homogeneous floating-point aggregates in the
+ AArch64 PCS.
+ Limitations: none.
+ PR: none.
+ Originator: ARM Ltd. */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ float a_x;
+ float a_y;
+} A;
+
+typedef struct B {
+ float b_x;
+ float b_y;
+} B;
+
+typedef struct C {
+ A a;
+ B b;
+} C;
+
+static C C_fn (int x, int y, int z, C source, int i, int j, int k)
+{
+ C result;
+ result.a.a_x = source.a.a_x;
+ result.a.a_y = source.a.a_y;
+ result.b.b_x = source.b.b_x;
+ result.b.b_y = source.b.b_y;
+
+ printf ("%d, %d, %d, %d, %d, %d\n", x, y, z, i, j, k);
+
+ printf ("%.1f, %.1f, %.1f, %.1f, "
+ "%.1f, %.1f, %.1f, %.1f\n",
+ source.a.a_x, source.a.a_y,
+ source.b.b_x, source.b.b_y,
+ result.a.a_x, result.a.a_y,
+ result.b.b_x, result.b.b_y);
+
+ return result;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+
+ ffi_type* struct_fields_source_a[3];
+ ffi_type* struct_fields_source_b[3];
+ ffi_type* struct_fields_source_c[3];
+ ffi_type* arg_types[8];
+
+ ffi_type struct_type_a, struct_type_b, struct_type_c;
+
+ struct A source_fld_a = {1.0, 2.0};
+ struct B source_fld_b = {4.0, 8.0};
+ int k = 1;
+
+ struct C result;
+ struct C source = {source_fld_a, source_fld_b};
+
+ struct_type_a.size = 0;
+ struct_type_a.alignment = 0;
+ struct_type_a.type = FFI_TYPE_STRUCT;
+ struct_type_a.elements = struct_fields_source_a;
+
+ struct_type_b.size = 0;
+ struct_type_b.alignment = 0;
+ struct_type_b.type = FFI_TYPE_STRUCT;
+ struct_type_b.elements = struct_fields_source_b;
+
+ struct_type_c.size = 0;
+ struct_type_c.alignment = 0;
+ struct_type_c.type = FFI_TYPE_STRUCT;
+ struct_type_c.elements = struct_fields_source_c;
+
+ struct_fields_source_a[0] = &ffi_type_float;
+ struct_fields_source_a[1] = &ffi_type_float;
+ struct_fields_source_a[2] = NULL;
+
+ struct_fields_source_b[0] = &ffi_type_float;
+ struct_fields_source_b[1] = &ffi_type_float;
+ struct_fields_source_b[2] = NULL;
+
+ struct_fields_source_c[0] = &struct_type_a;
+ struct_fields_source_c[1] = &struct_type_b;
+ struct_fields_source_c[2] = NULL;
+
+ arg_types[0] = &ffi_type_sint32;
+ arg_types[1] = &ffi_type_sint32;
+ arg_types[2] = &ffi_type_sint32;
+ arg_types[3] = &struct_type_c;
+ arg_types[4] = &ffi_type_sint32;
+ arg_types[5] = &ffi_type_sint32;
+ arg_types[6] = &ffi_type_sint32;
+ arg_types[7] = NULL;
+
+ void *args[7];
+ args[0] = &k;
+ args[1] = &k;
+ args[2] = &k;
+ args[3] = &source;
+ args[4] = &k;
+ args[5] = &k;
+ args[6] = &k;
+ CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 7, &struct_type_c,
+ arg_types) == FFI_OK);
+
+ ffi_call (&cif, FFI_FN (C_fn), &result, args);
+ /* { dg-output "1, 1, 1, 1, 1, 1\n" } */
+ /* { dg-output "1.0, 2.0, 4.0, 8.0, 1.0, 2.0, 4.0, 8.0" } */
+ CHECK (result.a.a_x == source.a.a_x);
+ CHECK (result.a.a_y == source.a.a_y);
+ CHECK (result.b.b_x == source.b.b_x);
+ CHECK (result.b.b_y == source.b.b_y);
+ exit (0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct2.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct2.c
new file mode 100644
index 0000000000..69268cdb8a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct2.c
@@ -0,0 +1,110 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Sample taken from Alan Modras patch to src/prep_cif.c.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030911 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ unsigned long a;
+ unsigned char b;
+} A;
+
+typedef struct B {
+ struct A x;
+ unsigned char y;
+} B;
+
+B B_fn(struct A b0, struct B b1)
+{
+ struct B result;
+
+ result.x.a = b0.a + b1.x.a;
+ result.x.b = b0.b + b1.x.b + b1.y;
+ result.y = b0.b + b1.x.b;
+
+ printf("%lu %d %lu %d %d: %lu %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y,
+ result.x.a, result.x.b, result.y);
+
+ return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct A b0;
+ struct B b1;
+
+ b0 = *(struct A*)(args[0]);
+ b1 = *(struct B*)(args[1]);
+
+ *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[3];
+ ffi_type* cls_struct_fields1[3];
+ ffi_type cls_struct_type, cls_struct_type1;
+ ffi_type* dbl_arg_types[3];
+
+ struct A e_dbl = { 1, 7};
+ struct B f_dbl = {{12 , 127}, 99};
+
+ struct B res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_fields[0] = &ffi_type_ulong;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ cls_struct_fields1[0] = &cls_struct_type;
+ cls_struct_fields1[1] = &ffi_type_uchar;
+ cls_struct_fields1[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 7 12 127 99: 13 233 134" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
+ /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct3.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct3.c
new file mode 100644
index 0000000000..ab18cad733
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct3.c
@@ -0,0 +1,111 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Sample taken from Alan Modras patch to src/prep_cif.c.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030911 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ unsigned long long a;
+ unsigned char b;
+} A;
+
+typedef struct B {
+ struct A x;
+ unsigned char y;
+} B;
+
+B B_fn(struct A b0, struct B b1)
+{
+ struct B result;
+
+ result.x.a = b0.a + b1.x.a;
+ result.x.b = b0.b + b1.x.b + b1.y;
+ result.y = b0.b + b1.x.b;
+
+ printf("%d %d %d %d %d: %d %d %d\n", (int)b0.a, b0.b,
+ (int)b1.x.a, b1.x.b, b1.y,
+ (int)result.x.a, result.x.b, result.y);
+
+ return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct A b0;
+ struct B b1;
+
+ b0 = *(struct A*)(args[0]);
+ b1 = *(struct B*)(args[1]);
+
+ *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[3];
+ ffi_type* cls_struct_fields1[3];
+ ffi_type cls_struct_type, cls_struct_type1;
+ ffi_type* dbl_arg_types[3];
+
+ struct A e_dbl = { 1LL, 7};
+ struct B f_dbl = {{12LL , 127}, 99};
+
+ struct B res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_fields[0] = &ffi_type_uint64;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ cls_struct_fields1[0] = &cls_struct_type;
+ cls_struct_fields1[1] = &ffi_type_uchar;
+ cls_struct_fields1[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 7 12 127 99: 13 233 134" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
+ /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct4.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct4.c
new file mode 100644
index 0000000000..2ffb4d65a0
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct4.c
@@ -0,0 +1,111 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Sample taken from Alan Modras patch to src/prep_cif.c.
+ Limitations: none.
+ PR: PR 25630.
+ Originator: <andreast@gcc.gnu.org> 20051010 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ double a;
+ unsigned char b;
+} A;
+
+typedef struct B {
+ struct A x;
+ unsigned char y;
+} B;
+
+static B B_fn(struct A b2, struct B b3)
+{
+ struct B result;
+
+ result.x.a = b2.a + b3.x.a;
+ result.x.b = b2.b + b3.x.b + b3.y;
+ result.y = b2.b + b3.x.b;
+
+ printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+ (int)b3.x.a, b3.x.b, b3.y,
+ (int)result.x.a, result.x.b, result.y);
+
+ return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct A b0;
+ struct B b1;
+
+ b0 = *(struct A*)(args[0]);
+ b1 = *(struct B*)(args[1]);
+
+ *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[3];
+ ffi_type* cls_struct_fields1[3];
+ ffi_type cls_struct_type, cls_struct_type1;
+ ffi_type* dbl_arg_types[3];
+
+ struct A e_dbl = { 1.0, 7};
+ struct B f_dbl = {{12.0 , 127}, 99};
+
+ struct B res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ cls_struct_fields1[0] = &cls_struct_type;
+ cls_struct_fields1[1] = &ffi_type_uchar;
+ cls_struct_fields1[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 7 12 127 99: 13 233 134" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
+ /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct5.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct5.c
new file mode 100644
index 0000000000..6c79845d98
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct5.c
@@ -0,0 +1,112 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Sample taken from Alan Modras patch to src/prep_cif.c.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20051010 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ long double a;
+ unsigned char b;
+} A;
+
+typedef struct B {
+ struct A x;
+ unsigned char y;
+} B;
+
+static B B_fn(struct A b2, struct B b3)
+{
+ struct B result;
+
+ result.x.a = b2.a + b3.x.a;
+ result.x.b = b2.b + b3.x.b + b3.y;
+ result.y = b2.b + b3.x.b;
+
+ printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+ (int)b3.x.a, b3.x.b, b3.y,
+ (int)result.x.a, result.x.b, result.y);
+
+ return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct A b0;
+ struct B b1;
+
+ b0 = *(struct A*)(args[0]);
+ b1 = *(struct B*)(args[1]);
+
+ *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[3];
+ ffi_type* cls_struct_fields1[3];
+ ffi_type cls_struct_type, cls_struct_type1;
+ ffi_type* dbl_arg_types[3];
+
+ struct A e_dbl = { 1.0, 7};
+ struct B f_dbl = {{12.0 , 127}, 99};
+
+ struct B res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_fields[0] = &ffi_type_longdouble;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ cls_struct_fields1[0] = &cls_struct_type;
+ cls_struct_fields1[1] = &ffi_type_uchar;
+ cls_struct_fields1[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 7 12 127 99: 13 233 134" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
+ /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct6.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct6.c
new file mode 100644
index 0000000000..59d35796f8
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct6.c
@@ -0,0 +1,131 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Sample taken from Alan Modras patch to src/prep_cif.c.
+ Limitations: none.
+ PR: PR 25630.
+ Originator: <andreast@gcc.gnu.org> 20051010 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ double a;
+ unsigned char b;
+} A;
+
+typedef struct B {
+ struct A x;
+ unsigned char y;
+} B;
+
+typedef struct C {
+ long d;
+ unsigned char e;
+} C;
+
+static B B_fn(struct A b2, struct B b3, struct C b4)
+{
+ struct B result;
+
+ result.x.a = b2.a + b3.x.a + b4.d;
+ result.x.b = b2.b + b3.x.b + b3.y + b4.e;
+ result.y = b2.b + b3.x.b + b4.e;
+
+ printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+ (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e,
+ (int)result.x.a, result.x.b, result.y);
+
+ return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct A b0;
+ struct B b1;
+ struct C b2;
+
+ b0 = *(struct A*)(args[0]);
+ b1 = *(struct B*)(args[1]);
+ b2 = *(struct C*)(args[2]);
+
+ *(B*)resp = B_fn(b0, b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[4];
+ ffi_type* cls_struct_fields[3];
+ ffi_type* cls_struct_fields1[3];
+ ffi_type* cls_struct_fields2[3];
+ ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+ ffi_type* dbl_arg_types[4];
+
+ struct A e_dbl = { 1.0, 7};
+ struct B f_dbl = {{12.0 , 127}, 99};
+ struct C g_dbl = { 2, 9};
+
+ struct B res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_type2.size = 0;
+ cls_struct_type2.alignment = 0;
+ cls_struct_type2.type = FFI_TYPE_STRUCT;
+ cls_struct_type2.elements = cls_struct_fields2;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ cls_struct_fields1[0] = &cls_struct_type;
+ cls_struct_fields1[1] = &ffi_type_uchar;
+ cls_struct_fields1[2] = NULL;
+
+ cls_struct_fields2[0] = &ffi_type_slong;
+ cls_struct_fields2[1] = &ffi_type_uchar;
+ cls_struct_fields2[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = &cls_struct_type2;
+ dbl_arg_types[3] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = NULL;
+
+ ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
+ /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct7.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct7.c
new file mode 100644
index 0000000000..27595e6f5c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct7.c
@@ -0,0 +1,111 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Sample taken from Alan Modras patch to src/prep_cif.c.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20051010 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ unsigned long long a;
+ unsigned char b;
+} A;
+
+typedef struct B {
+ struct A x;
+ unsigned char y;
+} B;
+
+static B B_fn(struct A b2, struct B b3)
+{
+ struct B result;
+
+ result.x.a = b2.a + b3.x.a;
+ result.x.b = b2.b + b3.x.b + b3.y;
+ result.y = b2.b + b3.x.b;
+
+ printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+ (int)b3.x.a, b3.x.b, b3.y,
+ (int)result.x.a, result.x.b, result.y);
+
+ return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct A b0;
+ struct B b1;
+
+ b0 = *(struct A*)(args[0]);
+ b1 = *(struct B*)(args[1]);
+
+ *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[3];
+ ffi_type* cls_struct_fields1[3];
+ ffi_type cls_struct_type, cls_struct_type1;
+ ffi_type* dbl_arg_types[3];
+
+ struct A e_dbl = { 1LL, 7};
+ struct B f_dbl = {{12.0 , 127}, 99};
+
+ struct B res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_fields[0] = &ffi_type_uint64;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ cls_struct_fields1[0] = &cls_struct_type;
+ cls_struct_fields1[1] = &ffi_type_uchar;
+ cls_struct_fields1[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 7 12 127 99: 13 233 134" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
+ /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct8.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct8.c
new file mode 100644
index 0000000000..0e6c68281e
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct8.c
@@ -0,0 +1,131 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Sample taken from Alan Modras patch to src/prep_cif.c.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20051010 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ unsigned long long a;
+ unsigned char b;
+} A;
+
+typedef struct B {
+ struct A x;
+ unsigned char y;
+} B;
+
+typedef struct C {
+ unsigned long long d;
+ unsigned char e;
+} C;
+
+static B B_fn(struct A b2, struct B b3, struct C b4)
+{
+ struct B result;
+
+ result.x.a = b2.a + b3.x.a + b4.d;
+ result.x.b = b2.b + b3.x.b + b3.y + b4.e;
+ result.y = b2.b + b3.x.b + b4.e;
+
+ printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+ (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e,
+ (int)result.x.a, result.x.b, result.y);
+
+ return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct A b0;
+ struct B b1;
+ struct C b2;
+
+ b0 = *(struct A*)(args[0]);
+ b1 = *(struct B*)(args[1]);
+ b2 = *(struct C*)(args[2]);
+
+ *(B*)resp = B_fn(b0, b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[4];
+ ffi_type* cls_struct_fields[3];
+ ffi_type* cls_struct_fields1[3];
+ ffi_type* cls_struct_fields2[3];
+ ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+ ffi_type* dbl_arg_types[4];
+
+ struct A e_dbl = { 1LL, 7};
+ struct B f_dbl = {{12LL , 127}, 99};
+ struct C g_dbl = { 2LL, 9};
+
+ struct B res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_type2.size = 0;
+ cls_struct_type2.alignment = 0;
+ cls_struct_type2.type = FFI_TYPE_STRUCT;
+ cls_struct_type2.elements = cls_struct_fields2;
+
+ cls_struct_fields[0] = &ffi_type_uint64;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ cls_struct_fields1[0] = &cls_struct_type;
+ cls_struct_fields1[1] = &ffi_type_uchar;
+ cls_struct_fields1[2] = NULL;
+
+ cls_struct_fields2[0] = &ffi_type_uint64;
+ cls_struct_fields2[1] = &ffi_type_uchar;
+ cls_struct_fields2[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = &cls_struct_type2;
+ dbl_arg_types[3] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = NULL;
+
+ ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
+ /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct9.c b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct9.c
new file mode 100644
index 0000000000..5f7ac67752
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/nested_struct9.c
@@ -0,0 +1,131 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Contains structs as parameter of the struct itself.
+ Sample taken from Alan Modras patch to src/prep_cif.c.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20051010 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ unsigned char a;
+ unsigned long long b;
+} A;
+
+typedef struct B {
+ struct A x;
+ unsigned char y;
+} B;
+
+typedef struct C {
+ unsigned long d;
+ unsigned char e;
+} C;
+
+static B B_fn(struct A b2, struct B b3, struct C b4)
+{
+ struct B result;
+
+ result.x.a = b2.a + b3.x.a + b4.d;
+ result.x.b = b2.b + b3.x.b + b3.y + b4.e;
+ result.y = b2.b + b3.x.b + b4.e;
+
+ printf("%d %d %d %d %d %d %d: %d %d %d\n", b2.a, (int)b2.b,
+ b3.x.a, (int)b3.x.b, b3.y, (int)b4.d, b4.e,
+ result.x.a, (int)result.x.b, result.y);
+
+ return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct A b0;
+ struct B b1;
+ struct C b2;
+
+ b0 = *(struct A*)(args[0]);
+ b1 = *(struct B*)(args[1]);
+ b2 = *(struct C*)(args[2]);
+
+ *(B*)resp = B_fn(b0, b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[4];
+ ffi_type* cls_struct_fields[3];
+ ffi_type* cls_struct_fields1[3];
+ ffi_type* cls_struct_fields2[3];
+ ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+ ffi_type* dbl_arg_types[4];
+
+ struct A e_dbl = { 1, 7LL};
+ struct B f_dbl = {{12.0 , 127}, 99};
+ struct C g_dbl = { 2, 9};
+
+ struct B res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_type2.size = 0;
+ cls_struct_type2.alignment = 0;
+ cls_struct_type2.type = FFI_TYPE_STRUCT;
+ cls_struct_type2.elements = cls_struct_fields2;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uint64;
+ cls_struct_fields[2] = NULL;
+
+ cls_struct_fields1[0] = &cls_struct_type;
+ cls_struct_fields1[1] = &ffi_type_uchar;
+ cls_struct_fields1[2] = NULL;
+
+ cls_struct_fields2[0] = &ffi_type_ulong;
+ cls_struct_fields2[1] = &ffi_type_uchar;
+ cls_struct_fields2[2] = NULL;
+
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = &cls_struct_type2;
+ dbl_arg_types[3] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = NULL;
+
+ ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
+ /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
+ CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+ CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+ CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/problem1.c b/js/src/ctypes/libffi/testsuite/libffi.closures/problem1.c
new file mode 100644
index 0000000000..6a91555a1f
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/problem1.c
@@ -0,0 +1,90 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct my_ffi_struct {
+ double a;
+ double b;
+ double c;
+} my_ffi_struct;
+
+my_ffi_struct callee(struct my_ffi_struct a1, struct my_ffi_struct a2)
+{
+ struct my_ffi_struct result;
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+
+ printf("%g %g %g %g %g %g: %g %g %g\n", a1.a, a1.b, a1.c,
+ a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+ return result;
+}
+
+void stub(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct my_ffi_struct a1;
+ struct my_ffi_struct a2;
+
+ a1 = *(struct my_ffi_struct*)(args[0]);
+ a2 = *(struct my_ffi_struct*)(args[1]);
+
+ *(my_ffi_struct *)resp = callee(a1, a2);
+}
+
+
+int main(void)
+{
+ ffi_type* my_ffi_struct_fields[4];
+ ffi_type my_ffi_struct_type;
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[4];
+ ffi_type* arg_types[3];
+
+ struct my_ffi_struct g = { 1.0, 2.0, 3.0 };
+ struct my_ffi_struct f = { 1.0, 2.0, 3.0 };
+ struct my_ffi_struct res;
+
+ my_ffi_struct_type.size = 0;
+ my_ffi_struct_type.alignment = 0;
+ my_ffi_struct_type.type = FFI_TYPE_STRUCT;
+ my_ffi_struct_type.elements = my_ffi_struct_fields;
+
+ my_ffi_struct_fields[0] = &ffi_type_double;
+ my_ffi_struct_fields[1] = &ffi_type_double;
+ my_ffi_struct_fields[2] = &ffi_type_double;
+ my_ffi_struct_fields[3] = NULL;
+
+ arg_types[0] = &my_ffi_struct_type;
+ arg_types[1] = &my_ffi_struct_type;
+ arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &my_ffi_struct_type,
+ arg_types) == FFI_OK);
+
+ args[0] = &g;
+ args[1] = &f;
+ args[2] = NULL;
+ ffi_call(&cif, FFI_FN(callee), &res, args);
+ /* { dg-output "1 2 3 1 2 3: 2 4 6" } */
+ printf("res: %g %g %g\n", res.a, res.b, res.c);
+ /* { dg-output "\nres: 2 4 6" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, stub, NULL, code) == FFI_OK);
+
+ res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(code))(g, f);
+ /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */
+ printf("res: %g %g %g\n", res.a, res.b, res.c);
+ /* { dg-output "\nres: 2 4 6" } */
+
+ exit(0);;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/stret_large.c b/js/src/ctypes/libffi/testsuite/libffi.closures/stret_large.c
new file mode 100644
index 0000000000..71c2469e1c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/stret_large.c
@@ -0,0 +1,145 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure returning with different structure size.
+ Depending on the ABI. Check bigger struct which overlaps
+ the gp and fp register count on Darwin/AIX/ppc64.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/21/2007 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+/* 13 FPRs: 104 bytes */
+/* 14 FPRs: 112 bytes */
+
+typedef struct struct_108byte {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ double i;
+ double j;
+ double k;
+ double l;
+ double m;
+ int n;
+} struct_108byte;
+
+struct_108byte cls_struct_108byte_fn(
+ struct_108byte b0,
+ struct_108byte b1,
+ struct_108byte b2,
+ struct_108byte b3)
+{
+ struct_108byte result;
+
+ result.a = b0.a + b1.a + b2.a + b3.a;
+ result.b = b0.b + b1.b + b2.b + b3.b;
+ result.c = b0.c + b1.c + b2.c + b3.c;
+ result.d = b0.d + b1.d + b2.d + b3.d;
+ result.e = b0.e + b1.e + b2.e + b3.e;
+ result.f = b0.f + b1.f + b2.f + b3.f;
+ result.g = b0.g + b1.g + b2.g + b3.g;
+ result.h = b0.h + b1.h + b2.h + b3.h;
+ result.i = b0.i + b1.i + b2.i + b3.i;
+ result.j = b0.j + b1.j + b2.j + b3.j;
+ result.k = b0.k + b1.k + b2.k + b3.k;
+ result.l = b0.l + b1.l + b2.l + b3.l;
+ result.m = b0.m + b1.m + b2.m + b3.m;
+ result.n = b0.n + b1.n + b2.n + b3.n;
+
+ printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c,
+ result.d, result.e, result.f, result.g, result.h, result.i,
+ result.j, result.k, result.l, result.m, result.n);
+
+ return result;
+}
+
+static void
+cls_struct_108byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+ struct_108byte b0, b1, b2, b3;
+
+ b0 = *(struct_108byte*)(args[0]);
+ b1 = *(struct_108byte*)(args[1]);
+ b2 = *(struct_108byte*)(args[2]);
+ b3 = *(struct_108byte*)(args[3]);
+
+ *(struct_108byte*)resp = cls_struct_108byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[15];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct_108byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 7 };
+ struct_108byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 4 };
+ struct_108byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 3 };
+ struct_108byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 2 };
+ struct_108byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_double;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_double;
+ cls_struct_fields[7] = &ffi_type_double;
+ cls_struct_fields[8] = &ffi_type_double;
+ cls_struct_fields[9] = &ffi_type_double;
+ cls_struct_fields[10] = &ffi_type_double;
+ cls_struct_fields[11] = &ffi_type_double;
+ cls_struct_fields[12] = &ffi_type_double;
+ cls_struct_fields[13] = &ffi_type_sint32;
+ cls_struct_fields[14] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = &cls_struct_type;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_108byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+ res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_108byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((struct_108byte(*)(struct_108byte, struct_108byte,
+ struct_108byte, struct_108byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+ res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/stret_large2.c b/js/src/ctypes/libffi/testsuite/libffi.closures/stret_large2.c
new file mode 100644
index 0000000000..d9c750ee1c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/stret_large2.c
@@ -0,0 +1,148 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure returning with different structure size.
+ Depending on the ABI. Check bigger struct which overlaps
+ the gp and fp register count on Darwin/AIX/ppc64.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/21/2007 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+/* 13 FPRs: 104 bytes */
+/* 14 FPRs: 112 bytes */
+
+typedef struct struct_116byte {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ double i;
+ double j;
+ double k;
+ double l;
+ double m;
+ double n;
+ int o;
+} struct_116byte;
+
+struct_116byte cls_struct_116byte_fn(
+ struct_116byte b0,
+ struct_116byte b1,
+ struct_116byte b2,
+ struct_116byte b3)
+{
+ struct_116byte result;
+
+ result.a = b0.a + b1.a + b2.a + b3.a;
+ result.b = b0.b + b1.b + b2.b + b3.b;
+ result.c = b0.c + b1.c + b2.c + b3.c;
+ result.d = b0.d + b1.d + b2.d + b3.d;
+ result.e = b0.e + b1.e + b2.e + b3.e;
+ result.f = b0.f + b1.f + b2.f + b3.f;
+ result.g = b0.g + b1.g + b2.g + b3.g;
+ result.h = b0.h + b1.h + b2.h + b3.h;
+ result.i = b0.i + b1.i + b2.i + b3.i;
+ result.j = b0.j + b1.j + b2.j + b3.j;
+ result.k = b0.k + b1.k + b2.k + b3.k;
+ result.l = b0.l + b1.l + b2.l + b3.l;
+ result.m = b0.m + b1.m + b2.m + b3.m;
+ result.n = b0.n + b1.n + b2.n + b3.n;
+ result.o = b0.o + b1.o + b2.o + b3.o;
+
+ printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c,
+ result.d, result.e, result.f, result.g, result.h, result.i,
+ result.j, result.k, result.l, result.m, result.n, result.o);
+
+ return result;
+}
+
+static void
+cls_struct_116byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+ struct_116byte b0, b1, b2, b3;
+
+ b0 = *(struct_116byte*)(args[0]);
+ b1 = *(struct_116byte*)(args[1]);
+ b2 = *(struct_116byte*)(args[2]);
+ b3 = *(struct_116byte*)(args[3]);
+
+ *(struct_116byte*)resp = cls_struct_116byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[16];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct_116byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 7 };
+ struct_116byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 6.0, 4 };
+ struct_116byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 7.0, 3 };
+ struct_116byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 8.0, 2 };
+ struct_116byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_double;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_double;
+ cls_struct_fields[7] = &ffi_type_double;
+ cls_struct_fields[8] = &ffi_type_double;
+ cls_struct_fields[9] = &ffi_type_double;
+ cls_struct_fields[10] = &ffi_type_double;
+ cls_struct_fields[11] = &ffi_type_double;
+ cls_struct_fields[12] = &ffi_type_double;
+ cls_struct_fields[13] = &ffi_type_double;
+ cls_struct_fields[14] = &ffi_type_sint32;
+ cls_struct_fields[15] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = &cls_struct_type;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_116byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+ res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_116byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((struct_116byte(*)(struct_116byte, struct_116byte,
+ struct_116byte, struct_116byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+ res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/stret_medium.c b/js/src/ctypes/libffi/testsuite/libffi.closures/stret_medium.c
new file mode 100644
index 0000000000..973ee02ede
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/stret_medium.c
@@ -0,0 +1,124 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure returning with different structure size.
+ Depending on the ABI. Check bigger struct which overlaps
+ the gp and fp register count on Darwin/AIX/ppc64.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/21/2007 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+typedef struct struct_72byte {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ double i;
+} struct_72byte;
+
+struct_72byte cls_struct_72byte_fn(
+ struct_72byte b0,
+ struct_72byte b1,
+ struct_72byte b2,
+ struct_72byte b3)
+{
+ struct_72byte result;
+
+ result.a = b0.a + b1.a + b2.a + b3.a;
+ result.b = b0.b + b1.b + b2.b + b3.b;
+ result.c = b0.c + b1.c + b2.c + b3.c;
+ result.d = b0.d + b1.d + b2.d + b3.d;
+ result.e = b0.e + b1.e + b2.e + b3.e;
+ result.f = b0.f + b1.f + b2.f + b3.f;
+ result.g = b0.g + b1.g + b2.g + b3.g;
+ result.h = b0.h + b1.h + b2.h + b3.h;
+ result.i = b0.i + b1.i + b2.i + b3.i;
+
+ printf("%g %g %g %g %g %g %g %g %g\n", result.a, result.b, result.c,
+ result.d, result.e, result.f, result.g, result.h, result.i);
+
+ return result;
+}
+
+static void
+cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+ struct_72byte b0, b1, b2, b3;
+
+ b0 = *(struct_72byte*)(args[0]);
+ b1 = *(struct_72byte*)(args[1]);
+ b2 = *(struct_72byte*)(args[2]);
+ b3 = *(struct_72byte*)(args[3]);
+
+ *(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[10];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7.0 };
+ struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0 };
+ struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3.0 };
+ struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2.0 };
+ struct_72byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_double;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_double;
+ cls_struct_fields[7] = &ffi_type_double;
+ cls_struct_fields[8] = &ffi_type_double;
+ cls_struct_fields[9] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = &cls_struct_type;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "22 15 17 25 6 13 19 18 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
+ struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/stret_medium2.c b/js/src/ctypes/libffi/testsuite/libffi.closures/stret_medium2.c
new file mode 100644
index 0000000000..84323d16a9
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/stret_medium2.c
@@ -0,0 +1,125 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure returning with different structure size.
+ Depending on the ABI. Check bigger struct which overlaps
+ the gp and fp register count on Darwin/AIX/ppc64.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/21/2007 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
+#include "ffitest.h"
+
+typedef struct struct_72byte {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ long long i;
+} struct_72byte;
+
+struct_72byte cls_struct_72byte_fn(
+ struct_72byte b0,
+ struct_72byte b1,
+ struct_72byte b2,
+ struct_72byte b3)
+{
+ struct_72byte result;
+
+ result.a = b0.a + b1.a + b2.a + b3.a;
+ result.b = b0.b + b1.b + b2.b + b3.b;
+ result.c = b0.c + b1.c + b2.c + b3.c;
+ result.d = b0.d + b1.d + b2.d + b3.d;
+ result.e = b0.e + b1.e + b2.e + b3.e;
+ result.f = b0.f + b1.f + b2.f + b3.f;
+ result.g = b0.g + b1.g + b2.g + b3.g;
+ result.h = b0.h + b1.h + b2.h + b3.h;
+ result.i = b0.i + b1.i + b2.i + b3.i;
+
+ printf("%g %g %g %g %g %g %g %g %" PRIdLL "\n", result.a, result.b, result.c,
+ result.d, result.e, result.f, result.g, result.h, result.i);
+
+ return result;
+}
+
+static void
+cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+ struct_72byte b0, b1, b2, b3;
+
+ b0 = *(struct_72byte*)(args[0]);
+ b1 = *(struct_72byte*)(args[1]);
+ b2 = *(struct_72byte*)(args[2]);
+ b3 = *(struct_72byte*)(args[3]);
+
+ *(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[10];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 };
+ struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 };
+ struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 };
+ struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 };
+ struct_72byte res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_double;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_double;
+ cls_struct_fields[7] = &ffi_type_double;
+ cls_struct_fields[8] = &ffi_type_sint64;
+ cls_struct_fields[9] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = &cls_struct_type;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "22 15 17 25 6 13 19 18 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
+ struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/testclosure.c b/js/src/ctypes/libffi/testsuite/libffi.closures/testclosure.c
new file mode 100644
index 0000000000..ca31056d8c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/testclosure.c
@@ -0,0 +1,70 @@
+/* Area: closure_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: 41908.
+ Originator: <rfm@gnu.org> 20091102 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_combined {
+ float a;
+ float b;
+ float c;
+ float d;
+} cls_struct_combined;
+
+void cls_struct_combined_fn(struct cls_struct_combined arg)
+{
+ printf("%g %g %g %g\n",
+ arg.a, arg.b,
+ arg.c, arg.d);
+ fflush(stdout);
+}
+
+static void
+cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
+ void** args, void* userdata __UNUSED__)
+{
+ struct cls_struct_combined a0;
+
+ a0 = *(struct cls_struct_combined*)(args[0]);
+
+ cls_struct_combined_fn(a0);
+}
+
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type* cls_struct_fields0[5];
+ ffi_type cls_struct_type0;
+ ffi_type* dbl_arg_types[5];
+
+ struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
+
+ cls_struct_type0.size = 0;
+ cls_struct_type0.alignment = 0;
+ cls_struct_type0.type = FFI_TYPE_STRUCT;
+ cls_struct_type0.elements = cls_struct_fields0;
+
+ cls_struct_fields0[0] = &ffi_type_float;
+ cls_struct_fields0[1] = &ffi_type_float;
+ cls_struct_fields0[2] = &ffi_type_float;
+ cls_struct_fields0[3] = &ffi_type_float;
+ cls_struct_fields0[4] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type0;
+ dbl_arg_types[1] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void,
+ dbl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
+
+ ((void(*)(cls_struct_combined)) (code))(g_dbl);
+ /* { dg-output "4 5 1 8" } */
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/unwindtest.cc b/js/src/ctypes/libffi/testsuite/libffi.closures/unwindtest.cc
new file mode 100644
index 0000000000..e1145657d1
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/unwindtest.cc
@@ -0,0 +1,117 @@
+/* Area: ffi_closure, unwind info
+ Purpose: Check if the unwind information is passed correctly.
+ Limitations: none.
+ PR: none.
+ Originator: Jeff Sturm <jsturm@one-point.com> */
+
+/* { dg-do run { xfail x86_64-apple-darwin* moxie*-*-* } } */
+
+#include "ffitest.h"
+
+void ABI_ATTR
+closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
+ void** args __UNUSED__, void* userdata __UNUSED__)
+{
+ throw 9;
+}
+
+typedef void (*closure_test_type)();
+
+void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+ {
+ *(ffi_arg*)resp =
+ (int)*(float *)args[0] +(int)(*(float *)args[1]) +
+ (int)(*(float *)args[2]) + (int)*(float *)args[3] +
+ (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) +
+ (int)*(float *)args[6] + (int)(*(int *)args[7]) +
+ (int)(*(double*)args[8]) + (int)*(int *)args[9] +
+ (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+ (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+ (int)(*(int *)args[14]) + *(int *)args[15] + (int)(intptr_t)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(float *)args[0], (int)(*(float *)args[1]),
+ (int)(*(float *)args[2]), (int)*(float *)args[3],
+ (int)(*(signed short *)args[4]), (int)(*(float *)args[5]),
+ (int)*(float *)args[6], (int)(*(int *)args[7]),
+ (int)(*(double *)args[8]), (int)*(int *)args[9],
+ (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+ (int)*(int *)args[12], (int)(*(int *)args[13]),
+ (int)(*(int *)args[14]), *(int *)args[15],
+ (int)(intptr_t)userdata, (int)*(ffi_arg*)resp);
+
+ throw (int)*(ffi_arg*)resp;
+}
+
+typedef int (*closure_test_type1)(float, float, float, float, signed short,
+ float, float, int, double, int, int, float,
+ int, int, int, int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[17];
+
+ {
+ cl_arg_types[1] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0,
+ &ffi_type_void, cl_arg_types) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn, NULL, code) == FFI_OK);
+
+ try
+ {
+ (*((closure_test_type)(code)))();
+ } catch (int exception_code)
+ {
+ CHECK(exception_code == 9);
+ }
+
+ printf("part one OK\n");
+ /* { dg-output "part one OK" } */
+ }
+
+ {
+
+ cl_arg_types[0] = &ffi_type_float;
+ cl_arg_types[1] = &ffi_type_float;
+ cl_arg_types[2] = &ffi_type_float;
+ cl_arg_types[3] = &ffi_type_float;
+ cl_arg_types[4] = &ffi_type_sshort;
+ cl_arg_types[5] = &ffi_type_float;
+ cl_arg_types[6] = &ffi_type_float;
+ cl_arg_types[7] = &ffi_type_uint;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_uint;
+ cl_arg_types[10] = &ffi_type_uint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_uint;
+ cl_arg_types[13] = &ffi_type_uint;
+ cl_arg_types[14] = &ffi_type_uint;
+ cl_arg_types[15] = &ffi_type_uint;
+ cl_arg_types[16] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1,
+ (void *) 3 /* userdata */, code) == FFI_OK);
+ try
+ {
+ (*((closure_test_type1)code))
+ (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
+ 19, 21, 1);
+ /* { dg-output "\n1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
+ } catch (int exception_code)
+ {
+ CHECK(exception_code == 255);
+ }
+ printf("part two OK\n");
+ /* { dg-output "\npart two OK" } */
+ }
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc b/js/src/ctypes/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc
new file mode 100644
index 0000000000..153d240940
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc
@@ -0,0 +1,54 @@
+/* Area: ffi_call, unwind info
+ Purpose: Check if the unwind information is passed correctly.
+ Limitations: none.
+ PR: none.
+ Originator: Andreas Tobler <andreast@gcc.gnu.org> 20061213 */
+
+/* { dg-do run { xfail moxie*-*-* } } */
+
+#include "ffitest.h"
+
+static int checking(int a __UNUSED__, short b __UNUSED__,
+ signed char c __UNUSED__)
+{
+ throw 9;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+
+ signed int si;
+ signed short ss;
+ signed char sc;
+
+ args[0] = &ffi_type_sint;
+ values[0] = &si;
+ args[1] = &ffi_type_sshort;
+ values[1] = &ss;
+ args[2] = &ffi_type_schar;
+ values[2] = &sc;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_sint, args) == FFI_OK);
+
+ si = -6;
+ ss = -12;
+ sc = -1;
+ {
+ try
+ {
+ ffi_call(&cif, FFI_FN(checking), &rint, values);
+ } catch (int exception_code)
+ {
+ CHECK(exception_code == 9);
+ }
+ printf("part one OK\n");
+ /* { dg-output "part one OK" } */
+ }
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex.inc
new file mode 100644
index 0000000000..4a812edf05
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex.inc
@@ -0,0 +1,91 @@
+/* -*-c-*- */
+#include "ffitest.h"
+#include <complex.h>
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ _Complex T_C_TYPE b;
+ unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(
+ struct cls_struct_align a1, struct cls_struct_align a2)
+{
+ struct cls_struct_align result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %f,%fi %d %d %f,%fi %d: %d %f,%fi %d\n",
+ a1.a, T_CONV creal (a1.b), T_CONV cimag (a1.b), a1.c,
+ a2.a, T_CONV creal (a2.b), T_CONV cimag (a2.b), a2.c,
+ result.a, T_CONV creal (result.b), T_CONV cimag (result.b), result.c);
+
+ return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_c[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* c_arg_types[5];
+
+ struct cls_struct_align g_c = { 12, 4951 + 7 * I, 127 };
+ struct cls_struct_align f_c = { 1, 9320 + 1 * I, 13 };
+ struct cls_struct_align res_c;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &T_FFI_TYPE;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ c_arg_types[0] = &cls_struct_type;
+ c_arg_types[1] = &cls_struct_type;
+ c_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ c_arg_types) == FFI_OK);
+
+ args_c[0] = &g_c;
+ args_c[1] = &f_c;
+ args_c[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_c, args_c);
+ /* { dg-output "12 4951,7i 127 1 9320,1i 13: 13 14271,8i 140" } */
+ printf("res: %d %f,%fi %d\n",
+ res_c.a, T_CONV creal (res_c.b), T_CONV cimag (res_c.b), res_c.c);
+ /* { dg-output "\nres: 13 14271,8i 140" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_c = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_c, f_c);
+ /* { dg-output "\n12 4951,7i 127 1 9320,1i 13: 13 14271,8i 140" } */
+ printf("res: %d %f,%fi %d\n",
+ res_c.a, T_CONV creal (res_c.b), T_CONV cimag (res_c.b), res_c.c);
+ /* { dg-output "\nres: 13 14271,8i 140" } */
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_double.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_double.c
new file mode 100644
index 0000000000..0dff23ae47
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_double.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_double.inc"
+#include "cls_align_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_float.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_float.c
new file mode 100644
index 0000000000..0affbd07e5
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_float.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_float.inc"
+#include "cls_align_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c
new file mode 100644
index 0000000000..7889ba859b
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_longdouble.inc"
+#include "cls_align_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex.inc
new file mode 100644
index 0000000000..f9374044e8
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex.inc
@@ -0,0 +1,42 @@
+/* -*-c-*- */
+#include "ffitest.h"
+#include <complex.h>
+
+static void cls_ret_complex_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+ {
+ _Complex T_C_TYPE *pa;
+ _Complex T_C_TYPE *pr;
+ pa = (_Complex T_C_TYPE *)args[0];
+ pr = (_Complex T_C_TYPE *)resp;
+ *pr = *pa;
+
+ printf("%.6f,%.6fi: %.6f,%.6fi\n",
+ T_CONV creal (*pa), T_CONV cimag (*pa),
+ T_CONV creal (*pr), T_CONV cimag (*pr));
+ }
+typedef _Complex T_C_TYPE (*cls_ret_complex)(_Complex T_C_TYPE);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[2];
+ _Complex T_C_TYPE res;
+
+ cl_arg_types[0] = &T_FFI_TYPE;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &T_FFI_TYPE, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_complex_fn, NULL, code) == FFI_OK);
+
+ res = (*((cls_ret_complex)code))(0.125 + 128.0 * I);
+ printf("res: %.6f,%.6fi\n", T_CONV creal (res), T_CONV cimag (res));
+ CHECK (res == (0.125 + 128.0 * I));
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_double.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_double.c
new file mode 100644
index 0000000000..05e35340e0
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_double.c
@@ -0,0 +1,10 @@
+/* Area: closure_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_double.inc"
+#include "cls_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_float.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_float.c
new file mode 100644
index 0000000000..5df7849d4c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_float.c
@@ -0,0 +1,10 @@
+/* Area: closure_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_float.inc"
+#include "cls_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_longdouble.c
new file mode 100644
index 0000000000..2b1c320a20
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_longdouble.c
@@ -0,0 +1,10 @@
+/* Area: closure_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_longdouble.inc"
+#include "cls_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct.inc
new file mode 100644
index 0000000000..df8708d1c4
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct.inc
@@ -0,0 +1,71 @@
+/* -*-c-*- */
+#include "ffitest.h"
+#include <complex.h>
+
+typedef struct Cs {
+ _Complex T_C_TYPE x;
+ _Complex T_C_TYPE y;
+} Cs;
+
+Cs gc;
+
+void
+closure_test_fn(Cs p)
+{
+ printf("%.1f,%.1fi %.1f,%.1fi\n",
+ T_CONV creal (p.x), T_CONV cimag (p.x),
+ T_CONV creal (p.y), T_CONV cimag (p.y));
+ gc = p;
+}
+
+void
+closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
+ void** args, void* userdata __UNUSED__)
+{
+ closure_test_fn(*(Cs*)args[0]);
+}
+
+int main(int argc __UNUSED__, char** argv __UNUSED__)
+{
+ ffi_cif cif;
+
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type *cl_arg_types[1];
+
+ ffi_type ts1_type;
+ ffi_type* ts1_type_elements[4];
+
+ Cs arg = { 1.0 + 11.0 * I, 2.0 + 22.0 * I};
+
+ ts1_type.size = 0;
+ ts1_type.alignment = 0;
+ ts1_type.type = FFI_TYPE_STRUCT;
+ ts1_type.elements = ts1_type_elements;
+
+ ts1_type_elements[0] = &T_FFI_TYPE;
+ ts1_type_elements[1] = &T_FFI_TYPE;
+ ts1_type_elements[2] = NULL;
+
+ cl_arg_types[0] = &ts1_type;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_void, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
+
+ gc.x = 0.0 + 0.0 * I;
+ gc.y = 0.0 + 0.0 * I;
+ ((void*(*)(Cs))(code))(arg);
+ /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */
+ CHECK (gc.x == arg.x && gc.y == arg.y);
+
+ gc.x = 0.0 + 0.0 * I;
+ gc.y = 0.0 + 0.0 * I;
+ closure_test_fn(arg);
+ /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */
+ CHECK (gc.x == arg.x && gc.y == arg.y);
+
+ return 0;
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_double.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_double.c
new file mode 100644
index 0000000000..ec71346a3f
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_double.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check complex arguments in structs.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_double.inc"
+#include "cls_complex_struct.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_float.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_float.c
new file mode 100644
index 0000000000..96fdf75043
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_float.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check complex arguments in structs.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_float.inc"
+#include "cls_complex_struct.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c
new file mode 100644
index 0000000000..005b467398
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check complex arguments in structs.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_longdouble.inc"
+#include "cls_complex_struct.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va.inc
new file mode 100644
index 0000000000..8a3e15f0f6
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va.inc
@@ -0,0 +1,80 @@
+/* -*-c-*- */
+#include "ffitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <complex.h>
+
+static _Complex T_C_TYPE gComplexValue1 = 1 + 2 * I;
+static _Complex T_C_TYPE gComplexValue2 = 3 + 4 * I;
+
+static int cls_variadic(const char *format, ...)
+{
+ va_list ap;
+ _Complex T_C_TYPE p1, p2;
+
+ va_start (ap, format);
+ p1 = va_arg (ap, _Complex T_C_TYPE);
+ p2 = va_arg (ap, _Complex T_C_TYPE);
+ va_end (ap);
+
+ return printf(format, T_CONV creal (p1), T_CONV cimag (p1),
+ T_CONV creal (p2), T_CONV cimag (p2));
+}
+
+static void
+cls_complex_va_fn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ char* format = *(char**)args[0];
+ gComplexValue1 = *(_Complex T_C_TYPE*)args[1];
+ gComplexValue2 = *(_Complex T_C_TYPE*)args[2];
+
+ *(ffi_arg*)resp =
+ printf(format,
+ T_CONV creal (gComplexValue1), T_CONV cimag (gComplexValue1),
+ T_CONV creal (gComplexValue2), T_CONV cimag (gComplexValue2));
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[4];
+ ffi_type* arg_types[4];
+ char *format = "%.1f,%.1fi %.1f,%.1fi\n";
+
+ _Complex T_C_TYPE complexArg1 = 1.0 + 22.0 *I;
+ _Complex T_C_TYPE complexArg2 = 333.0 + 4444.0 *I;
+ ffi_arg res = 0;
+
+ arg_types[0] = &ffi_type_pointer;
+ arg_types[1] = &T_FFI_TYPE;
+ arg_types[2] = &T_FFI_TYPE;
+ arg_types[3] = NULL;
+
+ /* This printf call is variadic */
+ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 3, &ffi_type_sint,
+ arg_types) == FFI_OK);
+
+ args[0] = &format;
+ args[1] = &complexArg1;
+ args[2] = &complexArg2;
+ args[3] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_variadic), &res, args);
+ printf("res: %d\n", (int) res);
+ CHECK (res == 24);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_complex_va_fn, NULL, code)
+ == FFI_OK);
+
+ res = ((int(*)(char *, ...))(code))(format, complexArg1, complexArg2);
+ CHECK (gComplexValue1 == complexArg1);
+ CHECK (gComplexValue2 == complexArg2);
+ printf("res: %d\n", (int) res);
+ CHECK (res == 24);
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_double.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_double.c
new file mode 100644
index 0000000000..879ccf3b81
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_double.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call, closure_call
+ Purpose: Test complex' passed in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_double.inc"
+#include "cls_complex_va.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_float.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_float.c
new file mode 100644
index 0000000000..2b17826045
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_float.c
@@ -0,0 +1,16 @@
+/* Area: ffi_call, closure_call
+ Purpose: Test complex' passed in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+/* Alpha splits _Complex into two arguments. It's illegal to pass
+ float through varargs, so _Complex float goes badly. In sort of
+ gets passed as _Complex double, but the compiler doesn't agree
+ with itself on this issue. */
+/* { dg-do run { xfail alpha*-*-* } } */
+
+#include "complex_defs_float.inc"
+#include "cls_complex_va.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c
new file mode 100644
index 0000000000..6eca9656ea
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call, closure_call
+ Purpose: Test complex' passed in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_longdouble.inc"
+#include "cls_complex_va.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/complex.exp b/js/src/ctypes/libffi/testsuite/libffi.complex/complex.exp
new file mode 100644
index 0000000000..4631db285a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/complex.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+dg-init
+libffi-init
+
+global srcdir subdir
+
+set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]]
+
+if { [libffi_feature_test "#ifdef FFI_TARGET_HAS_COMPLEX_TYPE"] } {
+ run-many-tests $tlist ""
+} else {
+ foreach test $tlist {
+ unsupported "$test"
+ }
+}
+
+dg-finish
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/complex.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/complex.inc
new file mode 100644
index 0000000000..515ae3e60d
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/complex.inc
@@ -0,0 +1,51 @@
+/* -*-c-*-*/
+#include "ffitest.h"
+#include <complex.h>
+
+static _Complex T_C_TYPE f_complex(_Complex T_C_TYPE c, int x, int *py)
+{
+ c = -(2 * creal (c)) + (cimag (c) + 1)* I;
+ *py += x;
+
+ return c;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+
+ _Complex T_C_TYPE tc_arg;
+ _Complex T_C_TYPE tc_result;
+ int tc_int_arg_x;
+ int tc_y;
+ int *tc_ptr_arg_y = &tc_y;
+
+ args[0] = &T_FFI_TYPE;
+ args[1] = &ffi_type_sint;
+ args[2] = &ffi_type_pointer;
+ values[0] = &tc_arg;
+ values[1] = &tc_int_arg_x;
+ values[2] = &tc_ptr_arg_y;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &T_FFI_TYPE, args) == FFI_OK);
+
+ tc_arg = 1 + 7 * I;
+ tc_int_arg_x = 1234;
+ tc_y = 9876;
+ ffi_call(&cif, FFI_FN(f_complex), &tc_result, values);
+
+ printf ("%f,%fi %f,%fi, x %d 1234, y %d 11110\n",
+ T_CONV creal (tc_result), T_CONV cimag (tc_result),
+ T_CONV creal (2.0), T_CONV creal (8.0), tc_int_arg_x, tc_y);
+
+ CHECK (creal (tc_result) == -2);
+ CHECK (cimag (tc_result) == 8);
+ CHECK (tc_int_arg_x == 1234);
+ CHECK (*tc_ptr_arg_y == 11110);
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_double.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_double.inc
new file mode 100644
index 0000000000..3583e166d6
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_double.inc
@@ -0,0 +1,7 @@
+/* -*-c-*- */
+/* Complex base type. */
+#define T_FFI_TYPE ffi_type_complex_double
+/* C type corresponding to the base type. */
+#define T_C_TYPE double
+/* C cast for a value of type T_C_TYPE that is passed to printf. */
+#define T_CONV
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_float.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_float.inc
new file mode 100644
index 0000000000..bbd9375cbf
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_float.inc
@@ -0,0 +1,7 @@
+/* -*-c-*- */
+/* Complex base type. */
+#define T_FFI_TYPE ffi_type_complex_float
+/* C type corresponding to the base type. */
+#define T_C_TYPE float
+/* C cast for a value of type T_C_TYPE that is passed to printf. */
+#define T_CONV (double)
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc
new file mode 100644
index 0000000000..14b9f243f4
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc
@@ -0,0 +1,7 @@
+/* -*-c-*- */
+/* Complex base type. */
+#define T_FFI_TYPE ffi_type_complex_longdouble
+/* C type corresponding to the base type. */
+#define T_C_TYPE long double
+/* C cast for a value of type T_C_TYPE that is passed to printf. */
+#define T_CONV
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/complex_double.c b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_double.c
new file mode 100644
index 0000000000..8a3297b2a2
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_double.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check complex types.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_double.inc"
+#include "complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/complex_float.c b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_float.c
new file mode 100644
index 0000000000..5044ebbcaa
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_float.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check complex types.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_float.inc"
+#include "complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/complex_int.c b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_int.c
new file mode 100644
index 0000000000..bac319081e
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_int.c
@@ -0,0 +1,86 @@
+/* Area: ffi_call
+ Purpose: Check non-standard complex types.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+#include "ffi.h"
+#include <complex.h>
+
+_Complex int f_complex(_Complex int c, int x, int *py)
+{
+ __real__ c = -2 * __real__ c;
+ __imag__ c = __imag__ c + 1;
+ *py += x;
+ return c;
+}
+
+/*
+ * This macro can be used to define new complex type descriptors
+ * in a platform independent way.
+ *
+ * name: Name of the new descriptor is ffi_type_complex_<name>.
+ * type: The C base type of the complex type.
+ */
+#define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \
+ static ffi_type *ffi_elements_complex_##name [2] = { \
+ (ffi_type *)(&ffitype), NULL \
+ }; \
+ struct struct_align_complex_##name { \
+ char c; \
+ _Complex type x; \
+ }; \
+ ffi_type ffi_type_complex_##name = { \
+ sizeof(_Complex type), \
+ offsetof(struct struct_align_complex_##name, x), \
+ FFI_TYPE_COMPLEX, \
+ (ffi_type **)ffi_elements_complex_##name \
+ }
+
+/* Define new complex type descriptors using the macro: */
+/* ffi_type_complex_sint */
+FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint);
+/* ffi_type_complex_uchar */
+FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8);
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+
+ _Complex int tc_arg;
+ _Complex int tc_result;
+ int tc_int_arg_x;
+ int tc_y;
+ int *tc_ptr_arg_y = &tc_y;
+
+ args[0] = &ffi_type_complex_sint;
+ args[1] = &ffi_type_sint;
+ args[2] = &ffi_type_pointer;
+ values[0] = &tc_arg;
+ values[1] = &tc_int_arg_x;
+ values[2] = &tc_ptr_arg_y;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_complex_sint, args)
+ == FFI_OK);
+
+ tc_arg = 1 + 7 * I;
+ tc_int_arg_x = 1234;
+ tc_y = 9876;
+ ffi_call(&cif, FFI_FN(f_complex), &tc_result, values);
+
+ printf ("%d,%di %d,%di, x %d 1234, y %d 11110\n",
+ (int)tc_result, (int)(tc_result * -I), 2, 8, tc_int_arg_x, tc_y);
+ /* dg-output "-2,8i 2,8i, x 1234 1234, y 11110 11110" */
+ CHECK (creal (tc_result) == -2);
+ CHECK (cimag (tc_result) == 8);
+ CHECK (tc_int_arg_x == 1234);
+ CHECK (*tc_ptr_arg_y == 11110);
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/complex_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_longdouble.c
new file mode 100644
index 0000000000..7e78366093
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/complex_longdouble.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check complex types.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_longdouble.inc"
+#include "complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/ffitest.h b/js/src/ctypes/libffi/testsuite/libffi.complex/ffitest.h
new file mode 100644
index 0000000000..d27d362d6a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/ffitest.h
@@ -0,0 +1 @@
+#include "../libffi.call/ffitest.h"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex.inc
new file mode 100644
index 0000000000..e37a774397
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex.inc
@@ -0,0 +1,78 @@
+/* -*-c-*- */
+#include "ffitest.h"
+
+#include <stdlib.h>
+#include <complex.h>
+
+static _Complex T_C_TYPE many(_Complex T_C_TYPE c1,
+ _Complex T_C_TYPE c2,
+ _Complex T_C_TYPE c3,
+ _Complex T_C_TYPE c4,
+ _Complex T_C_TYPE c5,
+ _Complex T_C_TYPE c6,
+ _Complex T_C_TYPE c7,
+ _Complex T_C_TYPE c8,
+ _Complex T_C_TYPE c9,
+ _Complex T_C_TYPE c10,
+ _Complex T_C_TYPE c11,
+ _Complex T_C_TYPE c12,
+ _Complex T_C_TYPE c13)
+{
+ printf("0 :%f,%fi\n"
+ "1 :%f,%fi\n"
+ "2 :%f,%fi\n"
+ "3 :%f,%fi\n"
+ "4 :%f,%fi\n"
+ "5 :%f,%fi\n"
+ "6 :%f,%fi\n"
+ "7 :%f,%fi\n"
+ "8 :%f,%fi\n"
+ "9 :%f,%fi\n"
+ "10:%f,%fi\n"
+ "11:%f,%fi\n"
+ "12:%f,%fi\n",
+ T_CONV creal (c1), T_CONV cimag (c1),
+ T_CONV creal (c2), T_CONV cimag (c2),
+ T_CONV creal (c3), T_CONV cimag (c3),
+ T_CONV creal (c4), T_CONV cimag (c4),
+ T_CONV creal (c5), T_CONV cimag (c5),
+ T_CONV creal (c6), T_CONV cimag (c6),
+ T_CONV creal (c7), T_CONV cimag (c7),
+ T_CONV creal (c8), T_CONV cimag (c8),
+ T_CONV creal (c9), T_CONV cimag (c9),
+ T_CONV creal (c10), T_CONV cimag (c10),
+ T_CONV creal (c11), T_CONV cimag (c11),
+ T_CONV creal (c12), T_CONV cimag (c12),
+ T_CONV creal (c13), T_CONV cimag (c13));
+
+ return (c1+c2-c3-c4+c5+c6+c7-c8-c9-c10-c11+c12+c13);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[13];
+ void *values[13];
+ _Complex T_C_TYPE ca[13];
+ _Complex T_C_TYPE c, cc;
+ int i;
+
+ for (i = 0; i < 13; i++)
+ {
+ args[i] = &T_FFI_TYPE;
+ values[i] = &ca[i];
+ ca[i] = i + (-20 - i) * I;
+ }
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, &T_FFI_TYPE, args) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(many), &c, values);
+
+ cc = many(ca[0], ca[1], ca[2], ca[3], ca[4], ca[5], ca[6], ca[7], ca[8],
+ ca[9], ca[10], ca[11], ca[12]);
+ CHECK(creal (cc) == creal (c));
+ CHECK(cimag (cc) == cimag (c));
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_double.c b/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_double.c
new file mode 100644
index 0000000000..3fd53c3354
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_double.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex, with many arguments
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_double.inc"
+#include "many_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_float.c b/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_float.c
new file mode 100644
index 0000000000..c43d21cd9e
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_float.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex, with many arguments
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_float.inc"
+#include "many_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_longdouble.c
new file mode 100644
index 0000000000..dbab723969
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/many_complex_longdouble.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex, with many arguments
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_longdouble.inc"
+#include "many_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex.inc
new file mode 100644
index 0000000000..8bf0c1fbab
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex.inc
@@ -0,0 +1,37 @@
+/* -*-c-*- */
+#include "ffitest.h"
+#include <complex.h>
+
+static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c)
+{
+ printf ("%f,%fi\n", T_CONV creal (c), T_CONV cimag (c));
+ return 2 * c;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ _Complex T_C_TYPE c, rc, rc2;
+ T_C_TYPE cr, ci;
+
+ args[0] = &T_FFI_TYPE;
+ values[0] = &c;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &T_FFI_TYPE, args) == FFI_OK);
+
+ for (cr = -127.0; cr < 127; cr++)
+ {
+ ci = 1000.0 - cr;
+ c = cr + ci * I;
+ ffi_call(&cif, FFI_FN(return_c), &rc, values);
+ rc2 = return_c(c);
+ printf ("%f,%fi vs %f,%fi\n",
+ T_CONV creal (rc), T_CONV cimag (rc),
+ T_CONV creal (rc2), T_CONV cimag (rc2));
+ CHECK(rc == 2 * c);
+ }
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1.inc
new file mode 100644
index 0000000000..7cecc0fefa
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1.inc
@@ -0,0 +1,41 @@
+/* -*-c-*- */
+#include "ffitest.h"
+#include <complex.h>
+
+static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c1, float fl2, unsigned int in3, _Complex T_C_TYPE c4)
+{
+ return c1 + fl2 + in3 + c4;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ _Complex T_C_TYPE c1, c4, rc, rc2;
+ float fl2;
+ unsigned int in3;
+ args[0] = &T_FFI_TYPE;
+ args[1] = &ffi_type_float;
+ args[2] = &ffi_type_uint;
+ args[3] = &T_FFI_TYPE;
+ values[0] = &c1;
+ values[1] = &fl2;
+ values[2] = &in3;
+ values[3] = &c4;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &T_FFI_TYPE, args) == FFI_OK);
+ c1 = 127.0 + 255.0 * I;
+ fl2 = 128.0;
+ in3 = 255;
+ c4 = 512.7 + 1024.1 * I;
+
+ ffi_call(&cif, FFI_FN(return_c), &rc, values);
+ rc2 = return_c(c1, fl2, in3, c4);
+ printf ("%f,%fi vs %f,%fi\n",
+ T_CONV creal (rc), T_CONV cimag (rc),
+ T_CONV creal (rc2), T_CONV cimag (rc2));
+ CHECK(rc == rc2);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_double.c b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_double.c
new file mode 100644
index 0000000000..727410d563
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_double.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_double.inc"
+#include "return_complex1.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_float.c b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_float.c
new file mode 100644
index 0000000000..a2aeada847
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_float.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_float.inc"
+#include "return_complex1.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_longdouble.c
new file mode 100644
index 0000000000..103504bf64
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex1_longdouble.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_longdouble.inc"
+#include "return_complex1.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2.inc b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2.inc
new file mode 100644
index 0000000000..265170bf71
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2.inc
@@ -0,0 +1,44 @@
+/* -*-c-*- */
+#include "ffitest.h"
+#include <complex.h>
+
+_Complex T_C_TYPE
+return_c(_Complex T_C_TYPE c1, _Complex T_C_TYPE c2,
+ unsigned int in3, _Complex T_C_TYPE c4)
+{
+ volatile _Complex T_C_TYPE r = c1 + c2 + in3 + c4;
+ return r;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ _Complex T_C_TYPE c1, c2, c4, rc, rc2;
+ unsigned int in3;
+ args[0] = &T_FFI_TYPE;
+ args[1] = &T_FFI_TYPE;
+ args[2] = &ffi_type_uint;
+ args[3] = &T_FFI_TYPE;
+ values[0] = &c1;
+ values[1] = &c2;
+ values[2] = &in3;
+ values[3] = &c4;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &T_FFI_TYPE, args) == FFI_OK);
+ c1 = 127.0 + 255.0 * I;
+ c2 = 128.0 + 256.0;
+ in3 = 255;
+ c4 = 512.7 + 1024.1 * I;
+
+ ffi_call(&cif, FFI_FN(return_c), &rc, values);
+ rc2 = return_c(c1, c2, in3, c4);
+ printf ("%f,%fi vs %f,%fi\n",
+ T_CONV creal (rc), T_CONV cimag (rc),
+ T_CONV creal (rc2), T_CONV cimag (rc2));
+ CHECK(rc == rc2);
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_double.c b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_double.c
new file mode 100644
index 0000000000..ab9efacb4a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_double.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_double.inc"
+#include "return_complex2.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_float.c b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_float.c
new file mode 100644
index 0000000000..d7f22c2a0c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_float.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_float.inc"
+#include "return_complex2.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_longdouble.c
new file mode 100644
index 0000000000..3edea629df
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex2_longdouble.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_longdouble.inc"
+#include "return_complex2.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_double.c b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_double.c
new file mode 100644
index 0000000000..e2497cc84a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_double.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_double.inc"
+#include "return_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_float.c b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_float.c
new file mode 100644
index 0000000000..a35528ff93
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_float.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_float.inc"
+#include "return_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_longdouble.c b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_longdouble.c
new file mode 100644
index 0000000000..142d7becba
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.complex/return_complex_longdouble.c
@@ -0,0 +1,10 @@
+/* Area: ffi_call
+ Purpose: Check return value complex.
+ Limitations: none.
+ PR: none.
+ Originator: <vogt@linux.vnet.ibm.com>. */
+
+/* { dg-do run } */
+
+#include "complex_defs_longdouble.inc"
+#include "return_complex.inc"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.go/aa-direct.c b/js/src/ctypes/libffi/testsuite/libffi.go/aa-direct.c
new file mode 100644
index 0000000000..b00c404ab3
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.go/aa-direct.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+
+#include "static-chain.h"
+
+#if defined(__GNUC__) && !defined(__clang__) && defined(STATIC_CHAIN_REG)
+
+#include "ffitest.h"
+
+/* Blatent assumption here that the prologue doesn't clobber the
+ static chain for trivial functions. If this is not true, don't
+ define STATIC_CHAIN_REG, and we'll test what we can via other tests. */
+void *doit(void)
+{
+ register void *chain __asm__(STATIC_CHAIN_REG);
+ return chain;
+}
+
+int main()
+{
+ ffi_cif cif;
+ void *result;
+
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK);
+
+ ffi_call_go(&cif, FFI_FN(doit), &result, NULL, &result);
+
+ CHECK(result == &result);
+
+ return 0;
+}
+
+#else /* UNSUPPORTED */
+int main() { return 0; }
+#endif
diff --git a/js/src/ctypes/libffi/testsuite/libffi.go/closure1.c b/js/src/ctypes/libffi/testsuite/libffi.go/closure1.c
new file mode 100644
index 0000000000..7b34afc88c
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.go/closure1.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+void doit(ffi_cif *cif, void *rvalue, void **avalue, void *closure)
+{
+ (void)cif;
+ (void)avalue;
+ *(void **)rvalue = closure;
+}
+
+typedef void * (*FN)(void);
+
+int main()
+{
+ ffi_cif cif;
+ ffi_go_closure cl;
+ void *result;
+
+ CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK);
+ CHECK(ffi_prep_go_closure(&cl, &cif, doit) == FFI_OK);
+
+ ffi_call_go(&cif, FFI_FN(*(FN *)&cl), &result, NULL, &cl);
+
+ CHECK(result == &cl);
+
+ exit(0);
+}
diff --git a/js/src/ctypes/libffi/testsuite/libffi.go/ffitest.h b/js/src/ctypes/libffi/testsuite/libffi.go/ffitest.h
new file mode 100644
index 0000000000..d27d362d6a
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.go/ffitest.h
@@ -0,0 +1 @@
+#include "../libffi.call/ffitest.h"
diff --git a/js/src/ctypes/libffi/testsuite/libffi.go/go.exp b/js/src/ctypes/libffi/testsuite/libffi.go/go.exp
new file mode 100644
index 0000000000..100c5e75b4
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.go/go.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+dg-init
+libffi-init
+
+global srcdir subdir
+
+set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]]
+
+if { [libffi_feature_test "#ifdef FFI_GO_CLOSURES"] } {
+ run-many-tests $tlist ""
+} else {
+ foreach test $tlist {
+ unsupported "$test"
+ }
+}
+
+dg-finish
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/js/src/ctypes/libffi/testsuite/libffi.go/static-chain.h b/js/src/ctypes/libffi/testsuite/libffi.go/static-chain.h
new file mode 100644
index 0000000000..3675b40a54
--- /dev/null
+++ b/js/src/ctypes/libffi/testsuite/libffi.go/static-chain.h
@@ -0,0 +1,19 @@
+#ifdef __aarch64__
+# define STATIC_CHAIN_REG "x18"
+#elif defined(__alpha__)
+# define STATIC_CHAIN_REG "$1"
+#elif defined(__arm__)
+# define STATIC_CHAIN_REG "ip"
+#elif defined(__sparc__)
+# if defined(__arch64__) || defined(__sparcv9)
+# define STATIC_CHAIN_REG "g5"
+# else
+# define STATIC_CHAIN_REG "g2"
+# endif
+#elif defined(__x86_64__)
+# define STATIC_CHAIN_REG "r10"
+#elif defined(__i386__)
+# ifndef ABI_NUM
+# define STATIC_CHAIN_REG "ecx" /* FFI_DEFAULT_ABI only */
+# endif
+#endif