├── testsuite
├── config
│ └── default.exp
├── libffi.go
│ ├── ffitest.h
│ ├── static-chain.h
│ ├── closure1.c
│ ├── aa-direct.c
│ └── go.exp
├── libffi.complex
│ ├── ffitest.h
│ ├── complex_float.c
│ ├── complex_double.c
│ ├── complex_defs_double.inc
│ ├── complex_longdouble.c
│ ├── cls_complex_float.c
│ ├── complex_defs_float.inc
│ ├── cls_complex_double.c
│ ├── complex_defs_longdouble.inc
│ ├── return_complex1_double.c
│ ├── return_complex1_float.c
│ ├── return_complex2_double.c
│ ├── return_complex2_float.c
│ ├── return_complex_double.c
│ ├── return_complex_float.c
│ ├── cls_complex_longdouble.c
│ ├── return_complex1_longdouble.c
│ ├── return_complex2_longdouble.c
│ ├── return_complex_longdouble.c
│ ├── many_complex_double.c
│ ├── many_complex_float.c
│ ├── many_complex_longdouble.c
│ ├── cls_align_complex_double.c
│ ├── cls_align_complex_float.c
│ ├── cls_complex_struct_double.c
│ ├── cls_complex_struct_float.c
│ ├── cls_complex_va_double.c
│ ├── cls_align_complex_longdouble.c
│ ├── cls_complex_struct_longdouble.c
│ ├── cls_complex_va_longdouble.c
│ ├── cls_complex_va_float.c
│ ├── return_complex.inc
│ ├── return_complex1.inc
│ ├── return_complex2.inc
│ ├── complex.exp
│ ├── cls_complex.inc
│ ├── complex.inc
│ ├── cls_complex_struct.inc
│ └── many_complex.inc
├── libffi.call
│ ├── err_bad_typedef.c
│ ├── return_ldl.c
│ ├── return_fl.c
│ ├── return_sc.c
│ ├── return_sl.c
│ ├── return_dbl.c
│ ├── return_fl1.c
│ ├── return_uc.c
│ ├── return_ul.c
│ ├── return_ll.c
│ ├── strlen.c
│ ├── return_fl3.c
│ ├── negint.c
│ ├── return_dbl2.c
│ ├── align_mixed.c
│ ├── return_dbl1.c
│ ├── align_stdcall.c
│ ├── strlen2.c
│ ├── strlen3.c
│ ├── return_ll1.c
│ ├── offsets.c
│ ├── struct10.c
│ ├── return_fl2.c
│ ├── many2.c
│ ├── strlen4.c
│ ├── float.c
│ ├── float1.c
│ ├── struct3.c
│ ├── uninitialized.c
│ ├── float4.c
│ ├── many.c
│ ├── promotion.c
│ ├── struct4.c
│ ├── struct6.c
│ ├── struct1.c
│ ├── struct5.c
│ ├── struct9.c
│ ├── struct2.c
│ ├── float2.c
│ ├── many_double.c
│ ├── float3.c
│ ├── many_mixed.c
│ ├── call.exp
│ ├── struct7.c
│ └── struct8.c
├── libffi.bhaible
│ └── Makefile
├── libffi.closures
│ ├── err_bad_abi.c
│ ├── cls_sint.c
│ ├── cls_float.c
│ ├── cls_uchar.c
│ ├── cls_schar.c
│ ├── cls_sshort.c
│ ├── cls_ulong_va.c
│ ├── cls_double.c
│ ├── cls_uchar_va.c
│ ├── cls_uint.c
│ ├── cls_uint_va.c
│ ├── cls_ushort_va.c
│ ├── cls_ushort.c
│ ├── unwindtest_ffi_call.cc
│ ├── cls_dbls_struct.c
│ ├── closure_simple.c
│ ├── cls_ulonglong.c
│ ├── cls_double_va.c
│ ├── cls_longdouble_va.c
│ ├── cls_many_mixed_float_double.c
│ ├── testclosure.c
│ ├── cls_multi_schar.c
│ ├── cls_multi_sshort.c
│ ├── cls_multi_ushort.c
│ ├── cls_many_mixed_args.c
│ ├── cls_pointer.c
│ └── closure.exp
└── lib
│ └── wrapper.exp
├── doc
├── libffi.pdf
├── Makefile.am
├── stamp-vti
└── version.texi
├── msvc_build
└── aarch64
│ ├── Ffi_staticLib.vcxproj.user
│ └── Ffi_staticLib.sln
├── src
├── arm
│ └── internal.h
├── s390
│ └── internal.h
├── x86
│ ├── asmnames.h
│ ├── internal64.h
│ └── internal.h
├── alpha
│ ├── internal.h
│ └── ffitarget.h
├── sparc
│ └── internal.h
├── bfin
│ └── ffitarget.h
├── m88k
│ └── ffitarget.h
├── vax
│ └── ffitarget.h
├── nios2
│ └── ffitarget.h
├── microblaze
│ └── ffitarget.h
├── ia64
│ └── ia64_flags.h
├── xtensa
│ └── ffitarget.h
├── metag
│ └── ffitarget.h
├── arc
│ └── ffitarget.h
├── m32r
│ └── ffitarget.h
├── moxie
│ └── ffitarget.h
├── sh
│ └── ffitarget.h
├── m68k
│ └── ffitarget.h
├── avr32
│ └── ffitarget.h
├── or1k
│ └── ffitarget.h
└── sh64
│ └── ffitarget.h
├── man
├── Makefile.am
├── ffi.3
├── ffi_prep_cif.3
└── ffi_prep_cif_var.3
├── include
├── Makefile.am
└── ffi_cfi.h
├── libffi.pc.in
├── README.md
├── m4
├── asmcfi.m4
├── ltversion.m4
├── ax_require_defined.m4
├── ax_append_flag.m4
├── ax_configure_args.m4
└── ax_check_compile_flag.m4
├── win32
├── vc11_x64
│ └── libffi-msvc.sln
├── vc12_x64
│ └── libffi-msvc.sln
├── vc9_x86
│ └── libffi.sln
├── vc11_x86
│ └── libffi-msvc.sln
├── vc12_x86
│ └── libffi-msvc.sln
├── vc14_x64
│ └── libffi-msvc.sln
├── vc15_x64
│ └── libffi-msvc.sln
├── vs16_x64
│ └── libffi-msvc.sln
├── vs17_x64
│ └── libffi-msvc.sln
├── vc14_x86
│ └── libffi-msvc.sln
├── vc15_x86
│ └── libffi-msvc.sln
├── vs16_x86
│ └── libffi-msvc.sln
└── vs17_x86
│ └── libffi-msvc.sln
├── winlibs.mak
├── LICENSE
├── libtool-version
└── libffi.map.in
/testsuite/config/default.exp:
--------------------------------------------------------------------------------
1 | load_lib "standard.exp"
2 |
--------------------------------------------------------------------------------
/testsuite/libffi.go/ffitest.h:
--------------------------------------------------------------------------------
1 | #include "../libffi.call/ffitest.h"
2 |
--------------------------------------------------------------------------------
/doc/libffi.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winlibs/libffi/HEAD/doc/libffi.pdf
--------------------------------------------------------------------------------
/testsuite/libffi.complex/ffitest.h:
--------------------------------------------------------------------------------
1 | #include "../libffi.call/ffitest.h"
2 |
--------------------------------------------------------------------------------
/doc/Makefile.am:
--------------------------------------------------------------------------------
1 | ## Process this with automake to create Makefile.in
2 |
3 | info_TEXINFOS = libffi.texi
4 |
--------------------------------------------------------------------------------
/doc/stamp-vti:
--------------------------------------------------------------------------------
1 | @set UPDATED 22 November 2019
2 | @set UPDATED-MONTH November 2019
3 | @set EDITION 3.3
4 | @set VERSION 3.3
5 |
--------------------------------------------------------------------------------
/doc/version.texi:
--------------------------------------------------------------------------------
1 | @set UPDATED 22 November 2019
2 | @set UPDATED-MONTH November 2019
3 | @set EDITION 3.3
4 | @set VERSION 3.3
5 |
--------------------------------------------------------------------------------
/msvc_build/aarch64/Ffi_staticLib.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/arm/internal.h:
--------------------------------------------------------------------------------
1 | #define ARM_TYPE_VFP_S 0
2 | #define ARM_TYPE_VFP_D 1
3 | #define ARM_TYPE_VFP_N 2
4 | #define ARM_TYPE_INT64 3
5 | #define ARM_TYPE_INT 4
6 | #define ARM_TYPE_VOID 5
7 | #define ARM_TYPE_STRUCT 6
8 |
--------------------------------------------------------------------------------
/man/Makefile.am:
--------------------------------------------------------------------------------
1 | ## Process this with automake to create Makefile.in
2 |
3 | AUTOMAKE_OPTIONS=foreign
4 |
5 | EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
6 |
7 | man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
8 |
9 |
--------------------------------------------------------------------------------
/include/Makefile.am:
--------------------------------------------------------------------------------
1 | ## Process this with automake to create Makefile.in
2 |
3 | AUTOMAKE_OPTIONS=foreign
4 |
5 | DISTCLEANFILES=ffitarget.h
6 | noinst_HEADERS=ffi_common.h ffi_cfi.h
7 | EXTRA_DIST=ffi.h.in
8 |
9 | nodist_include_HEADERS = ffi.h ffitarget.h
10 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/complex_float.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check complex types.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_float.inc"
10 | #include "complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/complex_double.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check complex types.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_double.inc"
10 | #include "complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/complex_defs_double.inc:
--------------------------------------------------------------------------------
1 | /* -*-c-*- */
2 | /* Complex base type. */
3 | #define T_FFI_TYPE ffi_type_complex_double
4 | /* C type corresponding to the base type. */
5 | #define T_C_TYPE double
6 | /* C cast for a value of type T_C_TYPE that is passed to printf. */
7 | #define T_CONV
8 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/complex_longdouble.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check complex types.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_longdouble.inc"
10 | #include "complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex_float.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_float.inc"
10 | #include "cls_complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/complex_defs_float.inc:
--------------------------------------------------------------------------------
1 | /* -*-c-*- */
2 | /* Complex base type. */
3 | #define T_FFI_TYPE ffi_type_complex_float
4 | /* C type corresponding to the base type. */
5 | #define T_C_TYPE float
6 | /* C cast for a value of type T_C_TYPE that is passed to printf. */
7 | #define T_CONV (double)
8 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex_double.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_double.inc"
10 | #include "cls_complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/complex_defs_longdouble.inc:
--------------------------------------------------------------------------------
1 | /* -*-c-*- */
2 | /* Complex base type. */
3 | #define T_FFI_TYPE ffi_type_complex_longdouble
4 | /* C type corresponding to the base type. */
5 | #define T_C_TYPE long double
6 | /* C cast for a value of type T_C_TYPE that is passed to printf. */
7 | #define T_CONV
8 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex1_double.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_double.inc"
10 | #include "return_complex1.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex1_float.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_float.inc"
10 | #include "return_complex1.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex2_double.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_double.inc"
10 | #include "return_complex2.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex2_float.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_float.inc"
10 | #include "return_complex2.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex_double.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_double.inc"
10 | #include "return_complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex_float.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_float.inc"
10 | #include "return_complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex_longdouble.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_longdouble.inc"
10 | #include "cls_complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex1_longdouble.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_longdouble.inc"
10 | #include "return_complex1.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex2_longdouble.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_longdouble.inc"
10 | #include "return_complex2.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex_longdouble.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_longdouble.inc"
10 | #include "return_complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/many_complex_double.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex, with many arguments
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_double.inc"
10 | #include "many_complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/many_complex_float.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex, with many arguments
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_float.inc"
10 | #include "many_complex.inc"
11 |
--------------------------------------------------------------------------------
/libffi.pc.in:
--------------------------------------------------------------------------------
1 | prefix=@prefix@
2 | exec_prefix=@exec_prefix@
3 | libdir=@libdir@
4 | toolexeclibdir=@toolexeclibdir@
5 | includedir=@includedir@
6 |
7 | Name: @PACKAGE_NAME@
8 | Description: Library supporting Foreign Function Interfaces
9 | Version: @PACKAGE_VERSION@
10 | Libs: -L${toolexeclibdir} -lffi
11 | Cflags: -I${includedir}
12 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/many_complex_longdouble.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value complex, with many arguments
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_longdouble.inc"
10 | #include "many_complex.inc"
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # libffi
2 |
3 | libffi Windows repository, used by PHP builds and various other projects
4 |
5 | The Visual Studio solutions are based on [http://github.com/pgregory/libffi-msvc.git](http://github.com/pgregory/libffi-msvc.git)
6 |
7 | ## Building for PHP
8 |
9 | - open and build the appropriate Visual studio solution in .\win32
10 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_align_complex_double.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check structure alignment of complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_double.inc"
10 | #include "cls_align_complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_align_complex_float.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check structure alignment of complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_float.inc"
10 | #include "cls_align_complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex_struct_double.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check complex arguments in structs.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_double.inc"
10 | #include "cls_complex_struct.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex_struct_float.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check complex arguments in structs.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_float.inc"
10 | #include "cls_complex_struct.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex_va_double.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Test complex' passed in variable argument lists.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_double.inc"
10 | #include "cls_complex_va.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_align_complex_longdouble.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check structure alignment of complex.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_longdouble.inc"
10 | #include "cls_align_complex.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex_struct_longdouble.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check complex arguments in structs.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_longdouble.inc"
10 | #include "cls_complex_struct.inc"
11 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex_va_longdouble.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Test complex' passed in variable argument lists.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "complex_defs_longdouble.inc"
10 | #include "cls_complex_va.inc"
11 |
--------------------------------------------------------------------------------
/src/s390/internal.h:
--------------------------------------------------------------------------------
1 | /* If these values change, sysv.S must be adapted! */
2 | #define FFI390_RET_DOUBLE 0
3 | #define FFI390_RET_FLOAT 1
4 | #define FFI390_RET_INT64 2
5 | #define FFI390_RET_INT32 3
6 | #define FFI390_RET_VOID 4
7 |
8 | #define FFI360_RET_MASK 7
9 | #define FFI390_RET_IN_MEM 8
10 |
11 | #define FFI390_RET_STRUCT (FFI390_RET_VOID | FFI390_RET_IN_MEM)
12 |
--------------------------------------------------------------------------------
/m4/asmcfi.m4:
--------------------------------------------------------------------------------
1 | AC_DEFUN([GCC_AS_CFI_PSEUDO_OP],
2 | [AC_CACHE_CHECK([assembler .cfi pseudo-op support],
3 | gcc_cv_as_cfi_pseudo_op, [
4 | gcc_cv_as_cfi_pseudo_op=unknown
5 | AC_TRY_COMPILE([asm (".cfi_sections\n\t.cfi_startproc\n\t.cfi_endproc");],,
6 | [gcc_cv_as_cfi_pseudo_op=yes],
7 | [gcc_cv_as_cfi_pseudo_op=no])
8 | ])
9 | if test "x$gcc_cv_as_cfi_pseudo_op" = xyes; then
10 | AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
11 | [Define if your assembler supports .cfi_* directives.])
12 | fi
13 | ])
14 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/err_bad_typedef.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_prep_cif
2 | Purpose: Test error return for bad typedefs.
3 | Limitations: none.
4 | PR: none.
5 | Originator: Blake Chaffin 6/6/2007 */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | int main (void)
12 | {
13 | ffi_cif cif;
14 | ffi_type* arg_types[1];
15 |
16 | ffi_type badType = ffi_type_void;
17 |
18 | arg_types[0] = NULL;
19 |
20 | badType.size = 0;
21 |
22 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType,
23 | arg_types) == FFI_BAD_TYPEDEF);
24 |
25 | exit(0);
26 | }
27 |
--------------------------------------------------------------------------------
/testsuite/libffi.go/static-chain.h:
--------------------------------------------------------------------------------
1 | #ifdef __aarch64__
2 | # define STATIC_CHAIN_REG "x18"
3 | #elif defined(__alpha__)
4 | # define STATIC_CHAIN_REG "$1"
5 | #elif defined(__arm__)
6 | # define STATIC_CHAIN_REG "ip"
7 | #elif defined(__sparc__)
8 | # if defined(__arch64__) || defined(__sparcv9)
9 | # define STATIC_CHAIN_REG "g5"
10 | # else
11 | # define STATIC_CHAIN_REG "g2"
12 | # endif
13 | #elif defined(__x86_64__)
14 | # define STATIC_CHAIN_REG "r10"
15 | #elif defined(__i386__)
16 | # ifndef ABI_NUM
17 | # define STATIC_CHAIN_REG "ecx" /* FFI_DEFAULT_ABI only */
18 | # endif
19 | #endif
20 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex_va_float.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Test complex' passed in variable argument lists.
3 | Limitations: none.
4 | PR: none.
5 | Originator: . */
6 |
7 | /* { dg-do run } */
8 |
9 | /* Alpha splits _Complex into two arguments. It's illegal to pass
10 | float through varargs, so _Complex float goes badly. In sort of
11 | gets passed as _Complex double, but the compiler doesn't agree
12 | with itself on this issue. */
13 | /* { dg-do run { xfail alpha*-*-* } } */
14 |
15 | #include "complex_defs_float.inc"
16 | #include "cls_complex_va.inc"
17 |
--------------------------------------------------------------------------------
/src/x86/asmnames.h:
--------------------------------------------------------------------------------
1 | #ifndef ASMNAMES_H
2 | #define ASMNAMES_H
3 |
4 | #define C2(X, Y) X ## Y
5 | #define C1(X, Y) C2(X, Y)
6 | #ifdef __USER_LABEL_PREFIX__
7 | # define C(X) C1(__USER_LABEL_PREFIX__, X)
8 | #else
9 | # define C(X) X
10 | #endif
11 |
12 | #ifdef __APPLE__
13 | # define L(X) C1(L, X)
14 | #else
15 | # define L(X) C1(.L, X)
16 | #endif
17 |
18 | #if defined(__ELF__) && defined(__PIC__)
19 | # define PLT(X) X@PLT
20 | #else
21 | # define PLT(X) X
22 | #endif
23 |
24 | #ifdef __ELF__
25 | # define ENDF(X) .type X,@function; .size X, . - X
26 | #else
27 | # define ENDF(X)
28 | #endif
29 |
30 | #endif /* ASMNAMES_H */
31 |
--------------------------------------------------------------------------------
/testsuite/libffi.go/closure1.c:
--------------------------------------------------------------------------------
1 | /* { dg-do run } */
2 |
3 | #include "ffitest.h"
4 |
5 | void doit(ffi_cif *cif, void *rvalue, void **avalue, void *closure)
6 | {
7 | (void)cif;
8 | (void)avalue;
9 | *(void **)rvalue = closure;
10 | }
11 |
12 | typedef void * (*FN)(void);
13 |
14 | int main()
15 | {
16 | ffi_cif cif;
17 | ffi_go_closure cl;
18 | void *result;
19 |
20 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK);
21 | CHECK(ffi_prep_go_closure(&cl, &cif, doit) == FFI_OK);
22 |
23 | ffi_call_go(&cif, FFI_FN(*(FN *)&cl), &result, NULL, &cl);
24 |
25 | CHECK(result == &cl);
26 |
27 | exit(0);
28 | }
29 |
--------------------------------------------------------------------------------
/src/alpha/internal.h:
--------------------------------------------------------------------------------
1 | #define ALPHA_ST_VOID 0
2 | #define ALPHA_ST_INT 1
3 | #define ALPHA_ST_FLOAT 2
4 | #define ALPHA_ST_DOUBLE 3
5 | #define ALPHA_ST_CPLXF 4
6 | #define ALPHA_ST_CPLXD 5
7 |
8 | #define ALPHA_LD_VOID 0
9 | #define ALPHA_LD_INT64 1
10 | #define ALPHA_LD_INT32 2
11 | #define ALPHA_LD_UINT16 3
12 | #define ALPHA_LD_SINT16 4
13 | #define ALPHA_LD_UINT8 5
14 | #define ALPHA_LD_SINT8 6
15 | #define ALPHA_LD_FLOAT 7
16 | #define ALPHA_LD_DOUBLE 8
17 | #define ALPHA_LD_CPLXF 9
18 | #define ALPHA_LD_CPLXD 10
19 |
20 | #define ALPHA_ST_SHIFT 0
21 | #define ALPHA_LD_SHIFT 8
22 | #define ALPHA_RET_IN_MEM 0x10000
23 | #define ALPHA_FLAGS(S, L) (((L) << ALPHA_LD_SHIFT) | (S))
24 |
--------------------------------------------------------------------------------
/src/x86/internal64.h:
--------------------------------------------------------------------------------
1 | #define UNIX64_RET_VOID 0
2 | #define UNIX64_RET_UINT8 1
3 | #define UNIX64_RET_UINT16 2
4 | #define UNIX64_RET_UINT32 3
5 | #define UNIX64_RET_SINT8 4
6 | #define UNIX64_RET_SINT16 5
7 | #define UNIX64_RET_SINT32 6
8 | #define UNIX64_RET_INT64 7
9 | #define UNIX64_RET_XMM32 8
10 | #define UNIX64_RET_XMM64 9
11 | #define UNIX64_RET_X87 10
12 | #define UNIX64_RET_X87_2 11
13 | #define UNIX64_RET_ST_XMM0_RAX 12
14 | #define UNIX64_RET_ST_RAX_XMM0 13
15 | #define UNIX64_RET_ST_XMM0_XMM1 14
16 | #define UNIX64_RET_ST_RAX_RDX 15
17 |
18 | #define UNIX64_RET_LAST 15
19 |
20 | #define UNIX64_FLAG_RET_IN_MEM (1 << 10)
21 | #define UNIX64_FLAG_XMM_ARGS (1 << 11)
22 | #define UNIX64_SIZE_SHIFT 12
23 |
--------------------------------------------------------------------------------
/src/x86/internal.h:
--------------------------------------------------------------------------------
1 | #define X86_RET_FLOAT 0
2 | #define X86_RET_DOUBLE 1
3 | #define X86_RET_LDOUBLE 2
4 | #define X86_RET_SINT8 3
5 | #define X86_RET_SINT16 4
6 | #define X86_RET_UINT8 5
7 | #define X86_RET_UINT16 6
8 | #define X86_RET_INT64 7
9 | #define X86_RET_INT32 8
10 | #define X86_RET_VOID 9
11 | #define X86_RET_STRUCTPOP 10
12 | #define X86_RET_STRUCTARG 11
13 | #define X86_RET_STRUCT_1B 12
14 | #define X86_RET_STRUCT_2B 13
15 | #define X86_RET_UNUSED14 14
16 | #define X86_RET_UNUSED15 15
17 |
18 | #define X86_RET_TYPE_MASK 15
19 | #define X86_RET_POP_SHIFT 4
20 |
21 | #define R_EAX 0
22 | #define R_EDX 1
23 | #define R_ECX 2
24 |
25 | #ifdef __PCC__
26 | # define HAVE_FASTCALL 0
27 | #else
28 | # define HAVE_FASTCALL 1
29 | #endif
30 |
--------------------------------------------------------------------------------
/m4/ltversion.m4:
--------------------------------------------------------------------------------
1 | # ltversion.m4 -- version numbers -*- Autoconf -*-
2 | #
3 | # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
4 | # Written by Scott James Remnant, 2004
5 | #
6 | # This file is free software; the Free Software Foundation gives
7 | # unlimited permission to copy and/or distribute it, with or without
8 | # modifications, as long as this notice is preserved.
9 |
10 | # @configure_input@
11 |
12 | # serial 4179 ltversion.m4
13 | # This file is part of GNU Libtool
14 |
15 | m4_define([LT_PACKAGE_VERSION], [2.4.6])
16 | m4_define([LT_PACKAGE_REVISION], [2.4.6])
17 |
18 | AC_DEFUN([LTVERSION_VERSION],
19 | [macro_version='2.4.6'
20 | macro_revision='2.4.6'
21 | _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
22 | _LT_DECL(, macro_revision, 0)
23 | ])
24 |
--------------------------------------------------------------------------------
/src/sparc/internal.h:
--------------------------------------------------------------------------------
1 | #define SPARC_RET_VOID 0
2 | #define SPARC_RET_STRUCT 1
3 | #define SPARC_RET_UINT8 2
4 | #define SPARC_RET_SINT8 3
5 | #define SPARC_RET_UINT16 4
6 | #define SPARC_RET_SINT16 5
7 | #define SPARC_RET_UINT32 6
8 | #define SP_V9_RET_SINT32 7 /* v9 only */
9 | #define SP_V8_RET_CPLX16 7 /* v8 only */
10 | #define SPARC_RET_INT64 8
11 | #define SPARC_RET_INT128 9
12 |
13 | /* Note that F_7 is missing, and is handled by SPARC_RET_STRUCT. */
14 | #define SPARC_RET_F_8 10
15 | #define SPARC_RET_F_6 11
16 | #define SPARC_RET_F_4 12
17 | #define SPARC_RET_F_2 13
18 | #define SP_V9_RET_F_3 14 /* v9 only */
19 | #define SP_V8_RET_CPLX8 14 /* v8 only */
20 | #define SPARC_RET_F_1 15
21 |
22 | #define SPARC_FLAG_RET_MASK 15
23 | #define SPARC_FLAG_RET_IN_MEM 32
24 | #define SPARC_FLAG_FP_ARGS 64
25 |
26 | #define SPARC_SIZEMASK_SHIFT 8
27 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_ldl.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value long double.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20071113 */
6 | /* { dg-do run } */
7 |
8 | #include "ffitest.h"
9 |
10 | static long double return_ldl(long double ldl)
11 | {
12 | return 2*ldl;
13 | }
14 | int main (void)
15 | {
16 | ffi_cif cif;
17 | ffi_type *args[MAX_ARGS];
18 | void *values[MAX_ARGS];
19 | long double ldl, rldl;
20 |
21 | args[0] = &ffi_type_longdouble;
22 | values[0] = &ldl;
23 |
24 | /* Initialize the cif */
25 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
26 | &ffi_type_longdouble, args) == FFI_OK);
27 |
28 | for (ldl = -127.0; ldl < 127.0; ldl++)
29 | {
30 | ffi_call(&cif, FFI_FN(return_ldl), &rldl, values);
31 | CHECK(rldl == 2 * ldl);
32 | }
33 | exit(0);
34 | }
35 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_fl.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value float.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20050212 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static float return_fl(float fl)
11 | {
12 | return 2 * fl;
13 | }
14 | int main (void)
15 | {
16 | ffi_cif cif;
17 | ffi_type *args[MAX_ARGS];
18 | void *values[MAX_ARGS];
19 | float fl, rfl;
20 |
21 | args[0] = &ffi_type_float;
22 | values[0] = &fl;
23 |
24 | /* Initialize the cif */
25 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
26 | &ffi_type_float, args) == FFI_OK);
27 |
28 | for (fl = -127.0; fl < 127; fl++)
29 | {
30 | ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
31 | printf ("%f vs %f\n", rfl, return_fl(fl));
32 | CHECK(rfl == 2 * fl);
33 | }
34 | exit(0);
35 | }
36 |
--------------------------------------------------------------------------------
/testsuite/libffi.go/aa-direct.c:
--------------------------------------------------------------------------------
1 | /* { dg-do run } */
2 |
3 | #include "static-chain.h"
4 |
5 | #if defined(__GNUC__) && !defined(__clang__) && defined(STATIC_CHAIN_REG)
6 |
7 | #include "ffitest.h"
8 |
9 | /* Blatent assumption here that the prologue doesn't clobber the
10 | static chain for trivial functions. If this is not true, don't
11 | define STATIC_CHAIN_REG, and we'll test what we can via other tests. */
12 | void *doit(void)
13 | {
14 | register void *chain __asm__(STATIC_CHAIN_REG);
15 | return chain;
16 | }
17 |
18 | int main()
19 | {
20 | ffi_cif cif;
21 | void *result;
22 |
23 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK);
24 |
25 | ffi_call_go(&cif, FFI_FN(doit), &result, NULL, &result);
26 |
27 | CHECK(result == &result);
28 |
29 | return 0;
30 | }
31 |
32 | #else /* UNSUPPORTED */
33 | int main() { return 0; }
34 | #endif
35 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_sc.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value signed char.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static signed char return_sc(signed char sc)
11 | {
12 | return sc;
13 | }
14 | int main (void)
15 | {
16 | ffi_cif cif;
17 | ffi_type *args[MAX_ARGS];
18 | void *values[MAX_ARGS];
19 | ffi_arg rint;
20 | signed char sc;
21 |
22 | args[0] = &ffi_type_schar;
23 | values[0] = ≻
24 |
25 | /* Initialize the cif */
26 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
27 | &ffi_type_schar, args) == FFI_OK);
28 |
29 | for (sc = (signed char) -127;
30 | sc < (signed char) 127; sc++)
31 | {
32 | ffi_call(&cif, FFI_FN(return_sc), &rint, values);
33 | CHECK((signed char)rint == sc);
34 | }
35 | exit(0);
36 | }
37 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_sl.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check if long as return type is handled correctly.
3 | Limitations: none.
4 | PR: none.
5 | */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | static long return_sl(long l1, long l2)
10 | {
11 | return l1 - l2;
12 | }
13 |
14 | int main (void)
15 | {
16 | ffi_cif cif;
17 | ffi_type *args[MAX_ARGS];
18 | void *values[MAX_ARGS];
19 | ffi_arg res;
20 | unsigned long l1, l2;
21 |
22 | args[0] = &ffi_type_slong;
23 | args[1] = &ffi_type_slong;
24 | values[0] = &l1;
25 | values[1] = &l2;
26 |
27 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
28 | &ffi_type_slong, args) == FFI_OK);
29 |
30 | l1 = 1073741823L;
31 | l2 = 1073741824L;
32 |
33 | ffi_call(&cif, FFI_FN(return_sl), &res, values);
34 | printf("res: %ld, %ld\n", (long)res, l1 - l2);
35 | /* { dg-output "res: -1, -1" } */
36 |
37 | exit(0);
38 | }
39 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_dbl.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value double.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20050212 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static double return_dbl(double dbl)
11 | {
12 | printf ("%f\n", dbl);
13 | return 2 * dbl;
14 | }
15 | int main (void)
16 | {
17 | ffi_cif cif;
18 | ffi_type *args[MAX_ARGS];
19 | void *values[MAX_ARGS];
20 | double dbl, rdbl;
21 |
22 | args[0] = &ffi_type_double;
23 | values[0] = &dbl;
24 |
25 | /* Initialize the cif */
26 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
27 | &ffi_type_double, args) == FFI_OK);
28 |
29 | for (dbl = -127.3; dbl < 127; dbl++)
30 | {
31 | ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
32 | printf ("%f vs %f\n", rdbl, return_dbl(dbl));
33 | CHECK(rdbl == 2 * dbl);
34 | }
35 | exit(0);
36 | }
37 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_fl1.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value float.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20050212 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static float return_fl(float fl1, float fl2)
11 | {
12 | return fl1 + fl2;
13 | }
14 | int main (void)
15 | {
16 | ffi_cif cif;
17 | ffi_type *args[MAX_ARGS];
18 | void *values[MAX_ARGS];
19 | float fl1, fl2, rfl;
20 |
21 | args[0] = &ffi_type_float;
22 | args[1] = &ffi_type_float;
23 | values[0] = &fl1;
24 | values[1] = &fl2;
25 |
26 | /* Initialize the cif */
27 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
28 | &ffi_type_float, args) == FFI_OK);
29 | fl1 = 127.0;
30 | fl2 = 128.0;
31 |
32 | ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
33 | printf ("%f vs %f\n", rfl, return_fl(fl1, fl2));
34 | CHECK(rfl == fl1 + fl2);
35 | exit(0);
36 | }
37 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_uc.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value unsigned char.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static unsigned char return_uc(unsigned char uc)
11 | {
12 | return uc;
13 | }
14 |
15 | int main (void)
16 | {
17 | ffi_cif cif;
18 | ffi_type *args[MAX_ARGS];
19 | void *values[MAX_ARGS];
20 | ffi_arg rint;
21 |
22 | unsigned char uc;
23 |
24 | args[0] = &ffi_type_uchar;
25 | values[0] = &uc;
26 |
27 | /* Initialize the cif */
28 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
29 | &ffi_type_uchar, args) == FFI_OK);
30 |
31 | for (uc = (unsigned char) '\x00';
32 | uc < (unsigned char) '\xff'; uc++)
33 | {
34 | ffi_call(&cif, FFI_FN(return_uc), &rint, values);
35 | CHECK((unsigned char)rint == uc);
36 | }
37 | exit(0);
38 | }
39 |
--------------------------------------------------------------------------------
/win32/vc11_x64/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|x64 = Debug|x64
9 | Release|x64 = Release|x64
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64
13 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/win32/vc12_x64/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|x64 = Debug|x64
9 | Release|x64 = Release|x64
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64
13 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/testsuite/libffi.bhaible/Makefile:
--------------------------------------------------------------------------------
1 | CC = gcc
2 | CFLAGS = -O2 -Wall
3 | prefix =
4 | includedir = $(prefix)/include
5 | libdir = $(prefix)/lib
6 | CPPFLAGS = -I$(includedir)
7 | LDFLAGS = -L$(libdir) -Wl,-rpath,$(libdir)
8 |
9 | all: check-call check-callback
10 |
11 | test-call: test-call.c testcases.c
12 | $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o test-call test-call.c -lffi
13 |
14 | test-callback: test-callback.c testcases.c
15 | $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o test-callback test-callback.c -lffi
16 |
17 | check-call: test-call
18 | ./test-call > test-call.out
19 | LC_ALL=C uniq -u < test-call.out > failed-call
20 | test '!' -s failed-call
21 |
22 | check-callback: test-callback
23 | ./test-callback > test-callback.out
24 | LC_ALL=C uniq -u < test-callback.out > failed-callback
25 | test '!' -s failed-callback
26 |
27 | clean:
28 | rm -f test-call test-callback test-call.out test-callback.out failed-call failed-callback
29 |
--------------------------------------------------------------------------------
/win32/vc9_x86/libffi.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual Studio 2008
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcproj", "{1D251A7E-C06F-4991-932B-0FA87A0883FC}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Win32 = Debug|Win32
9 | Release|Win32 = Release|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {1D251A7E-C06F-4991-932B-0FA87A0883FC}.Debug|Win32.ActiveCfg = Debug|Win32
13 | {1D251A7E-C06F-4991-932B-0FA87A0883FC}.Debug|Win32.Build.0 = Debug|Win32
14 | {1D251A7E-C06F-4991-932B-0FA87A0883FC}.Release|Win32.ActiveCfg = Release|Win32
15 | {1D251A7E-C06F-4991-932B-0FA87A0883FC}.Release|Win32.Build.0 = Release|Win32
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/win32/vc11_x86/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Win32 = Debug|Win32
9 | Release|Win32 = Release|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32
13 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/win32/vc12_x86/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Win32 = Debug|Win32
9 | Release|Win32 = Release|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32
13 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/err_bad_abi.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_prep_cif, ffi_prep_closure
2 | Purpose: Test error return for bad ABIs.
3 | Limitations: none.
4 | PR: none.
5 | Originator: Blake Chaffin 6/6/2007 */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | static void
12 | dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
13 | void** args __UNUSED__, void* userdata __UNUSED__)
14 | {}
15 |
16 | int main (void)
17 | {
18 | ffi_cif cif;
19 | void *code;
20 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
21 | ffi_type* arg_types[1];
22 |
23 | arg_types[0] = NULL;
24 |
25 | CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void,
26 | arg_types) == FFI_BAD_ABI);
27 |
28 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void,
29 | arg_types) == FFI_OK);
30 |
31 | cif.abi= 255;
32 |
33 | CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI);
34 |
35 | exit(0);
36 | }
37 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex.inc:
--------------------------------------------------------------------------------
1 | /* -*-c-*- */
2 | #include "ffitest.h"
3 | #include
4 |
5 | static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c)
6 | {
7 | printf ("%f,%fi\n", T_CONV creal (c), T_CONV cimag (c));
8 | return 2 * c;
9 | }
10 | int main (void)
11 | {
12 | ffi_cif cif;
13 | ffi_type *args[MAX_ARGS];
14 | void *values[MAX_ARGS];
15 | _Complex T_C_TYPE c, rc, rc2;
16 | T_C_TYPE cr, ci;
17 |
18 | args[0] = &T_FFI_TYPE;
19 | values[0] = &c;
20 |
21 | /* Initialize the cif */
22 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
23 | &T_FFI_TYPE, args) == FFI_OK);
24 |
25 | for (cr = -127.0; cr < 127; cr++)
26 | {
27 | ci = 1000.0 - cr;
28 | c = cr + ci * I;
29 | ffi_call(&cif, FFI_FN(return_c), &rc, values);
30 | rc2 = return_c(c);
31 | printf ("%f,%fi vs %f,%fi\n",
32 | T_CONV creal (rc), T_CONV cimag (rc),
33 | T_CONV creal (rc2), T_CONV cimag (rc2));
34 | CHECK(rc == 2 * c);
35 | }
36 | exit(0);
37 | }
38 |
--------------------------------------------------------------------------------
/win32/vc14_x64/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Release|x64 = Release|x64
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64
16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64
17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/win32/vc15_x64/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Release|x64 = Release|x64
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64
16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64
17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/win32/vs16_x64/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Release|x64 = Release|x64
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64
16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64
17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/win32/vs17_x64/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Release|x64 = Release|x64
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64
16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64
17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/man/ffi.3:
--------------------------------------------------------------------------------
1 | .Dd February 15, 2008
2 | .Dt FFI 3
3 | .Sh NAME
4 | .Nm FFI
5 | .Nd Foreign Function Interface
6 | .Sh LIBRARY
7 | libffi, -lffi
8 | .Sh SYNOPSIS
9 | .In ffi.h
10 | .Ft ffi_status
11 | .Fo ffi_prep_cif
12 | .Fa "ffi_cif *cif"
13 | .Fa "ffi_abi abi"
14 | .Fa "unsigned int nargs"
15 | .Fa "ffi_type *rtype"
16 | .Fa "ffi_type **atypes"
17 | .Fc
18 | .Ft void
19 | .Fo ffi_prep_cif_var
20 | .Fa "ffi_cif *cif"
21 | .Fa "ffi_abi abi"
22 | .Fa "unsigned int nfixedargs"
23 | .Fa "unsigned int ntotalargs"
24 | .Fa "ffi_type *rtype"
25 | .Fa "ffi_type **atypes"
26 | .Fc
27 | .Ft void
28 | .Fo ffi_call
29 | .Fa "ffi_cif *cif"
30 | .Fa "void (*fn)(void)"
31 | .Fa "void *rvalue"
32 | .Fa "void **avalue"
33 | .Fc
34 | .Sh DESCRIPTION
35 | The foreign function interface provides a mechanism by which a function can
36 | generate a call to another function at runtime without requiring knowledge of
37 | the called function's interface at compile time.
38 | .Sh SEE ALSO
39 | .Xr ffi_prep_cif 3 ,
40 | .Xr ffi_prep_cif_var 3 ,
41 | .Xr ffi_call 3
42 |
--------------------------------------------------------------------------------
/win32/vc14_x86/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32
16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32
17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/win32/vc15_x86/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32
16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32
17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/win32/vs16_x86/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32
16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32
17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/win32/vs17_x86/libffi-msvc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32
16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32
17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_ul.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check if unsigned long as return type is handled correctly.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20060724 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | static unsigned long return_ul(unsigned long ul1, unsigned long ul2)
10 | {
11 | return ul1 + ul2;
12 | }
13 |
14 | int main (void)
15 | {
16 | ffi_cif cif;
17 | ffi_type *args[MAX_ARGS];
18 | void *values[MAX_ARGS];
19 | ffi_arg res;
20 | unsigned long ul1, ul2;
21 |
22 | args[0] = &ffi_type_ulong;
23 | args[1] = &ffi_type_ulong;
24 | values[0] = &ul1;
25 | values[1] = &ul2;
26 |
27 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
28 | &ffi_type_ulong, args) == FFI_OK);
29 |
30 | ul1 = 1073741823L;
31 | ul2 = 1073741824L;
32 |
33 | ffi_call(&cif, FFI_FN(return_ul), &res, values);
34 | printf("res: %lu, %lu\n", (unsigned long)res, ul1 + ul2);
35 | /* { dg-output "res: 2147483647, 2147483647" } */
36 |
37 | exit(0);
38 | }
39 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_ll.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value long long.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | static long long return_ll(long long ll)
10 | {
11 | return ll;
12 | }
13 |
14 | int main (void)
15 | {
16 | ffi_cif cif;
17 | ffi_type *args[MAX_ARGS];
18 | void *values[MAX_ARGS];
19 | long long rlonglong;
20 | long long ll;
21 |
22 | args[0] = &ffi_type_sint64;
23 | values[0] = ≪
24 |
25 | /* Initialize the cif */
26 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
27 | &ffi_type_sint64, args) == FFI_OK);
28 |
29 | for (ll = 0LL; ll < 100LL; ll++)
30 | {
31 | ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
32 | CHECK(rlonglong == ll);
33 | }
34 |
35 | for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
36 | {
37 | ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
38 | CHECK(rlonglong == ll);
39 | }
40 | exit(0);
41 | }
42 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/strlen.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check strlen function call.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static size_t ABI_ATTR my_strlen(char *s)
11 | {
12 | return (strlen(s));
13 | }
14 |
15 | int main (void)
16 | {
17 | ffi_cif cif;
18 | ffi_type *args[MAX_ARGS];
19 | void *values[MAX_ARGS];
20 | ffi_arg rint;
21 | char *s;
22 |
23 | args[0] = &ffi_type_pointer;
24 | values[0] = (void*) &s;
25 |
26 | /* Initialize the cif */
27 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1,
28 | &ffi_type_sint, args) == FFI_OK);
29 |
30 | s = "a";
31 | ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
32 | CHECK(rint == 1);
33 |
34 | s = "1234567";
35 | ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
36 | CHECK(rint == 7);
37 |
38 | s = "1234567890123456789012345";
39 | ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
40 | CHECK(rint == 25);
41 |
42 | exit (0);
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_fl3.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value float.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20050212 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static float return_fl(float fl1, float fl2, unsigned int in3, float fl4)
11 | {
12 | return fl1 + fl2 + in3 + fl4;
13 | }
14 | int main (void)
15 | {
16 | ffi_cif cif;
17 | ffi_type *args[MAX_ARGS];
18 | void *values[MAX_ARGS];
19 | float fl1, fl2, fl4, rfl;
20 | unsigned int in3;
21 | args[0] = &ffi_type_float;
22 | args[1] = &ffi_type_float;
23 | args[2] = &ffi_type_uint;
24 | args[3] = &ffi_type_float;
25 | values[0] = &fl1;
26 | values[1] = &fl2;
27 | values[2] = &in3;
28 | values[3] = &fl4;
29 |
30 | /* Initialize the cif */
31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
32 | &ffi_type_float, args) == FFI_OK);
33 | fl1 = 127.0;
34 | fl2 = 128.0;
35 | in3 = 255;
36 | fl4 = 512.7;
37 |
38 | ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
39 | printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, in3, fl4));
40 | CHECK(rfl == fl1 + fl2 + in3 + fl4);
41 | exit(0);
42 | }
43 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/negint.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check that negative integers are passed correctly.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | static int checking(int a, short b, signed char c)
12 | {
13 |
14 | return (a < 0 && b < 0 && c < 0);
15 | }
16 |
17 | int main (void)
18 | {
19 | ffi_cif cif;
20 | ffi_type *args[MAX_ARGS];
21 | void *values[MAX_ARGS];
22 | ffi_arg rint;
23 |
24 | signed int si;
25 | signed short ss;
26 | signed char sc;
27 |
28 | args[0] = &ffi_type_sint;
29 | values[0] = &si;
30 | args[1] = &ffi_type_sshort;
31 | values[1] = &ss;
32 | args[2] = &ffi_type_schar;
33 | values[2] = ≻
34 |
35 | /* Initialize the cif */
36 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
37 | &ffi_type_sint, args) == FFI_OK);
38 |
39 | si = -6;
40 | ss = -12;
41 | sc = -1;
42 |
43 | checking (si, ss, sc);
44 |
45 | ffi_call(&cif, FFI_FN(checking), &rint, values);
46 |
47 | printf ("%d vs %d\n", (int)rint, checking (si, ss, sc));
48 |
49 | CHECK(rint != 0);
50 |
51 | exit (0);
52 | }
53 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex1.inc:
--------------------------------------------------------------------------------
1 | /* -*-c-*- */
2 | #include "ffitest.h"
3 | #include
4 |
5 | static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c1, float fl2, unsigned int in3, _Complex T_C_TYPE c4)
6 | {
7 | return c1 + fl2 + in3 + c4;
8 | }
9 | int main (void)
10 | {
11 | ffi_cif cif;
12 | ffi_type *args[MAX_ARGS];
13 | void *values[MAX_ARGS];
14 | _Complex T_C_TYPE c1, c4, rc, rc2;
15 | float fl2;
16 | unsigned int in3;
17 | args[0] = &T_FFI_TYPE;
18 | args[1] = &ffi_type_float;
19 | args[2] = &ffi_type_uint;
20 | args[3] = &T_FFI_TYPE;
21 | values[0] = &c1;
22 | values[1] = &fl2;
23 | values[2] = &in3;
24 | values[3] = &c4;
25 |
26 | /* Initialize the cif */
27 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
28 | &T_FFI_TYPE, args) == FFI_OK);
29 | c1 = 127.0 + 255.0 * I;
30 | fl2 = 128.0;
31 | in3 = 255;
32 | c4 = 512.7 + 1024.1 * I;
33 |
34 | ffi_call(&cif, FFI_FN(return_c), &rc, values);
35 | rc2 = return_c(c1, fl2, in3, c4);
36 | printf ("%f,%fi vs %f,%fi\n",
37 | T_CONV creal (rc), T_CONV cimag (rc),
38 | T_CONV creal (rc2), T_CONV cimag (rc2));
39 | CHECK(rc == rc2);
40 | exit(0);
41 | }
42 |
--------------------------------------------------------------------------------
/winlibs.mak:
--------------------------------------------------------------------------------
1 | !IFNDEF VERSION
2 | VERSION=unknown
3 | !ENDIF
4 |
5 | !IF "$(PHP_SDK_ARCH)" == "x64"
6 | PLATFORM=x64
7 | SUBFOLDER=x64
8 | !ELSE
9 | PLATFORM=Win32
10 | SUBFOLDER=
11 | !ENDIF
12 |
13 | OUTPUT=$(MAKEDIR)\..\libffi-$(VERSION)-$(PHP_SDK_VS)-$(PHP_SDK_ARCH)
14 | ARCHIVE=$(OUTPUT).zip
15 |
16 | all:
17 | git checkout .
18 | git clean -fdx
19 |
20 | cd win32\$(PHP_SDK_VS)_$(PHP_SDK_ARCH)
21 | msbuild libffi-msvc.sln /p:Configuration=Release /p:Platform=$(PLATFORM)
22 |
23 | cd ..\..
24 | -rmdir /s /q $(OUTPUT)
25 | xcopy include\ffi.h $(OUTPUT)\include\*
26 | # sed -i "s/#if defined _MSC_VER && !defined FFI_BUILDING/#if 0 \/*defined _MSC_VER \&\& !defined FFI_BUILDING*\//" $(OUTPUT)\include\ffi.h
27 | sed -i "s/#define LIBFFI_H/#define LIBFFI_H\n#define FFI_BUILDING/" $(OUTPUT)\include\ffi.h
28 | xcopy src\x86\ffitarget.h $(OUTPUT)\include\*
29 | xcopy fficonfig.h $(OUTPUT)\include\*
30 | xcopy win32\$(PHP_SDK_VS)_$(PHP_SDK_ARCH)\$(SUBFOLDER)\Release\libffi.lib $(OUTPUT)\lib\*
31 | xcopy win32\$(PHP_SDK_VS)_$(PHP_SDK_ARCH)\libffi\$(SUBFOLDER)\Release\libffi.pdb $(OUTPUT)\lib\*
32 |
33 | del $(ARCHIVE)
34 | 7za a $(ARCHIVE) $(OUTPUT)\*
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | libffi - Copyright (c) 1996-2019 Anthony Green, Red Hat, Inc and others.
2 | See source files for details.
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | ``Software''), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_dbl2.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value double.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20050212 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static double return_dbl(double dbl1, double dbl2, unsigned int in3, double dbl4)
11 | {
12 | return dbl1 + dbl2 + in3 + dbl4;
13 | }
14 | int main (void)
15 | {
16 | ffi_cif cif;
17 | ffi_type *args[MAX_ARGS];
18 | void *values[MAX_ARGS];
19 | double dbl1, dbl2, dbl4, rdbl;
20 | unsigned int in3;
21 | args[0] = &ffi_type_double;
22 | args[1] = &ffi_type_double;
23 | args[2] = &ffi_type_uint;
24 | args[3] = &ffi_type_double;
25 | values[0] = &dbl1;
26 | values[1] = &dbl2;
27 | values[2] = &in3;
28 | values[3] = &dbl4;
29 |
30 | /* Initialize the cif */
31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
32 | &ffi_type_double, args) == FFI_OK);
33 | dbl1 = 127.0;
34 | dbl2 = 128.0;
35 | in3 = 255;
36 | dbl4 = 512.7;
37 |
38 | ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
39 | printf ("%f vs %f\n", rdbl, return_dbl(dbl1, dbl2, in3, dbl4));
40 | CHECK(rdbl == dbl1 + dbl2 + in3 + dbl4);
41 | exit(0);
42 | }
43 |
--------------------------------------------------------------------------------
/libtool-version:
--------------------------------------------------------------------------------
1 | # This file is used to maintain libtool version info for libffi. See
2 | # the libtool manual to understand the meaning of the fields. This is
3 | # a separate file so that version updates don't involve re-running
4 | # automake.
5 | #
6 | # Here are a set of rules to help you update your library version
7 | # information:
8 | #
9 | # 1. Start with version information of `0:0:0' for each libtool library.
10 | #
11 | # 2. Update the version information only immediately before a public
12 | # release of your software. More frequent updates are unnecessary,
13 | # and only guarantee that the current interface number gets larger
14 | # faster.
15 | #
16 | # 3. If the library source code has changed at all since the last
17 | # update, then increment revision (`c:r:a' becomes `c:r+1:a').
18 | #
19 | # 4. If any interfaces have been added, removed, or changed since the
20 | # last update, increment current, and set revision to 0.
21 | #
22 | # 5. If any interfaces have been added since the last public release,
23 | # then increment age.
24 | #
25 | # 6. If any interfaces have been removed since the last public
26 | # release, then set age to 0.
27 | #
28 | # CURRENT:REVISION:AGE
29 | 8:0:1
30 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/align_mixed.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check for proper argument alignment.
3 | Limitations: none.
4 | PR: none.
5 | Originator: (from many_win32.c) */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | static float ABI_ATTR align_arguments(int i1,
12 | double f2,
13 | int i3,
14 | double f4)
15 | {
16 | return i1+f2+i3+f4;
17 | }
18 |
19 | int main(void)
20 | {
21 | ffi_cif cif;
22 | ffi_type *args[4] = {
23 | &ffi_type_sint,
24 | &ffi_type_double,
25 | &ffi_type_sint,
26 | &ffi_type_double
27 | };
28 | double fa[2] = {1,2};
29 | int ia[2] = {1,2};
30 | void *values[4] = {&ia[0], &fa[0], &ia[1], &fa[1]};
31 | float f, ff;
32 |
33 | /* Initialize the cif */
34 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 4,
35 | &ffi_type_float, args) == FFI_OK);
36 |
37 | ff = align_arguments(ia[0], fa[0], ia[1], fa[1]);
38 |
39 | ffi_call(&cif, FFI_FN(align_arguments), &f, values);
40 |
41 | if (f == ff)
42 | printf("align arguments tests ok!\n");
43 | else
44 | CHECK(0);
45 | exit(0);
46 | }
47 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_dbl1.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value double.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20050212 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static double return_dbl(double dbl1, float fl2, unsigned int in3, double dbl4)
11 | {
12 | return dbl1 + fl2 + in3 + dbl4;
13 | }
14 | int main (void)
15 | {
16 | ffi_cif cif;
17 | ffi_type *args[MAX_ARGS];
18 | void *values[MAX_ARGS];
19 | double dbl1, dbl4, rdbl;
20 | float fl2;
21 | unsigned int in3;
22 | args[0] = &ffi_type_double;
23 | args[1] = &ffi_type_float;
24 | args[2] = &ffi_type_uint;
25 | args[3] = &ffi_type_double;
26 | values[0] = &dbl1;
27 | values[1] = &fl2;
28 | values[2] = &in3;
29 | values[3] = &dbl4;
30 |
31 | /* Initialize the cif */
32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
33 | &ffi_type_double, args) == FFI_OK);
34 | dbl1 = 127.0;
35 | fl2 = 128.0;
36 | in3 = 255;
37 | dbl4 = 512.7;
38 |
39 | ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
40 | printf ("%f vs %f\n", rdbl, return_dbl(dbl1, fl2, in3, dbl4));
41 | CHECK(rdbl == dbl1 + fl2 + in3 + dbl4);
42 | exit(0);
43 | }
44 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/align_stdcall.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check for proper argument alignment.
3 | Limitations: none.
4 | PR: none.
5 | Originator: (from many_win32.c) */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | static float ABI_ATTR align_arguments(int i1,
12 | double f2,
13 | int i3,
14 | double f4)
15 | {
16 | return i1+f2+i3+f4;
17 | }
18 |
19 | int main(void)
20 | {
21 | ffi_cif cif;
22 | ffi_type *args[4] = {
23 | &ffi_type_sint,
24 | &ffi_type_double,
25 | &ffi_type_sint,
26 | &ffi_type_double
27 | };
28 | double fa[2] = {1,2};
29 | int ia[2] = {1,2};
30 | void *values[4] = {&ia[0], &fa[0], &ia[1], &fa[1]};
31 | float f, ff;
32 |
33 | /* Initialize the cif */
34 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 4,
35 | &ffi_type_float, args) == FFI_OK);
36 |
37 | ff = align_arguments(ia[0], fa[0], ia[1], fa[1]);;
38 |
39 | ffi_call(&cif, FFI_FN(align_arguments), &f, values);
40 |
41 | if (f == ff)
42 | printf("align arguments tests ok!\n");
43 | else
44 | CHECK(0);
45 | exit(0);
46 | }
47 |
--------------------------------------------------------------------------------
/testsuite/libffi.go/go.exp:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc.
2 |
3 | # This program is free software; you can redistribute it and/or modify
4 | # it under the terms of the GNU General Public License as published by
5 | # the Free Software Foundation; either version 3 of the License, or
6 | # (at your option) any later version.
7 | #
8 | # This program is distributed in the hope that it will be useful,
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | # GNU General Public License for more details.
12 | #
13 | # You should have received a copy of the GNU General Public License
14 | # along with this program; see the file COPYING3. If not see
15 | # .
16 |
17 | dg-init
18 | libffi-init
19 |
20 | global srcdir subdir
21 |
22 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]]
23 |
24 | if { [libffi_feature_test "#ifdef FFI_GO_CLOSURES"] } {
25 | run-many-tests $tlist ""
26 | } else {
27 | foreach test $tlist {
28 | unsupported "$test"
29 | }
30 | }
31 |
32 | dg-finish
33 |
34 | # Local Variables:
35 | # tcl-indent-level:4
36 | # End:
37 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/strlen2.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check strlen function call with additional arguments.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | static size_t ABI_ATTR my_f(char *s, float a)
12 | {
13 | return (size_t) ((int) strlen(s) + (int) a);
14 | }
15 |
16 | int main (void)
17 | {
18 | ffi_cif cif;
19 | ffi_type *args[MAX_ARGS];
20 | void *values[MAX_ARGS];
21 | ffi_arg rint;
22 | char *s;
23 | float v2;
24 | args[0] = &ffi_type_pointer;
25 | args[1] = &ffi_type_float;
26 | values[0] = (void*) &s;
27 | values[1] = (void*) &v2;
28 |
29 | /* Initialize the cif */
30 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 2,
31 | &ffi_type_sint, args) == FFI_OK);
32 |
33 | s = "a";
34 | v2 = 0.0;
35 | ffi_call(&cif, FFI_FN(my_f), &rint, values);
36 | CHECK(rint == 1);
37 |
38 | s = "1234567";
39 | v2 = -1.0;
40 | ffi_call(&cif, FFI_FN(my_f), &rint, values);
41 | CHECK(rint == 6);
42 |
43 | s = "1234567890123456789012345";
44 | v2 = 1.0;
45 | ffi_call(&cif, FFI_FN(my_f), &rint, values);
46 | CHECK(rint == 26);
47 |
48 | exit(0);
49 | }
50 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/strlen3.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check strlen function call with additional arguments.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | static size_t ABI_ATTR my_f(float a, char *s)
12 | {
13 | return (size_t) ((int) strlen(s) + (int) a);
14 | }
15 |
16 | int main (void)
17 | {
18 | ffi_cif cif;
19 | ffi_type *args[MAX_ARGS];
20 | void *values[MAX_ARGS];
21 | ffi_arg rint;
22 | char *s;
23 | float v2;
24 | args[1] = &ffi_type_pointer;
25 | args[0] = &ffi_type_float;
26 | values[1] = (void*) &s;
27 | values[0] = (void*) &v2;
28 |
29 | /* Initialize the cif */
30 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 2,
31 | &ffi_type_sint, args) == FFI_OK);
32 |
33 | s = "a";
34 | v2 = 0.0;
35 | ffi_call(&cif, FFI_FN(my_f), &rint, values);
36 | CHECK(rint == 1);
37 |
38 | s = "1234567";
39 | v2 = -1.0;
40 | ffi_call(&cif, FFI_FN(my_f), &rint, values);
41 | CHECK(rint == 6);
42 |
43 | s = "1234567890123456789012345";
44 | v2 = 1.0;
45 | ffi_call(&cif, FFI_FN(my_f), &rint, values);
46 | CHECK(rint == 26);
47 |
48 | exit(0);
49 | }
50 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/return_complex2.inc:
--------------------------------------------------------------------------------
1 | /* -*-c-*- */
2 | #include "ffitest.h"
3 | #include
4 |
5 | _Complex T_C_TYPE
6 | return_c(_Complex T_C_TYPE c1, _Complex T_C_TYPE c2,
7 | unsigned int in3, _Complex T_C_TYPE c4)
8 | {
9 | volatile _Complex T_C_TYPE r = c1 + c2 + in3 + c4;
10 | return r;
11 | }
12 |
13 | int main (void)
14 | {
15 | ffi_cif cif;
16 | ffi_type *args[MAX_ARGS];
17 | void *values[MAX_ARGS];
18 | _Complex T_C_TYPE c1, c2, c4, rc, rc2;
19 | unsigned int in3;
20 | args[0] = &T_FFI_TYPE;
21 | args[1] = &T_FFI_TYPE;
22 | args[2] = &ffi_type_uint;
23 | args[3] = &T_FFI_TYPE;
24 | values[0] = &c1;
25 | values[1] = &c2;
26 | values[2] = &in3;
27 | values[3] = &c4;
28 |
29 | /* Initialize the cif */
30 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
31 | &T_FFI_TYPE, args) == FFI_OK);
32 | c1 = 127.0 + 255.0 * I;
33 | c2 = 128.0 + 256.0;
34 | in3 = 255;
35 | c4 = 512.7 + 1024.1 * I;
36 |
37 | ffi_call(&cif, FFI_FN(return_c), &rc, values);
38 | rc2 = return_c(c1, c2, in3, c4);
39 | printf ("%f,%fi vs %f,%fi\n",
40 | T_CONV creal (rc), T_CONV cimag (rc),
41 | T_CONV creal (rc2), T_CONV cimag (rc2));
42 | CHECK(rc == rc2);
43 | exit(0);
44 | }
45 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/complex.exp:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc.
2 |
3 | # This program is free software; you can redistribute it and/or modify
4 | # it under the terms of the GNU General Public License as published by
5 | # the Free Software Foundation; either version 3 of the License, or
6 | # (at your option) any later version.
7 | #
8 | # This program is distributed in the hope that it will be useful,
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | # GNU General Public License for more details.
12 | #
13 | # You should have received a copy of the GNU General Public License
14 | # along with this program; see the file COPYING3. If not see
15 | # .
16 |
17 | dg-init
18 | libffi-init
19 |
20 | global srcdir subdir
21 |
22 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]]
23 |
24 | if { [libffi_feature_test "#ifdef FFI_TARGET_HAS_COMPLEX_TYPE"] } {
25 | run-many-tests $tlist ""
26 | } else {
27 | foreach test $tlist {
28 | unsupported "$test"
29 | }
30 | }
31 |
32 | dg-finish
33 |
34 | # Local Variables:
35 | # tcl-indent-level:4
36 | # End:
37 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_ll1.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check if long long are passed in the corresponding regs on ppc.
3 | Limitations: none.
4 | PR: 20104.
5 | Originator: 20050222 */
6 |
7 | /* { dg-do run } */
8 | /* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
9 | #include "ffitest.h"
10 | static long long return_ll(int ll0, long long ll1, int ll2)
11 | {
12 | return ll0 + ll1 + ll2;
13 | }
14 |
15 | int main (void)
16 | {
17 | ffi_cif cif;
18 | ffi_type *args[MAX_ARGS];
19 | void *values[MAX_ARGS];
20 | long long rlonglong;
21 | long long ll1;
22 | unsigned ll0, ll2;
23 |
24 | args[0] = &ffi_type_sint;
25 | args[1] = &ffi_type_sint64;
26 | args[2] = &ffi_type_sint;
27 | values[0] = &ll0;
28 | values[1] = &ll1;
29 | values[2] = &ll2;
30 |
31 | /* Initialize the cif */
32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
33 | &ffi_type_sint64, args) == FFI_OK);
34 |
35 | ll0 = 11111111;
36 | ll1 = 11111111111000LL;
37 | ll2 = 11111111;
38 |
39 | ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
40 | printf("res: %" PRIdLL ", %" PRIdLL "\n", rlonglong, ll0 + ll1 + ll2);
41 | /* { dg-output "res: 11111133333222, 11111133333222" } */
42 | exit(0);
43 | }
44 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_sint.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value sint32.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20031108 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static void cls_ret_sint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
11 | void* userdata __UNUSED__)
12 | {
13 | *(ffi_arg*)resp = *(signed int *)args[0];
14 | printf("%d: %d\n",*(signed int *)args[0],
15 | (int)*(ffi_arg *)(resp));
16 | }
17 | typedef signed int (*cls_ret_sint)(signed int);
18 |
19 | int main (void)
20 | {
21 | ffi_cif cif;
22 | void *code;
23 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
24 | ffi_type * cl_arg_types[2];
25 | signed int res;
26 |
27 | cl_arg_types[0] = &ffi_type_sint;
28 | cl_arg_types[1] = NULL;
29 |
30 | /* Initialize the cif */
31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
32 | &ffi_type_sint, cl_arg_types) == FFI_OK);
33 |
34 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sint_fn, NULL, code) == FFI_OK);
35 |
36 | res = (*((cls_ret_sint)code))(65534);
37 | /* { dg-output "65534: 65534" } */
38 | printf("res: %d\n",res);
39 | /* { dg-output "\nres: 65534" } */
40 |
41 | exit(0);
42 | }
43 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_float.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value float.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20030828 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static void cls_ret_float_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
11 | void* userdata __UNUSED__)
12 | {
13 | *(float *)resp = *(float *)args[0];
14 |
15 | printf("%g: %g\n",*(float *)args[0],
16 | *(float *)resp);
17 | }
18 |
19 | typedef float (*cls_ret_float)(float);
20 |
21 | int main (void)
22 | {
23 | ffi_cif cif;
24 | void *code;
25 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
26 | ffi_type * cl_arg_types[2];
27 | float res;
28 |
29 | cl_arg_types[0] = &ffi_type_float;
30 | cl_arg_types[1] = NULL;
31 |
32 | /* Initialize the cif */
33 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
34 | &ffi_type_float, cl_arg_types) == FFI_OK);
35 |
36 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_float_fn, NULL, code) == FFI_OK);
37 | res = ((((cls_ret_float)code)(-2122.12)));
38 | /* { dg-output "\\-2122.12: \\-2122.12" } */
39 | printf("res: %.6f\n", res);
40 | /* { dg-output "\nres: \-2122.120117" } */
41 | exit(0);
42 | }
43 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_uchar.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value uchar.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20030828 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static void cls_ret_uchar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
11 | void* userdata __UNUSED__)
12 | {
13 | *(ffi_arg*)resp = *(unsigned char *)args[0];
14 | printf("%d: %d\n",*(unsigned char *)args[0],
15 | (int)*(ffi_arg *)(resp));
16 | }
17 | typedef unsigned char (*cls_ret_uchar)(unsigned char);
18 |
19 | int main (void)
20 | {
21 | ffi_cif cif;
22 | void *code;
23 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
24 | ffi_type * cl_arg_types[2];
25 | unsigned char res;
26 |
27 | cl_arg_types[0] = &ffi_type_uchar;
28 | cl_arg_types[1] = NULL;
29 |
30 | /* Initialize the cif */
31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
32 | &ffi_type_uchar, cl_arg_types) == FFI_OK);
33 |
34 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uchar_fn, NULL, code) == FFI_OK);
35 |
36 | res = (*((cls_ret_uchar)code))(127);
37 | /* { dg-output "127: 127" } */
38 | printf("res: %d\n",res);
39 | /* { dg-output "\nres: 127" } */
40 |
41 | exit(0);
42 | }
43 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_schar.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value schar.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20031108 */
6 |
7 |
8 |
9 | /* { dg-do run } */
10 | #include "ffitest.h"
11 |
12 | static void cls_ret_schar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
13 | void* userdata __UNUSED__)
14 | {
15 | *(ffi_arg*)resp = *(signed char *)args[0];
16 | printf("%d: %d\n",*(signed char *)args[0],
17 | (int)*(ffi_arg *)(resp));
18 | }
19 | typedef signed char (*cls_ret_schar)(signed char);
20 |
21 | int main (void)
22 | {
23 | ffi_cif cif;
24 | void *code;
25 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
26 | ffi_type * cl_arg_types[2];
27 | signed char res;
28 |
29 | cl_arg_types[0] = &ffi_type_schar;
30 | cl_arg_types[1] = NULL;
31 |
32 | /* Initialize the cif */
33 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
34 | &ffi_type_schar, cl_arg_types) == FFI_OK);
35 |
36 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_schar_fn, NULL, code) == FFI_OK);
37 |
38 | res = (*((cls_ret_schar)code))(127);
39 | /* { dg-output "127: 127" } */
40 | printf("res: %d\n", res);
41 | /* { dg-output "\nres: 127" } */
42 |
43 | exit(0);
44 | }
45 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_sshort.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value sshort.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20031108 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static void cls_ret_sshort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
11 | void* userdata __UNUSED__)
12 | {
13 | *(ffi_arg*)resp = *(signed short *)args[0];
14 | printf("%d: %d\n",*(signed short *)args[0],
15 | (int)*(ffi_arg *)(resp));
16 | }
17 | typedef signed short (*cls_ret_sshort)(signed short);
18 |
19 | int main (void)
20 | {
21 | ffi_cif cif;
22 | void *code;
23 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
24 | ffi_type * cl_arg_types[2];
25 | signed short res;
26 |
27 | cl_arg_types[0] = &ffi_type_sshort;
28 | cl_arg_types[1] = NULL;
29 |
30 | /* Initialize the cif */
31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
32 | &ffi_type_sshort, cl_arg_types) == FFI_OK);
33 |
34 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sshort_fn, NULL, code) == FFI_OK);
35 |
36 | res = (*((cls_ret_sshort)code))(255);
37 | /* { dg-output "255: 255" } */
38 | printf("res: %d\n",res);
39 | /* { dg-output "\nres: 255" } */
40 |
41 | exit(0);
42 | }
43 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_ulong_va.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Test anonymous unsigned long argument.
3 | Limitations: none.
4 | PR: none.
5 | Originator: ARM Ltd. */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | typedef unsigned long T;
12 |
13 | static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
14 | void* userdata __UNUSED__)
15 | {
16 | *(T *)resp = *(T *)args[0];
17 |
18 | printf("%ld: %ld %ld\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
19 | }
20 |
21 | typedef T (*cls_ret_T)(T, ...);
22 |
23 | int main (void)
24 | {
25 | ffi_cif cif;
26 | void *code;
27 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
28 | ffi_type * cl_arg_types[3];
29 | T res;
30 |
31 | cl_arg_types[0] = &ffi_type_ulong;
32 | cl_arg_types[1] = &ffi_type_ulong;
33 | cl_arg_types[2] = NULL;
34 |
35 | /* Initialize the cif */
36 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
37 | &ffi_type_ulong, cl_arg_types) == FFI_OK);
38 |
39 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
40 | res = ((((cls_ret_T)code)(67, 4)));
41 | /* { dg-output "67: 67 4" } */
42 | printf("res: %ld\n", res);
43 | /* { dg-output "\nres: 67" } */
44 | exit(0);
45 | }
46 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_double.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value double.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20030828 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
11 | void* userdata __UNUSED__)
12 | {
13 | *(double *)resp = *(double *)args[0];
14 |
15 | printf("%f: %f\n",*(double *)args[0],
16 | *(double *)resp);
17 | }
18 | typedef double (*cls_ret_double)(double);
19 |
20 | int main (void)
21 | {
22 | ffi_cif cif;
23 | void *code;
24 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
25 | ffi_type * cl_arg_types[2];
26 | double res;
27 |
28 | cl_arg_types[0] = &ffi_type_double;
29 | cl_arg_types[1] = NULL;
30 |
31 | /* Initialize the cif */
32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
33 | &ffi_type_double, cl_arg_types) == FFI_OK);
34 |
35 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK);
36 |
37 | res = (*((cls_ret_double)code))(21474.789);
38 | /* { dg-output "21474.789000: 21474.789000" } */
39 | printf("res: %.6f\n", res);
40 | /* { dg-output "\nres: 21474.789000" } */
41 |
42 | exit(0);
43 | }
44 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_uchar_va.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Test anonymous unsigned char argument.
3 | Limitations: none.
4 | PR: none.
5 | Originator: ARM Ltd. */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | typedef unsigned char T;
11 |
12 | static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
13 | void* userdata __UNUSED__)
14 | {
15 | *(ffi_arg *)resp = *(T *)args[0];
16 |
17 | printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]);
18 | }
19 |
20 | typedef T (*cls_ret_T)(T, ...);
21 |
22 | int main (void)
23 | {
24 | ffi_cif cif;
25 | void *code;
26 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
27 | ffi_type * cl_arg_types[3];
28 | T res;
29 |
30 | cl_arg_types[0] = &ffi_type_uchar;
31 | cl_arg_types[1] = &ffi_type_uchar;
32 | cl_arg_types[2] = NULL;
33 |
34 | /* Initialize the cif */
35 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
36 | &ffi_type_uchar, cl_arg_types) == FFI_OK);
37 |
38 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
39 | res = ((((cls_ret_T)code)(67, 4)));
40 | /* { dg-output "67: 67 4" } */
41 | printf("res: %d\n", res);
42 | /* { dg-output "\nres: 67" } */
43 | exit(0);
44 | }
45 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_uint.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value uint.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20030828 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static void cls_ret_uint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
11 | void* userdata __UNUSED__)
12 | {
13 | *(ffi_arg *)resp = *(unsigned int *)args[0];
14 |
15 | printf("%d: %d\n",*(unsigned int *)args[0],
16 | (int)*(ffi_arg *)(resp));
17 | }
18 | typedef unsigned int (*cls_ret_uint)(unsigned int);
19 |
20 | int main (void)
21 | {
22 | ffi_cif cif;
23 | void *code;
24 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
25 | ffi_type * cl_arg_types[2];
26 | unsigned int res;
27 |
28 | cl_arg_types[0] = &ffi_type_uint;
29 | cl_arg_types[1] = NULL;
30 |
31 | /* Initialize the cif */
32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
33 | &ffi_type_uint, cl_arg_types) == FFI_OK);
34 |
35 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uint_fn, NULL, code) == FFI_OK);
36 |
37 | res = (*((cls_ret_uint)code))(2147483647);
38 | /* { dg-output "2147483647: 2147483647" } */
39 | printf("res: %d\n",res);
40 | /* { dg-output "\nres: 2147483647" } */
41 |
42 | exit(0);
43 | }
44 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_uint_va.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Test anonymous unsigned int argument.
3 | Limitations: none.
4 | PR: none.
5 | Originator: ARM Ltd. */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | typedef unsigned int T;
12 |
13 | static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
14 | void* userdata __UNUSED__)
15 | {
16 | *(ffi_arg *)resp = *(T *)args[0];
17 |
18 | printf("%d: %d %d\n", (int)*(ffi_arg *)resp, *(T *)args[0], *(T *)args[1]);
19 | }
20 |
21 | typedef T (*cls_ret_T)(T, ...);
22 |
23 | int main (void)
24 | {
25 | ffi_cif cif;
26 | void *code;
27 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
28 | ffi_type * cl_arg_types[3];
29 | T res;
30 |
31 | cl_arg_types[0] = &ffi_type_uint;
32 | cl_arg_types[1] = &ffi_type_uint;
33 | cl_arg_types[2] = NULL;
34 |
35 | /* Initialize the cif */
36 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
37 | &ffi_type_uint, cl_arg_types) == FFI_OK);
38 |
39 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
40 | res = ((((cls_ret_T)code)(67, 4)));
41 | /* { dg-output "67: 67 4" } */
42 | printf("res: %d\n", res);
43 | /* { dg-output "\nres: 67" } */
44 | exit(0);
45 | }
46 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_ushort_va.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Test anonymous unsigned short argument.
3 | Limitations: none.
4 | PR: none.
5 | Originator: ARM Ltd. */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | typedef unsigned short T;
11 |
12 | static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
13 | void* userdata __UNUSED__)
14 | {
15 | *(ffi_arg *)resp = *(T *)args[0];
16 |
17 | printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]);
18 | }
19 |
20 | typedef T (*cls_ret_T)(T, ...);
21 |
22 | int main (void)
23 | {
24 | ffi_cif cif;
25 | void *code;
26 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
27 | ffi_type * cl_arg_types[3];
28 | T res;
29 |
30 | cl_arg_types[0] = &ffi_type_ushort;
31 | cl_arg_types[1] = &ffi_type_ushort;
32 | cl_arg_types[2] = NULL;
33 |
34 | /* Initialize the cif */
35 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
36 | &ffi_type_ushort, cl_arg_types) == FFI_OK);
37 |
38 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
39 | res = ((((cls_ret_T)code)(67, 4)));
40 | /* { dg-output "67: 67 4" } */
41 | printf("res: %d\n", res);
42 | /* { dg-output "\nres: 67" } */
43 | exit(0);
44 | }
45 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/offsets.c:
--------------------------------------------------------------------------------
1 | /* Area: Struct layout
2 | Purpose: Test ffi_get_struct_offsets
3 | Limitations: none.
4 | PR: none.
5 | Originator: Tom Tromey. */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | #include
10 |
11 | struct test_1
12 | {
13 | char c;
14 | float f;
15 | char c2;
16 | int i;
17 | };
18 |
19 | int
20 | main (void)
21 | {
22 | ffi_type test_1_type;
23 | ffi_type *test_1_elements[5];
24 | size_t test_1_offsets[4];
25 |
26 | test_1_elements[0] = &ffi_type_schar;
27 | test_1_elements[1] = &ffi_type_float;
28 | test_1_elements[2] = &ffi_type_schar;
29 | test_1_elements[3] = &ffi_type_sint;
30 | test_1_elements[4] = NULL;
31 |
32 | test_1_type.size = 0;
33 | test_1_type.alignment = 0;
34 | test_1_type.type = FFI_TYPE_STRUCT;
35 | test_1_type.elements = test_1_elements;
36 |
37 | CHECK (ffi_get_struct_offsets (FFI_DEFAULT_ABI, &test_1_type, test_1_offsets)
38 | == FFI_OK);
39 | CHECK (test_1_type.size == sizeof (struct test_1));
40 | CHECK (offsetof (struct test_1, c) == test_1_offsets[0]);
41 | CHECK (offsetof (struct test_1, f) == test_1_offsets[1]);
42 | CHECK (offsetof (struct test_1, c2) == test_1_offsets[2]);
43 | CHECK (offsetof (struct test_1, i) == test_1_offsets[3]);
44 |
45 | return 0;
46 | }
47 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_ushort.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value ushort.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20030828 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static void cls_ret_ushort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
11 | void* userdata __UNUSED__)
12 | {
13 | *(ffi_arg*)resp = *(unsigned short *)args[0];
14 |
15 | printf("%d: %d\n",*(unsigned short *)args[0],
16 | (int)*(ffi_arg *)(resp));
17 | }
18 | typedef unsigned short (*cls_ret_ushort)(unsigned short);
19 |
20 | int main (void)
21 | {
22 | ffi_cif cif;
23 | void *code;
24 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
25 | ffi_type * cl_arg_types[2];
26 | unsigned short res;
27 |
28 | cl_arg_types[0] = &ffi_type_ushort;
29 | cl_arg_types[1] = NULL;
30 |
31 | /* Initialize the cif */
32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
33 | &ffi_type_ushort, cl_arg_types) == FFI_OK);
34 |
35 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ushort_fn, NULL, code) == FFI_OK);
36 |
37 | res = (*((cls_ret_ushort)code))(65535);
38 | /* { dg-output "65535: 65535" } */
39 | printf("res: %d\n",res);
40 | /* { dg-output "\nres: 65535" } */
41 |
42 | exit(0);
43 | }
44 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/struct10.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check structures.
3 | Limitations: none.
4 | PR: none.
5 | Originator: Sergei Trofimovich
6 |
7 | The test originally discovered in ruby's bindings
8 | for ffi in https://bugs.gentoo.org/634190 */
9 |
10 | /* { dg-do run } */
11 | #include "ffitest.h"
12 |
13 | struct s {
14 | int s32;
15 | float f32;
16 | signed char s8;
17 | };
18 |
19 | struct s make_s(void) {
20 | struct s r;
21 | r.s32 = 0x1234;
22 | r.f32 = 7.0;
23 | r.s8 = 0x78;
24 | return r;
25 | }
26 |
27 | int main() {
28 | ffi_cif cif;
29 | struct s r;
30 | ffi_type rtype;
31 | ffi_type* s_fields[] = {
32 | &ffi_type_sint,
33 | &ffi_type_float,
34 | &ffi_type_schar,
35 | NULL,
36 | };
37 |
38 | rtype.size = 0;
39 | rtype.alignment = 0,
40 | rtype.type = FFI_TYPE_STRUCT,
41 | rtype.elements = s_fields,
42 |
43 | r.s32 = 0xbad;
44 | r.f32 = 999.999;
45 | r.s8 = 0x51;
46 |
47 | // Here we emulate the following call:
48 | //r = make_s();
49 |
50 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &rtype, NULL) == FFI_OK);
51 | ffi_call(&cif, FFI_FN(make_s), &r, NULL);
52 |
53 | CHECK(r.s32 == 0x1234);
54 | CHECK(r.f32 == 7.0);
55 | CHECK(r.s8 == 0x78);
56 | exit(0);
57 | }
58 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/unwindtest_ffi_call.cc:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, unwind info
2 | Purpose: Check if the unwind information is passed correctly.
3 | Limitations: none.
4 | PR: none.
5 | Originator: Andreas Tobler 20061213 */
6 |
7 | /* { dg-do run { xfail moxie*-*-* } } */
8 |
9 | #include "ffitest.h"
10 |
11 | static int checking(int a __UNUSED__, short b __UNUSED__,
12 | signed char c __UNUSED__)
13 | {
14 | throw 9;
15 | }
16 |
17 | int main (void)
18 | {
19 | ffi_cif cif;
20 | ffi_type *args[MAX_ARGS];
21 | void *values[MAX_ARGS];
22 | ffi_arg rint;
23 |
24 | signed int si;
25 | signed short ss;
26 | signed char sc;
27 |
28 | args[0] = &ffi_type_sint;
29 | values[0] = &si;
30 | args[1] = &ffi_type_sshort;
31 | values[1] = &ss;
32 | args[2] = &ffi_type_schar;
33 | values[2] = ≻
34 |
35 | /* Initialize the cif */
36 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
37 | &ffi_type_sint, args) == FFI_OK);
38 |
39 | si = -6;
40 | ss = -12;
41 | sc = -1;
42 | {
43 | try
44 | {
45 | ffi_call(&cif, FFI_FN(checking), &rint, values);
46 | } catch (int exception_code)
47 | {
48 | CHECK(exception_code == 9);
49 | }
50 | printf("part one OK\n");
51 | /* { dg-output "part one OK" } */
52 | }
53 | exit(0);
54 | }
55 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex.inc:
--------------------------------------------------------------------------------
1 | /* -*-c-*- */
2 | #include "ffitest.h"
3 | #include
4 |
5 | static void cls_ret_complex_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
6 | void* userdata __UNUSED__)
7 | {
8 | _Complex T_C_TYPE *pa;
9 | _Complex T_C_TYPE *pr;
10 | pa = (_Complex T_C_TYPE *)args[0];
11 | pr = (_Complex T_C_TYPE *)resp;
12 | *pr = *pa;
13 |
14 | printf("%.6f,%.6fi: %.6f,%.6fi\n",
15 | T_CONV creal (*pa), T_CONV cimag (*pa),
16 | T_CONV creal (*pr), T_CONV cimag (*pr));
17 | }
18 | typedef _Complex T_C_TYPE (*cls_ret_complex)(_Complex T_C_TYPE);
19 |
20 | int main (void)
21 | {
22 | ffi_cif cif;
23 | void *code;
24 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
25 | ffi_type * cl_arg_types[2];
26 | _Complex T_C_TYPE res;
27 |
28 | cl_arg_types[0] = &T_FFI_TYPE;
29 | cl_arg_types[1] = NULL;
30 |
31 | /* Initialize the cif */
32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
33 | &T_FFI_TYPE, cl_arg_types) == FFI_OK);
34 |
35 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_complex_fn, NULL, code) == FFI_OK);
36 |
37 | res = (*((cls_ret_complex)code))(0.125 + 128.0 * I);
38 | printf("res: %.6f,%.6fi\n", T_CONV creal (res), T_CONV cimag (res));
39 | CHECK (res == (0.125 + 128.0 * I));
40 |
41 | exit(0);
42 | }
43 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/return_fl2.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value float.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20050212 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | /* Use volatile float to avoid false negative on ix86. See PR target/323. */
11 | static float return_fl(float fl1, float fl2, float fl3, float fl4)
12 | {
13 | volatile float sum;
14 |
15 | sum = fl1 + fl2 + fl3 + fl4;
16 | return sum;
17 | }
18 | int main (void)
19 | {
20 | ffi_cif cif;
21 | ffi_type *args[MAX_ARGS];
22 | void *values[MAX_ARGS];
23 | float fl1, fl2, fl3, fl4, rfl;
24 | volatile float sum;
25 |
26 | args[0] = &ffi_type_float;
27 | args[1] = &ffi_type_float;
28 | args[2] = &ffi_type_float;
29 | args[3] = &ffi_type_float;
30 | values[0] = &fl1;
31 | values[1] = &fl2;
32 | values[2] = &fl3;
33 | values[3] = &fl4;
34 |
35 | /* Initialize the cif */
36 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
37 | &ffi_type_float, args) == FFI_OK);
38 | fl1 = 127.0;
39 | fl2 = 128.0;
40 | fl3 = 255.1;
41 | fl4 = 512.7;
42 |
43 | ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
44 | printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, fl3, fl4));
45 |
46 | sum = fl1 + fl2 + fl3 + fl4;
47 | CHECK(rfl == sum);
48 | exit(0);
49 | }
50 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/many2.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check uint8_t arguments.
3 | Limitations: none.
4 | PR: PR45677.
5 | Originator: Dan Witte 20100916 */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | #define NARGS 7
12 |
13 | typedef unsigned char u8;
14 |
15 | #ifdef __GNUC__
16 | __attribute__((noinline))
17 | #endif
18 | uint8_t
19 | foo (uint8_t a, uint8_t b, uint8_t c, uint8_t d,
20 | uint8_t e, uint8_t f, uint8_t g)
21 | {
22 | return a + b + c + d + e + f + g;
23 | }
24 |
25 | uint8_t ABI_ATTR
26 | bar (uint8_t a, uint8_t b, uint8_t c, uint8_t d,
27 | uint8_t e, uint8_t f, uint8_t g)
28 | {
29 | return foo (a, b, c, d, e, f, g);
30 | }
31 |
32 | int
33 | main (void)
34 | {
35 | ffi_type *ffitypes[NARGS];
36 | int i;
37 | ffi_cif cif;
38 | ffi_arg result = 0;
39 | uint8_t args[NARGS];
40 | void *argptrs[NARGS];
41 |
42 | for (i = 0; i < NARGS; ++i)
43 | ffitypes[i] = &ffi_type_uint8;
44 |
45 | CHECK (ffi_prep_cif (&cif, ABI_NUM, NARGS,
46 | &ffi_type_uint8, ffitypes) == FFI_OK);
47 |
48 | for (i = 0; i < NARGS; ++i)
49 | {
50 | args[i] = i;
51 | argptrs[i] = &args[i];
52 | }
53 | ffi_call (&cif, FFI_FN (bar), &result, argptrs);
54 |
55 | CHECK (result == 21);
56 | return 0;
57 | }
58 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/strlen4.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check strlen function call with additional arguments.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | static size_t ABI_ATTR my_f(float a, char *s, int i)
12 | {
13 | return (size_t) ((int) strlen(s) + (int) a + i);
14 | }
15 |
16 | int main (void)
17 | {
18 | ffi_cif cif;
19 | ffi_type *args[MAX_ARGS];
20 | void *values[MAX_ARGS];
21 | ffi_arg rint;
22 | char *s;
23 | int v1;
24 | float v2;
25 | args[2] = &ffi_type_sint;
26 | args[1] = &ffi_type_pointer;
27 | args[0] = &ffi_type_float;
28 | values[2] = (void*) &v1;
29 | values[1] = (void*) &s;
30 | values[0] = (void*) &v2;
31 |
32 | /* Initialize the cif */
33 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 3,
34 | &ffi_type_sint, args) == FFI_OK);
35 |
36 | s = "a";
37 | v1 = 1;
38 | v2 = 0.0;
39 | ffi_call(&cif, FFI_FN(my_f), &rint, values);
40 | CHECK(rint == 2);
41 |
42 | s = "1234567";
43 | v2 = -1.0;
44 | v1 = -2;
45 | ffi_call(&cif, FFI_FN(my_f), &rint, values);
46 | CHECK(rint == 4);
47 |
48 | s = "1234567890123456789012345";
49 | v2 = 1.0;
50 | v1 = 2;
51 | ffi_call(&cif, FFI_FN(my_f), &rint, values);
52 | CHECK(rint == 28);
53 |
54 | exit(0);
55 | }
56 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/float.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value float.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | static int floating(int a, float b, double c, long double d)
12 | {
13 | int i;
14 |
15 | i = (int) ((float)a/b + ((float)c/(float)d));
16 |
17 | return i;
18 | }
19 |
20 | int main (void)
21 | {
22 | ffi_cif cif;
23 | ffi_type *args[MAX_ARGS];
24 | void *values[MAX_ARGS];
25 | ffi_arg rint;
26 |
27 | float f;
28 | signed int si1;
29 | double d;
30 | long double ld;
31 |
32 | args[0] = &ffi_type_sint;
33 | values[0] = &si1;
34 | args[1] = &ffi_type_float;
35 | values[1] = &f;
36 | args[2] = &ffi_type_double;
37 | values[2] = &d;
38 | args[3] = &ffi_type_longdouble;
39 | values[3] = &ld;
40 |
41 | /* Initialize the cif */
42 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
43 | &ffi_type_sint, args) == FFI_OK);
44 |
45 | si1 = 6;
46 | f = 3.14159;
47 | d = (double)1.0/(double)3.0;
48 | ld = 2.71828182846L;
49 |
50 | floating (si1, f, d, ld);
51 |
52 | ffi_call(&cif, FFI_FN(floating), &rint, values);
53 |
54 | printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld));
55 |
56 | CHECK((int)rint == floating(si1, f, d, ld));
57 |
58 | exit (0);
59 | }
60 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/complex.inc:
--------------------------------------------------------------------------------
1 | /* -*-c-*-*/
2 | #include "ffitest.h"
3 | #include
4 |
5 | static _Complex T_C_TYPE f_complex(_Complex T_C_TYPE c, int x, int *py)
6 | {
7 | c = -(2 * creal (c)) + (cimag (c) + 1)* I;
8 | *py += x;
9 |
10 | return c;
11 | }
12 |
13 | int main (void)
14 | {
15 | ffi_cif cif;
16 | ffi_type *args[MAX_ARGS];
17 | void *values[MAX_ARGS];
18 |
19 | _Complex T_C_TYPE tc_arg;
20 | _Complex T_C_TYPE tc_result;
21 | int tc_int_arg_x;
22 | int tc_y;
23 | int *tc_ptr_arg_y = &tc_y;
24 |
25 | args[0] = &T_FFI_TYPE;
26 | args[1] = &ffi_type_sint;
27 | args[2] = &ffi_type_pointer;
28 | values[0] = &tc_arg;
29 | values[1] = &tc_int_arg_x;
30 | values[2] = &tc_ptr_arg_y;
31 |
32 | /* Initialize the cif */
33 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
34 | &T_FFI_TYPE, args) == FFI_OK);
35 |
36 | tc_arg = 1 + 7 * I;
37 | tc_int_arg_x = 1234;
38 | tc_y = 9876;
39 | ffi_call(&cif, FFI_FN(f_complex), &tc_result, values);
40 |
41 | printf ("%f,%fi %f,%fi, x %d 1234, y %d 11110\n",
42 | T_CONV creal (tc_result), T_CONV cimag (tc_result),
43 | T_CONV creal (2.0), T_CONV creal (8.0), tc_int_arg_x, tc_y);
44 |
45 | CHECK (creal (tc_result) == -2);
46 | CHECK (cimag (tc_result) == 8);
47 | CHECK (tc_int_arg_x == 1234);
48 | CHECK (*tc_ptr_arg_y == 11110);
49 |
50 | exit(0);
51 | }
52 |
--------------------------------------------------------------------------------
/m4/ax_require_defined.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_REQUIRE_DEFINED(MACRO)
8 | #
9 | # DESCRIPTION
10 | #
11 | # AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
12 | # been defined and thus are available for use. This avoids random issues
13 | # where a macro isn't expanded. Instead the configure script emits a
14 | # non-fatal:
15 | #
16 | # ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
17 | #
18 | # It's like AC_REQUIRE except it doesn't expand the required macro.
19 | #
20 | # Here's an example:
21 | #
22 | # AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
23 | #
24 | # LICENSE
25 | #
26 | # Copyright (c) 2014 Mike Frysinger
27 | #
28 | # Copying and distribution of this file, with or without modification, are
29 | # permitted in any medium without royalty provided the copyright notice
30 | # and this notice are preserved. This file is offered as-is, without any
31 | # warranty.
32 |
33 | #serial 2
34 |
35 | AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
36 | m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
37 | ])dnl AX_REQUIRE_DEFINED
38 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/float1.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value double.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | #include "float.h"
10 |
11 | #include
12 |
13 | typedef union
14 | {
15 | double d;
16 | unsigned char c[sizeof (double)];
17 | } value_type;
18 |
19 | #define CANARY 0xba
20 |
21 | static double dblit(float f)
22 | {
23 | return f/3.0;
24 | }
25 |
26 | int main (void)
27 | {
28 | ffi_cif cif;
29 | ffi_type *args[MAX_ARGS];
30 | void *values[MAX_ARGS];
31 | float f;
32 | value_type result[2];
33 | unsigned int i;
34 |
35 | args[0] = &ffi_type_float;
36 | values[0] = &f;
37 |
38 | /* Initialize the cif */
39 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
40 | &ffi_type_double, args) == FFI_OK);
41 |
42 | f = 3.14159;
43 |
44 | /* Put a canary in the return array. This is a regression test for
45 | a buffer overrun. */
46 | memset(result[1].c, CANARY, sizeof (double));
47 |
48 | ffi_call(&cif, FFI_FN(dblit), &result[0].d, values);
49 |
50 | /* These are not always the same!! Check for a reasonable delta */
51 |
52 | CHECK(fabs(result[0].d - dblit(f)) < DBL_EPSILON);
53 |
54 | /* Check the canary. */
55 | for (i = 0; i < sizeof (double); ++i)
56 | CHECK(result[1].c[i] == CANARY);
57 |
58 | exit(0);
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/man/ffi_prep_cif.3:
--------------------------------------------------------------------------------
1 | .Dd February 15, 2008
2 | .Dt ffi_prep_cif 3
3 | .Sh NAME
4 | .Nm ffi_prep_cif
5 | .Nd Prepare a
6 | .Nm ffi_cif
7 | structure for use with
8 | .Nm ffi_call
9 | .
10 | .Sh SYNOPSIS
11 | .In ffi.h
12 | .Ft ffi_status
13 | .Fo ffi_prep_cif
14 | .Fa "ffi_cif *cif"
15 | .Fa "ffi_abi abi"
16 | .Fa "unsigned int nargs"
17 | .Fa "ffi_type *rtype"
18 | .Fa "ffi_type **atypes"
19 | .Fc
20 | .Sh DESCRIPTION
21 | The
22 | .Nm ffi_prep_cif
23 | function prepares a
24 | .Nm ffi_cif
25 | structure for use with
26 | .Nm ffi_call
27 | .
28 | .Fa abi
29 | specifies a set of calling conventions to use.
30 | .Fa atypes
31 | is an array of
32 | .Fa nargs
33 | pointers to
34 | .Nm ffi_type
35 | structs that describe the data type, size and alignment of each argument.
36 | .Fa rtype
37 | points to an
38 | .Nm ffi_type
39 | that describes the data type, size and alignment of the
40 | return value. Note that to call a variadic function
41 | .Nm ffi_prep_cif_var
42 | must be used instead.
43 | .Sh RETURN VALUES
44 | Upon successful completion,
45 | .Nm ffi_prep_cif
46 | returns
47 | .Nm FFI_OK .
48 | It will return
49 | .Nm FFI_BAD_TYPEDEF
50 | if
51 | .Fa cif
52 | is
53 | .Nm NULL
54 | or
55 | .Fa atypes
56 | or
57 | .Fa rtype
58 | is malformed. If
59 | .Fa abi
60 | does not refer to a valid ABI,
61 | .Nm FFI_BAD_ABI
62 | will be returned. Available ABIs are
63 | defined in
64 | .Nm .
65 | .Sh SEE ALSO
66 | .Xr ffi 3 ,
67 | .Xr ffi_call 3 ,
68 | .Xr ffi_prep_cif_var 3
69 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/struct3.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check structures.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | typedef struct
11 | {
12 | int si;
13 | } test_structure_3;
14 |
15 | static test_structure_3 ABI_ATTR struct3(test_structure_3 ts)
16 | {
17 | ts.si = -(ts.si*2);
18 |
19 | return ts;
20 | }
21 |
22 | int main (void)
23 | {
24 | ffi_cif cif;
25 | ffi_type *args[MAX_ARGS];
26 | void *values[MAX_ARGS];
27 | int compare_value;
28 | ffi_type ts3_type;
29 | ffi_type *ts3_type_elements[2];
30 |
31 | test_structure_3 ts3_arg;
32 | test_structure_3 *ts3_result =
33 | (test_structure_3 *) malloc (sizeof(test_structure_3));
34 |
35 | ts3_type.size = 0;
36 | ts3_type.alignment = 0;
37 | ts3_type.type = FFI_TYPE_STRUCT;
38 | ts3_type.elements = ts3_type_elements;
39 | ts3_type_elements[0] = &ffi_type_sint;
40 | ts3_type_elements[1] = NULL;
41 |
42 | args[0] = &ts3_type;
43 | values[0] = &ts3_arg;
44 |
45 | /* Initialize the cif */
46 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1,
47 | &ts3_type, args) == FFI_OK);
48 |
49 | ts3_arg.si = -123;
50 | compare_value = ts3_arg.si;
51 |
52 | ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
53 |
54 | printf ("%d %d\n", ts3_result->si, -(compare_value*2));
55 |
56 | CHECK(ts3_result->si == -(compare_value*2));
57 |
58 | free (ts3_result);
59 | exit(0);
60 | }
61 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/uninitialized.c:
--------------------------------------------------------------------------------
1 | /* { dg-do run } */
2 | #include "ffitest.h"
3 |
4 | typedef struct
5 | {
6 | unsigned char uc;
7 | double d;
8 | unsigned int ui;
9 | } test_structure_1;
10 |
11 | static test_structure_1 struct1(test_structure_1 ts)
12 | {
13 | ts.uc++;
14 | ts.d--;
15 | ts.ui++;
16 |
17 | return ts;
18 | }
19 |
20 | int main (void)
21 | {
22 | ffi_cif cif;
23 | ffi_type *args[MAX_ARGS];
24 | void *values[MAX_ARGS];
25 | ffi_type ts1_type;
26 | ffi_type *ts1_type_elements[4];
27 |
28 | memset(&cif, 1, sizeof(cif));
29 | ts1_type.size = 0;
30 | ts1_type.alignment = 0;
31 | ts1_type.type = FFI_TYPE_STRUCT;
32 | ts1_type.elements = ts1_type_elements;
33 | ts1_type_elements[0] = &ffi_type_uchar;
34 | ts1_type_elements[1] = &ffi_type_double;
35 | ts1_type_elements[2] = &ffi_type_uint;
36 | ts1_type_elements[3] = NULL;
37 |
38 | test_structure_1 ts1_arg;
39 | /* This is a hack to get a properly aligned result buffer */
40 | test_structure_1 *ts1_result =
41 | (test_structure_1 *) malloc (sizeof(test_structure_1));
42 |
43 | args[0] = &ts1_type;
44 | values[0] = &ts1_arg;
45 |
46 | /* Initialize the cif */
47 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
48 | &ts1_type, args) == FFI_OK);
49 |
50 | ts1_arg.uc = '\x01';
51 | ts1_arg.d = 3.14159;
52 | ts1_arg.ui = 555;
53 |
54 | ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
55 |
56 | CHECK(ts1_result->ui == 556);
57 | CHECK(ts1_result->d == 3.14159 - 1);
58 |
59 | free (ts1_result);
60 | exit(0);
61 | }
62 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/float4.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check denorm double value.
3 | Limitations: none.
4 | PR: PR26483.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | /* { dg-options "-mieee" { target alpha*-*-* } } */
9 |
10 | #include "ffitest.h"
11 | #include "float.h"
12 |
13 | typedef union
14 | {
15 | double d;
16 | unsigned char c[sizeof (double)];
17 | } value_type;
18 |
19 | #define CANARY 0xba
20 |
21 | static double dblit(double d)
22 | {
23 | return d;
24 | }
25 |
26 | int main (void)
27 | {
28 | ffi_cif cif;
29 | ffi_type *args[MAX_ARGS];
30 | void *values[MAX_ARGS];
31 | double d;
32 | value_type result[2];
33 | unsigned int i;
34 |
35 | args[0] = &ffi_type_double;
36 | values[0] = &d;
37 |
38 | /* Initialize the cif */
39 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
40 | &ffi_type_double, args) == FFI_OK);
41 |
42 | d = DBL_MIN / 2;
43 |
44 | /* Put a canary in the return array. This is a regression test for
45 | a buffer overrun. */
46 | memset(result[1].c, CANARY, sizeof (double));
47 |
48 | ffi_call(&cif, FFI_FN(dblit), &result[0].d, values);
49 |
50 | /* The standard delta check doesn't work for denorms. Since we didn't do
51 | any arithmetic, we should get the original result back, and hence an
52 | exact check should be OK here. */
53 |
54 | CHECK(result[0].d == dblit(d));
55 |
56 | /* Check the canary. */
57 | for (i = 0; i < sizeof (double); ++i)
58 | CHECK(result[1].c[i] == CANARY);
59 |
60 | exit(0);
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/many.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value float, with many arguments
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | 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)
15 | {
16 | #if 0
17 | printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
18 | (double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
19 | (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
20 | (double) f11, (double) f12, (double) f13);
21 | #endif
22 |
23 | return f1+f2+f3+f4+f5+f6+f7+f8+f9+f10+f11+f12+f13;
24 | }
25 |
26 | int main (void)
27 | {
28 | ffi_cif cif;
29 | ffi_type *args[13];
30 | void *values[13];
31 | float fa[13];
32 | float f, ff;
33 | int i;
34 |
35 | for (i = 0; i < 13; i++)
36 | {
37 | args[i] = &ffi_type_float;
38 | values[i] = &fa[i];
39 | fa[i] = (float) i;
40 | }
41 |
42 | /* Initialize the cif */
43 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 13,
44 | &ffi_type_float, args) == FFI_OK);
45 |
46 | ffi_call(&cif, FFI_FN(many), &f, values);
47 |
48 | ff = many(fa[0], fa[1],
49 | fa[2], fa[3],
50 | fa[4], fa[5],
51 | fa[6], fa[7],
52 | fa[8], fa[9],
53 | fa[10],fa[11],fa[12]);
54 |
55 | if (fabs(f - ff) < FLT_EPSILON)
56 | exit(0);
57 | else
58 | abort();
59 | }
60 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/promotion.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Promotion test.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | static int promotion(signed char sc, signed short ss,
10 | unsigned char uc, unsigned short us)
11 | {
12 | int r = (int) sc + (int) ss + (int) uc + (int) us;
13 |
14 | return r;
15 | }
16 |
17 | int main (void)
18 | {
19 | ffi_cif cif;
20 | ffi_type *args[MAX_ARGS];
21 | void *values[MAX_ARGS];
22 | ffi_arg rint;
23 | signed char sc;
24 | unsigned char uc;
25 | signed short ss;
26 | unsigned short us;
27 | unsigned long ul;
28 |
29 | args[0] = &ffi_type_schar;
30 | args[1] = &ffi_type_sshort;
31 | args[2] = &ffi_type_uchar;
32 | args[3] = &ffi_type_ushort;
33 | values[0] = ≻
34 | values[1] = &ss;
35 | values[2] = &uc;
36 | values[3] = &us;
37 |
38 | /* Initialize the cif */
39 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
40 | &ffi_type_sint, args) == FFI_OK);
41 |
42 | us = 0;
43 | ul = 0;
44 |
45 | for (sc = (signed char) -127;
46 | sc <= (signed char) 120; sc += 1)
47 | for (ss = -30000; ss <= 30000; ss += 10000)
48 | for (uc = (unsigned char) 0;
49 | uc <= (unsigned char) 200; uc += 20)
50 | for (us = 0; us <= 60000; us += 10000)
51 | {
52 | ul++;
53 | ffi_call(&cif, FFI_FN(promotion), &rint, values);
54 | CHECK((int)rint == (signed char) sc + (signed short) ss +
55 | (unsigned char) uc + (unsigned short) us);
56 | }
57 | printf("%lu promotion tests run\n", ul);
58 | exit(0);
59 | }
60 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/struct4.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check structures.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | typedef struct
11 | {
12 | unsigned ui1;
13 | unsigned ui2;
14 | unsigned ui3;
15 | } test_structure_4;
16 |
17 | static test_structure_4 ABI_ATTR struct4(test_structure_4 ts)
18 | {
19 | ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
20 |
21 | return ts;
22 | }
23 |
24 | int main (void)
25 | {
26 | ffi_cif cif;
27 | ffi_type *args[MAX_ARGS];
28 | void *values[MAX_ARGS];
29 | ffi_type ts4_type;
30 | ffi_type *ts4_type_elements[4];
31 |
32 | test_structure_4 ts4_arg;
33 |
34 | /* This is a hack to get a properly aligned result buffer */
35 | test_structure_4 *ts4_result =
36 | (test_structure_4 *) malloc (sizeof(test_structure_4));
37 |
38 | ts4_type.size = 0;
39 | ts4_type.alignment = 0;
40 | ts4_type.type = FFI_TYPE_STRUCT;
41 | ts4_type.elements = ts4_type_elements;
42 | ts4_type_elements[0] = &ffi_type_uint;
43 | ts4_type_elements[1] = &ffi_type_uint;
44 | ts4_type_elements[2] = &ffi_type_uint;
45 | ts4_type_elements[3] = NULL;
46 |
47 | args[0] = &ts4_type;
48 | values[0] = &ts4_arg;
49 |
50 | /* Initialize the cif */
51 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts4_type, args) == FFI_OK);
52 |
53 | ts4_arg.ui1 = 2;
54 | ts4_arg.ui2 = 3;
55 | ts4_arg.ui3 = 4;
56 |
57 | ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
58 |
59 | CHECK(ts4_result->ui3 == 2U * 3U * 4U);
60 |
61 |
62 | free (ts4_result);
63 | exit(0);
64 | }
65 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/struct6.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check structures.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | typedef struct
10 | {
11 | float f;
12 | double d;
13 | } test_structure_6;
14 |
15 | static test_structure_6 ABI_ATTR struct6 (test_structure_6 ts)
16 | {
17 | ts.f += 1;
18 | ts.d += 1;
19 |
20 | return ts;
21 | }
22 |
23 | int main (void)
24 | {
25 | ffi_cif cif;
26 | ffi_type *args[MAX_ARGS];
27 | void *values[MAX_ARGS];
28 | ffi_type ts6_type;
29 | ffi_type *ts6_type_elements[3];
30 |
31 | test_structure_6 ts6_arg;
32 |
33 | /* This is a hack to get a properly aligned result buffer */
34 | test_structure_6 *ts6_result =
35 | (test_structure_6 *) malloc (sizeof(test_structure_6));
36 |
37 | ts6_type.size = 0;
38 | ts6_type.alignment = 0;
39 | ts6_type.type = FFI_TYPE_STRUCT;
40 | ts6_type.elements = ts6_type_elements;
41 | ts6_type_elements[0] = &ffi_type_float;
42 | ts6_type_elements[1] = &ffi_type_double;
43 | ts6_type_elements[2] = NULL;
44 |
45 | args[0] = &ts6_type;
46 | values[0] = &ts6_arg;
47 |
48 | /* Initialize the cif */
49 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts6_type, args) == FFI_OK);
50 |
51 | ts6_arg.f = 5.55f;
52 | ts6_arg.d = 6.66;
53 |
54 | printf ("%g\n", ts6_arg.f);
55 | printf ("%g\n", ts6_arg.d);
56 |
57 | ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
58 |
59 | CHECK(ts6_result->f == 5.55f + 1);
60 | CHECK(ts6_result->d == 6.66 + 1);
61 |
62 | free (ts6_result);
63 | exit(0);
64 | }
65 |
--------------------------------------------------------------------------------
/man/ffi_prep_cif_var.3:
--------------------------------------------------------------------------------
1 | .Dd January 25, 2011
2 | .Dt ffi_prep_cif_var 3
3 | .Sh NAME
4 | .Nm ffi_prep_cif_var
5 | .Nd Prepare a
6 | .Nm ffi_cif
7 | structure for use with
8 | .Nm ffi_call
9 | for variadic functions.
10 | .Sh SYNOPSIS
11 | .In ffi.h
12 | .Ft ffi_status
13 | .Fo ffi_prep_cif_var
14 | .Fa "ffi_cif *cif"
15 | .Fa "ffi_abi abi"
16 | .Fa "unsigned int nfixedargs"
17 | .Fa "unsigned int ntotalargs"
18 | .Fa "ffi_type *rtype"
19 | .Fa "ffi_type **atypes"
20 | .Fc
21 | .Sh DESCRIPTION
22 | The
23 | .Nm ffi_prep_cif_var
24 | function prepares a
25 | .Nm ffi_cif
26 | structure for use with
27 | .Nm ffi_call
28 | for variadic functions.
29 | .Fa abi
30 | specifies a set of calling conventions to use.
31 | .Fa atypes
32 | is an array of
33 | .Fa ntotalargs
34 | pointers to
35 | .Nm ffi_type
36 | structs that describe the data type, size and alignment of each argument.
37 | .Fa rtype
38 | points to an
39 | .Nm ffi_type
40 | that describes the data type, size and alignment of the
41 | return value.
42 | .Fa nfixedargs
43 | must contain the number of fixed (non-variadic) arguments.
44 | Note that to call a non-variadic function
45 | .Nm ffi_prep_cif
46 | must be used.
47 | .Sh RETURN VALUES
48 | Upon successful completion,
49 | .Nm ffi_prep_cif_var
50 | returns
51 | .Nm FFI_OK .
52 | It will return
53 | .Nm FFI_BAD_TYPEDEF
54 | if
55 | .Fa cif
56 | is
57 | .Nm NULL
58 | or
59 | .Fa atypes
60 | or
61 | .Fa rtype
62 | is malformed. If
63 | .Fa abi
64 | does not refer to a valid ABI,
65 | .Nm FFI_BAD_ABI
66 | will be returned. Available ABIs are
67 | defined in
68 | .Nm
69 | .
70 | .Sh SEE ALSO
71 | .Xr ffi 3 ,
72 | .Xr ffi_call 3 ,
73 | .Xr ffi_prep_cif 3
74 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_dbls_struct.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check double arguments in structs.
3 | Limitations: none.
4 | PR: none.
5 | Originator: Blake Chaffin 6/23/2007 */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 |
11 | typedef struct Dbls {
12 | double x;
13 | double y;
14 | } Dbls;
15 |
16 | void
17 | closure_test_fn(Dbls p)
18 | {
19 | printf("%.1f %.1f\n", p.x, p.y);
20 | }
21 |
22 | void
23 | closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
24 | void** args, void* userdata __UNUSED__)
25 | {
26 | closure_test_fn(*(Dbls*)args[0]);
27 | }
28 |
29 | int main(int argc __UNUSED__, char** argv __UNUSED__)
30 | {
31 | ffi_cif cif;
32 |
33 | void *code;
34 | ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
35 | ffi_type* cl_arg_types[1];
36 |
37 | ffi_type ts1_type;
38 | ffi_type* ts1_type_elements[4];
39 |
40 | Dbls arg = { 1.0, 2.0 };
41 |
42 | ts1_type.size = 0;
43 | ts1_type.alignment = 0;
44 | ts1_type.type = FFI_TYPE_STRUCT;
45 | ts1_type.elements = ts1_type_elements;
46 |
47 | ts1_type_elements[0] = &ffi_type_double;
48 | ts1_type_elements[1] = &ffi_type_double;
49 | ts1_type_elements[2] = NULL;
50 |
51 | cl_arg_types[0] = &ts1_type;
52 |
53 | /* Initialize the cif */
54 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
55 | &ffi_type_void, cl_arg_types) == FFI_OK);
56 |
57 | CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
58 |
59 | ((void*(*)(Dbls))(code))(arg);
60 | /* { dg-output "1.0 2.0" } */
61 |
62 | closure_test_fn(arg);
63 | /* { dg-output "\n1.0 2.0" } */
64 |
65 | return 0;
66 | }
67 |
--------------------------------------------------------------------------------
/msvc_build/aarch64/Ffi_staticLib.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28302.56
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ffi_staticLib_arm64", "Ffi_staticLib.vcxproj", "{115502C0-BE05-4767-BF19-5C87D805FAD6}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|ARM64 = Debug|ARM64
11 | Debug|x64 = Debug|x64
12 | Debug|x86 = Debug|x86
13 | Release|ARM64 = Release|ARM64
14 | Release|x64 = Release|x64
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|ARM64.ActiveCfg = Debug|ARM64
19 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|ARM64.Build.0 = Debug|ARM64
20 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|x64.ActiveCfg = Debug|ARM64
21 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|x86.ActiveCfg = Debug|ARM64
22 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|ARM64.ActiveCfg = Release|ARM64
23 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|ARM64.Build.0 = Release|ARM64
24 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|x64.ActiveCfg = Release|ARM64
25 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|x86.ActiveCfg = Release|ARM64
26 | EndGlobalSection
27 | GlobalSection(SolutionProperties) = preSolution
28 | HideSolutionNode = FALSE
29 | EndGlobalSection
30 | GlobalSection(ExtensibilityGlobals) = postSolution
31 | SolutionGuid = {241C54C7-20DD-4897-9376-E6B6D1B43BD5}
32 | EndGlobalSection
33 | EndGlobal
34 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/closure_simple.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check simple closure handling with all ABIs
3 | Limitations: none.
4 | PR: none.
5 | Originator: */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | static void
11 | closure_test(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata)
12 | {
13 | *(ffi_arg*)resp =
14 | (int)*(int *)args[0] + (int)(*(int *)args[1])
15 | + (int)(*(int *)args[2]) + (int)(*(int *)args[3])
16 | + (int)(intptr_t)userdata;
17 |
18 | printf("%d %d %d %d: %d\n",
19 | (int)*(int *)args[0], (int)(*(int *)args[1]),
20 | (int)(*(int *)args[2]), (int)(*(int *)args[3]),
21 | (int)*(ffi_arg *)resp);
22 |
23 | }
24 |
25 | typedef int (ABI_ATTR *closure_test_type0)(int, int, int, int);
26 |
27 | int main (void)
28 | {
29 | ffi_cif cif;
30 | void *code;
31 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
32 | ffi_type * cl_arg_types[17];
33 | int res;
34 |
35 | cl_arg_types[0] = &ffi_type_uint;
36 | cl_arg_types[1] = &ffi_type_uint;
37 | cl_arg_types[2] = &ffi_type_uint;
38 | cl_arg_types[3] = &ffi_type_uint;
39 | cl_arg_types[4] = NULL;
40 |
41 | /* Initialize the cif */
42 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 4,
43 | &ffi_type_sint, cl_arg_types) == FFI_OK);
44 |
45 | CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test,
46 | (void *) 3 /* userdata */, code) == FFI_OK);
47 |
48 | res = (*(closure_test_type0)code)(0, 1, 2, 3);
49 | /* { dg-output "0 1 2 3: 9" } */
50 |
51 | printf("res: %d\n",res);
52 | /* { dg-output "\nres: 9" } */
53 |
54 | exit(0);
55 | }
56 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/struct1.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check structures.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | typedef struct
11 | {
12 | unsigned char uc;
13 | double d;
14 | unsigned int ui;
15 | } test_structure_1;
16 |
17 | static test_structure_1 ABI_ATTR struct1(test_structure_1 ts)
18 | {
19 | ts.uc++;
20 | ts.d--;
21 | ts.ui++;
22 |
23 | return ts;
24 | }
25 |
26 | int main (void)
27 | {
28 | ffi_cif cif;
29 | ffi_type *args[MAX_ARGS];
30 | void *values[MAX_ARGS];
31 | ffi_type ts1_type;
32 | ffi_type *ts1_type_elements[4];
33 |
34 | test_structure_1 ts1_arg;
35 |
36 | /* This is a hack to get a properly aligned result buffer */
37 | test_structure_1 *ts1_result =
38 | (test_structure_1 *) malloc (sizeof(test_structure_1));
39 |
40 | ts1_type.size = 0;
41 | ts1_type.alignment = 0;
42 | ts1_type.type = FFI_TYPE_STRUCT;
43 | ts1_type.elements = ts1_type_elements;
44 | ts1_type_elements[0] = &ffi_type_uchar;
45 | ts1_type_elements[1] = &ffi_type_double;
46 | ts1_type_elements[2] = &ffi_type_uint;
47 | ts1_type_elements[3] = NULL;
48 |
49 | args[0] = &ts1_type;
50 | values[0] = &ts1_arg;
51 |
52 | /* Initialize the cif */
53 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1,
54 | &ts1_type, args) == FFI_OK);
55 |
56 | ts1_arg.uc = '\x01';
57 | ts1_arg.d = 3.14159;
58 | ts1_arg.ui = 555;
59 |
60 | ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
61 |
62 | CHECK(ts1_result->ui == 556);
63 | CHECK(ts1_result->d == 3.14159 - 1);
64 |
65 | free (ts1_result);
66 | exit(0);
67 | }
68 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/struct5.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check structures.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | typedef struct
10 | {
11 | char c1;
12 | char c2;
13 | } test_structure_5;
14 |
15 | static test_structure_5 ABI_ATTR struct5(test_structure_5 ts1, test_structure_5 ts2)
16 | {
17 | ts1.c1 += ts2.c1;
18 | ts1.c2 -= ts2.c2;
19 |
20 | return ts1;
21 | }
22 |
23 | int main (void)
24 | {
25 | ffi_cif cif;
26 | ffi_type *args[MAX_ARGS];
27 | void *values[MAX_ARGS];
28 | ffi_type ts5_type;
29 | ffi_type *ts5_type_elements[3];
30 |
31 | test_structure_5 ts5_arg1, ts5_arg2;
32 |
33 | /* This is a hack to get a properly aligned result buffer */
34 | test_structure_5 *ts5_result =
35 | (test_structure_5 *) malloc (sizeof(test_structure_5));
36 |
37 | ts5_type.size = 0;
38 | ts5_type.alignment = 0;
39 | ts5_type.type = FFI_TYPE_STRUCT;
40 | ts5_type.elements = ts5_type_elements;
41 | ts5_type_elements[0] = &ffi_type_schar;
42 | ts5_type_elements[1] = &ffi_type_schar;
43 | ts5_type_elements[2] = NULL;
44 |
45 | args[0] = &ts5_type;
46 | args[1] = &ts5_type;
47 | values[0] = &ts5_arg1;
48 | values[1] = &ts5_arg2;
49 |
50 | /* Initialize the cif */
51 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts5_type, args) == FFI_OK);
52 |
53 | ts5_arg1.c1 = 2;
54 | ts5_arg1.c2 = 6;
55 | ts5_arg2.c1 = 5;
56 | ts5_arg2.c2 = 3;
57 |
58 | ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
59 |
60 | CHECK(ts5_result->c1 == 7);
61 | CHECK(ts5_result->c2 == 3);
62 |
63 |
64 | free (ts5_result);
65 | exit(0);
66 | }
67 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/struct9.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check structures.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | typedef struct
11 | {
12 | float f;
13 | int i;
14 | } test_structure_9;
15 |
16 | static test_structure_9 ABI_ATTR struct9 (test_structure_9 ts)
17 | {
18 | ts.f += 1;
19 | ts.i += 1;
20 |
21 | return ts;
22 | }
23 |
24 | int main (void)
25 | {
26 | ffi_cif cif;
27 | ffi_type *args[MAX_ARGS];
28 | void *values[MAX_ARGS];
29 | ffi_type ts9_type;
30 | ffi_type *ts9_type_elements[3];
31 |
32 | test_structure_9 ts9_arg;
33 |
34 | /* This is a hack to get a properly aligned result buffer */
35 | test_structure_9 *ts9_result =
36 | (test_structure_9 *) malloc (sizeof(test_structure_9));
37 |
38 | ts9_type.size = 0;
39 | ts9_type.alignment = 0;
40 | ts9_type.type = FFI_TYPE_STRUCT;
41 | ts9_type.elements = ts9_type_elements;
42 | ts9_type_elements[0] = &ffi_type_float;
43 | ts9_type_elements[1] = &ffi_type_sint;
44 | ts9_type_elements[2] = NULL;
45 |
46 | args[0] = &ts9_type;
47 | values[0] = &ts9_arg;
48 |
49 | /* Initialize the cif */
50 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts9_type, args) == FFI_OK);
51 |
52 | ts9_arg.f = 5.55f;
53 | ts9_arg.i = 5;
54 |
55 | printf ("%g\n", ts9_arg.f);
56 | printf ("%d\n", ts9_arg.i);
57 |
58 | ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
59 |
60 | printf ("%g\n", ts9_result->f);
61 | printf ("%d\n", ts9_result->i);
62 |
63 | CHECK(ts9_result->f == 5.55f + 1);
64 | CHECK(ts9_result->i == 5 + 1);
65 |
66 | free (ts9_result);
67 | exit(0);
68 | }
69 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/struct2.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check structures.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | typedef struct
11 | {
12 | double d1;
13 | double d2;
14 | } test_structure_2;
15 |
16 | static test_structure_2 ABI_ATTR struct2(test_structure_2 ts)
17 | {
18 | ts.d1--;
19 | ts.d2--;
20 |
21 | return ts;
22 | }
23 |
24 | int main (void)
25 | {
26 | ffi_cif cif;
27 | ffi_type *args[MAX_ARGS];
28 | void *values[MAX_ARGS];
29 | test_structure_2 ts2_arg;
30 | ffi_type ts2_type;
31 | ffi_type *ts2_type_elements[3];
32 |
33 | /* This is a hack to get a properly aligned result buffer */
34 | test_structure_2 *ts2_result =
35 | (test_structure_2 *) malloc (sizeof(test_structure_2));
36 |
37 | ts2_type.size = 0;
38 | ts2_type.alignment = 0;
39 | ts2_type.type = FFI_TYPE_STRUCT;
40 | ts2_type.elements = ts2_type_elements;
41 | ts2_type_elements[0] = &ffi_type_double;
42 | ts2_type_elements[1] = &ffi_type_double;
43 | ts2_type_elements[2] = NULL;
44 |
45 | args[0] = &ts2_type;
46 | values[0] = &ts2_arg;
47 |
48 | /* Initialize the cif */
49 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts2_type, args) == FFI_OK);
50 |
51 | ts2_arg.d1 = 5.55;
52 | ts2_arg.d2 = 6.66;
53 |
54 | printf ("%g\n", ts2_arg.d1);
55 | printf ("%g\n", ts2_arg.d2);
56 |
57 | ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
58 |
59 | printf ("%g\n", ts2_result->d1);
60 | printf ("%g\n", ts2_result->d2);
61 |
62 | CHECK(ts2_result->d1 == 5.55 - 1);
63 | CHECK(ts2_result->d2 == 6.66 - 1);
64 |
65 | free (ts2_result);
66 | exit(0);
67 | }
68 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_ulonglong.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value long long.
3 | Limitations: none.
4 | PR: none.
5 | Originator: 20030828 */
6 |
7 | /* { dg-do run } */
8 | /* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
9 | #include "ffitest.h"
10 |
11 | static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp,
12 | void** args, void* userdata __UNUSED__)
13 | {
14 | *(unsigned long long *)resp= 0xfffffffffffffffLL ^ *(unsigned long long *)args[0];
15 |
16 | printf("%" PRIuLL ": %" PRIuLL "\n",*(unsigned long long *)args[0],
17 | *(unsigned long long *)(resp));
18 | }
19 | typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long);
20 |
21 | int main (void)
22 | {
23 | ffi_cif cif;
24 | void *code;
25 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
26 | ffi_type * cl_arg_types[2];
27 | unsigned long long res;
28 |
29 | cl_arg_types[0] = &ffi_type_uint64;
30 | cl_arg_types[1] = NULL;
31 |
32 | /* Initialize the cif */
33 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
34 | &ffi_type_uint64, cl_arg_types) == FFI_OK);
35 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ulonglong_fn, NULL, code) == FFI_OK);
36 | res = (*((cls_ret_ulonglong)code))(214LL);
37 | /* { dg-output "214: 1152921504606846761" } */
38 | printf("res: %" PRIdLL "\n", res);
39 | /* { dg-output "\nres: 1152921504606846761" } */
40 |
41 | res = (*((cls_ret_ulonglong)code))(9223372035854775808LL);
42 | /* { dg-output "\n9223372035854775808: 8070450533247928831" } */
43 | printf("res: %" PRIdLL "\n", res);
44 | /* { dg-output "\nres: 8070450533247928831" } */
45 |
46 | exit(0);
47 | }
48 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/float2.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value long double.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 | /* { dg-do run } */
7 |
8 | #include "ffitest.h"
9 | #include "float.h"
10 |
11 | #include
12 |
13 | static long double ldblit(float f)
14 | {
15 | return (long double) (((long double) f)/ (long double) 3.0);
16 | }
17 |
18 | int main (void)
19 | {
20 | ffi_cif cif;
21 | ffi_type *args[MAX_ARGS];
22 | void *values[MAX_ARGS];
23 | float f;
24 | long double ld;
25 | long double original;
26 |
27 | args[0] = &ffi_type_float;
28 | values[0] = &f;
29 |
30 | /* Initialize the cif */
31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
32 | &ffi_type_longdouble, args) == FFI_OK);
33 |
34 | f = 3.14159;
35 |
36 | #if defined(__sun) && defined(__GNUC__)
37 | /* long double support under SunOS/gcc is pretty much non-existent.
38 | You'll get the odd bus error in library routines like printf() */
39 | #else
40 | printf ("%Lf\n", ldblit(f));
41 | #endif
42 |
43 | ld = 666;
44 | ffi_call(&cif, FFI_FN(ldblit), &ld, values);
45 |
46 | #if defined(__sun) && defined(__GNUC__)
47 | /* long double support under SunOS/gcc is pretty much non-existent.
48 | You'll get the odd bus error in library routines like printf() */
49 | #else
50 | printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
51 | #endif
52 |
53 | /* These are not always the same!! Check for a reasonable delta */
54 | original = ldblit(f);
55 | if (((ld > original) ? (ld - original) : (original - ld)) < LDBL_EPSILON)
56 | puts("long double return value tests ok!");
57 | else
58 | CHECK(0);
59 |
60 | exit(0);
61 | }
62 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/many_double.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value double, with many arguments
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | static double many(double f1,
15 | double f2,
16 | double f3,
17 | double f4,
18 | double f5,
19 | double f6,
20 | double f7,
21 | double f8,
22 | double f9,
23 | double f10,
24 | double f11,
25 | double f12,
26 | double f13)
27 | {
28 | #if 0
29 | printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
30 | (double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
31 | (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
32 | (double) f11, (double) f12, (double) f13);
33 | #endif
34 |
35 | return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
36 | }
37 |
38 | int main (void)
39 | {
40 | ffi_cif cif;
41 | ffi_type *args[13];
42 | void *values[13];
43 | double fa[13];
44 | double f, ff;
45 | int i;
46 |
47 | for (i = 0; i < 13; i++)
48 | {
49 | args[i] = &ffi_type_double;
50 | values[i] = &fa[i];
51 | fa[i] = (double) i;
52 | }
53 |
54 | /* Initialize the cif */
55 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
56 | &ffi_type_double, args) == FFI_OK);
57 |
58 | ffi_call(&cif, FFI_FN(many), &f, values);
59 |
60 | ff = many(fa[0], fa[1],
61 | fa[2], fa[3],
62 | fa[4], fa[5],
63 | fa[6], fa[7],
64 | fa[8], fa[9],
65 | fa[10],fa[11],fa[12]);
66 | if (fabs(f - ff) < FLT_EPSILON)
67 | exit(0);
68 | else
69 | abort();
70 | }
71 |
--------------------------------------------------------------------------------
/m4/ax_append_flag.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
8 | #
9 | # DESCRIPTION
10 | #
11 | # FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
12 | # added in between.
13 | #
14 | # If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
15 | # CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
16 | # FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
17 | # FLAG.
18 | #
19 | # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
20 | #
21 | # LICENSE
22 | #
23 | # Copyright (c) 2008 Guido U. Draheim
24 | # Copyright (c) 2011 Maarten Bosmans
25 | #
26 | # Copying and distribution of this file, with or without modification, are
27 | # permitted in any medium without royalty provided the copyright notice
28 | # and this notice are preserved. This file is offered as-is, without any
29 | # warranty.
30 |
31 | #serial 8
32 |
33 | AC_DEFUN([AX_APPEND_FLAG],
34 | [dnl
35 | AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
36 | AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
37 | AS_VAR_SET_IF(FLAGS,[
38 | AS_CASE([" AS_VAR_GET(FLAGS) "],
39 | [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
40 | [
41 | AS_VAR_APPEND(FLAGS,[" $1"])
42 | AC_RUN_LOG([: FLAGS="$FLAGS"])
43 | ])
44 | ],
45 | [
46 | AS_VAR_SET(FLAGS,[$1])
47 | AC_RUN_LOG([: FLAGS="$FLAGS"])
48 | ])
49 | AS_VAR_POPDEF([FLAGS])dnl
50 | ])dnl AX_APPEND_FLAG
51 |
--------------------------------------------------------------------------------
/libffi.map.in:
--------------------------------------------------------------------------------
1 | #define LIBFFI_ASM
2 | #define LIBFFI_H
3 | #include
4 | #include
5 |
6 | /* These version numbers correspond to the libtool-version abi numbers,
7 | not to the libffi release numbers. */
8 |
9 | LIBFFI_BASE_7.0 {
10 | global:
11 | /* Exported data variables. */
12 | ffi_type_void;
13 | ffi_type_uint8;
14 | ffi_type_sint8;
15 | ffi_type_uint16;
16 | ffi_type_sint16;
17 | ffi_type_uint32;
18 | ffi_type_sint32;
19 | ffi_type_uint64;
20 | ffi_type_sint64;
21 | ffi_type_float;
22 | ffi_type_double;
23 | ffi_type_longdouble;
24 | ffi_type_pointer;
25 |
26 | /* Exported functions. */
27 | ffi_call;
28 | ffi_prep_cif;
29 | ffi_prep_cif_var;
30 |
31 | ffi_raw_call;
32 | ffi_ptrarray_to_raw;
33 | ffi_raw_to_ptrarray;
34 | ffi_raw_size;
35 |
36 | ffi_java_raw_call;
37 | ffi_java_ptrarray_to_raw;
38 | ffi_java_raw_to_ptrarray;
39 | ffi_java_raw_size;
40 |
41 | local:
42 | *;
43 | };
44 |
45 | LIBFFI_BASE_7.1 {
46 | global:
47 | ffi_get_struct_offsets;
48 | } LIBFFI_BASE_7.0;
49 |
50 | #ifdef FFI_TARGET_HAS_COMPLEX_TYPE
51 | LIBFFI_COMPLEX_7.0 {
52 | global:
53 | /* Exported data variables. */
54 | ffi_type_complex_float;
55 | ffi_type_complex_double;
56 | ffi_type_complex_longdouble;
57 | } LIBFFI_BASE_7.0;
58 | #endif
59 |
60 | #if FFI_CLOSURES
61 | LIBFFI_CLOSURE_7.0 {
62 | global:
63 | ffi_closure_alloc;
64 | ffi_closure_free;
65 | ffi_prep_closure;
66 | ffi_prep_closure_loc;
67 | ffi_prep_raw_closure;
68 | ffi_prep_raw_closure_loc;
69 | ffi_prep_java_raw_closure;
70 | ffi_prep_java_raw_closure_loc;
71 | } LIBFFI_BASE_7.0;
72 | #endif
73 |
74 | #if FFI_GO_CLOSURES
75 | LIBFFI_GO_CLOSURE_7.0 {
76 | global:
77 | ffi_call_go;
78 | ffi_prep_go_closure;
79 | } LIBFFI_CLOSURE_7.0;
80 | #endif
81 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_double_va.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Test doubles passed in variable argument lists.
3 | Limitations: none.
4 | PR: none.
5 | Originator: Blake Chaffin 6/6/2007 */
6 |
7 | /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
8 | /* { dg-output "" { xfail avr32*-*-* } } */
9 | /* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
10 |
11 | #include "ffitest.h"
12 |
13 | static void
14 | cls_double_va_fn(ffi_cif* cif __UNUSED__, void* resp,
15 | void** args, void* userdata __UNUSED__)
16 | {
17 | char* format = *(char**)args[0];
18 | double doubleValue = *(double*)args[1];
19 |
20 | *(ffi_arg*)resp = printf(format, doubleValue);
21 | }
22 |
23 | int main (void)
24 | {
25 | ffi_cif cif;
26 | void *code;
27 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
28 | void* args[3];
29 | ffi_type* arg_types[3];
30 |
31 | char* format = "%.1f\n";
32 | double doubleArg = 7;
33 | ffi_arg res = 0;
34 |
35 | arg_types[0] = &ffi_type_pointer;
36 | arg_types[1] = &ffi_type_double;
37 | arg_types[2] = NULL;
38 |
39 | /* This printf call is variadic */
40 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
41 | arg_types) == FFI_OK);
42 |
43 | args[0] = &format;
44 | args[1] = &doubleArg;
45 | args[2] = NULL;
46 |
47 | ffi_call(&cif, FFI_FN(printf), &res, args);
48 | /* { dg-output "7.0" } */
49 | printf("res: %d\n", (int) res);
50 | /* { dg-output "\nres: 4" } */
51 |
52 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL,
53 | code) == FFI_OK);
54 |
55 | res = ((int(*)(char*, ...))(code))(format, doubleArg);
56 | /* { dg-output "\n7.0" } */
57 | printf("res: %d\n", (int) res);
58 | /* { dg-output "\nres: 4" } */
59 |
60 | exit(0);
61 | }
62 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/float3.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check float arguments with different orders.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 |
9 | #include "ffitest.h"
10 | #include "float.h"
11 |
12 | #include
13 |
14 | static double floating_1(float a, double b, long double c)
15 | {
16 | return (double) a + b + (double) c;
17 | }
18 |
19 | static double floating_2(long double a, double b, float c)
20 | {
21 | return (double) a + b + (double) c;
22 | }
23 |
24 | int main (void)
25 | {
26 | ffi_cif cif;
27 | ffi_type *args[MAX_ARGS];
28 | void *values[MAX_ARGS];
29 | double rd;
30 |
31 | float f;
32 | double d;
33 | long double ld;
34 |
35 | args[0] = &ffi_type_float;
36 | values[0] = &f;
37 | args[1] = &ffi_type_double;
38 | values[1] = &d;
39 | args[2] = &ffi_type_longdouble;
40 | values[2] = &ld;
41 |
42 | /* Initialize the cif */
43 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
44 | &ffi_type_double, args) == FFI_OK);
45 |
46 | f = 3.14159;
47 | d = (double)1.0/(double)3.0;
48 | ld = 2.71828182846L;
49 |
50 | floating_1 (f, d, ld);
51 |
52 | ffi_call(&cif, FFI_FN(floating_1), &rd, values);
53 |
54 | CHECK(fabs(rd - floating_1(f, d, ld)) < DBL_EPSILON);
55 |
56 | args[0] = &ffi_type_longdouble;
57 | values[0] = &ld;
58 | args[1] = &ffi_type_double;
59 | values[1] = &d;
60 | args[2] = &ffi_type_float;
61 | values[2] = &f;
62 |
63 | /* Initialize the cif */
64 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
65 | &ffi_type_double, args) == FFI_OK);
66 |
67 | floating_2 (ld, d, f);
68 |
69 | ffi_call(&cif, FFI_FN(floating_2), &rd, values);
70 |
71 | CHECK(fabs(rd - floating_2(ld, d, f)) < DBL_EPSILON);
72 |
73 | exit (0);
74 | }
75 |
--------------------------------------------------------------------------------
/src/bfin/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 | ffitarget.h - Copyright (c) 2012 Alexandre K. I. de Mendonca
3 |
4 | Blackfin Foreign Function Interface
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | ``Software''), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 | ----------------------------------------------------------------------- */
26 |
27 | #ifndef LIBFFI_TARGET_H
28 | #define LIBFFI_TARGET_H
29 |
30 | #ifndef LIBFFI_ASM
31 | typedef unsigned long ffi_arg;
32 | typedef signed long ffi_sarg;
33 |
34 | typedef enum ffi_abi {
35 | FFI_FIRST_ABI = 0,
36 | FFI_SYSV,
37 | FFI_LAST_ABI,
38 | FFI_DEFAULT_ABI = FFI_SYSV
39 | } ffi_abi;
40 | #endif
41 |
42 | #endif
43 |
44 |
--------------------------------------------------------------------------------
/src/m88k/ffitarget.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 Miodrag Vallat.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * ``Software''), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included
13 | * in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | /*
25 | * m88k Foreign Function Interface
26 | */
27 |
28 | #ifndef LIBFFI_TARGET_H
29 | #define LIBFFI_TARGET_H
30 |
31 | #ifndef LIBFFI_ASM
32 | typedef unsigned long ffi_arg;
33 | typedef signed long ffi_sarg;
34 |
35 | typedef enum ffi_abi {
36 | FFI_FIRST_ABI = 0,
37 | FFI_OBSD,
38 | FFI_DEFAULT_ABI = FFI_OBSD,
39 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
40 | } ffi_abi;
41 | #endif
42 |
43 | /* ---- Definitions for closures ----------------------------------------- */
44 |
45 | #define FFI_CLOSURES 1
46 | #define FFI_TRAMPOLINE_SIZE 0x14
47 | #define FFI_NATIVE_RAW_API 0
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/src/vax/ffitarget.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 Miodrag Vallat.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * ``Software''), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included
13 | * in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | /*
25 | * vax Foreign Function Interface
26 | */
27 |
28 | #ifndef LIBFFI_TARGET_H
29 | #define LIBFFI_TARGET_H
30 |
31 | #ifndef LIBFFI_ASM
32 | typedef unsigned long ffi_arg;
33 | typedef signed long ffi_sarg;
34 |
35 | typedef enum ffi_abi {
36 | FFI_FIRST_ABI = 0,
37 | FFI_ELFBSD,
38 | FFI_DEFAULT_ABI = FFI_ELFBSD,
39 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
40 | } ffi_abi;
41 | #endif
42 |
43 | /* ---- Definitions for closures ----------------------------------------- */
44 |
45 | #define FFI_CLOSURES 1
46 | #define FFI_TRAMPOLINE_SIZE 15
47 | #define FFI_NATIVE_RAW_API 0
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_longdouble_va.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Test long doubles passed in variable argument lists.
3 | Limitations: none.
4 | PR: none.
5 | Originator: Blake Chaffin 6/6/2007 */
6 |
7 | /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
8 | /* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */
9 | /* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
10 |
11 | #include "ffitest.h"
12 |
13 | static void
14 | cls_longdouble_va_fn(ffi_cif* cif __UNUSED__, void* resp,
15 | void** args, void* userdata __UNUSED__)
16 | {
17 | char* format = *(char**)args[0];
18 | long double ldValue = *(long double*)args[1];
19 |
20 | *(ffi_arg*)resp = printf(format, ldValue);
21 | }
22 |
23 | int main (void)
24 | {
25 | ffi_cif cif;
26 | void *code;
27 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
28 | void* args[3];
29 | ffi_type* arg_types[3];
30 |
31 | char* format = "%.1Lf\n";
32 | long double ldArg = 7;
33 | ffi_arg res = 0;
34 |
35 | arg_types[0] = &ffi_type_pointer;
36 | arg_types[1] = &ffi_type_longdouble;
37 | arg_types[2] = NULL;
38 |
39 | /* This printf call is variadic */
40 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
41 | arg_types) == FFI_OK);
42 |
43 | args[0] = &format;
44 | args[1] = &ldArg;
45 | args[2] = NULL;
46 |
47 | ffi_call(&cif, FFI_FN(printf), &res, args);
48 | /* { dg-output "7.0" } */
49 | printf("res: %d\n", (int) res);
50 | /* { dg-output "\nres: 4" } */
51 |
52 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL,
53 | code) == FFI_OK);
54 |
55 | res = ((int(*)(char*, ...))(code))(format, ldArg);
56 | /* { dg-output "\n7.0" } */
57 | printf("res: %d\n", (int) res);
58 | /* { dg-output "\nres: 4" } */
59 |
60 | exit(0);
61 | }
62 |
--------------------------------------------------------------------------------
/m4/ax_configure_args.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # https://www.gnu.org/software/autoconf-archive/ax_configure_args.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CONFIGURE_ARGS
8 | #
9 | # DESCRIPTION
10 | #
11 | # Helper macro for AX_ENABLE_BUILDDIR.
12 | #
13 | # The traditional way of starting a subdir-configure is running the script
14 | # with ${1+"$@"} but since autoconf 2.60 this is broken. Instead we have
15 | # to rely on eval'ing $ac_configure_args however some old autoconf
16 | # versions do not provide that. To ensure maximum portability of autoconf
17 | # extension macros this helper can be AC_REQUIRE'd so that
18 | # $ac_configure_args will always be present.
19 | #
20 | # Sadly, the traditional "exec $SHELL" of the enable_builddir macros is
21 | # spoiled now and must be replaced by "eval + exit $?".
22 | #
23 | # Example:
24 | #
25 | # AC_DEFUN([AX_ENABLE_SUBDIR],[dnl
26 | # AC_REQUIRE([AX_CONFIGURE_ARGS])dnl
27 | # eval $SHELL $ac_configure_args || exit $?
28 | # ...])
29 | #
30 | # LICENSE
31 | #
32 | # Copyright (c) 2008 Guido U. Draheim
33 | #
34 | # Copying and distribution of this file, with or without modification, are
35 | # permitted in any medium without royalty provided the copyright notice
36 | # and this notice are preserved. This file is offered as-is, without any
37 | # warranty.
38 |
39 | #serial 14
40 |
41 | AC_DEFUN([AX_CONFIGURE_ARGS],[
42 | # [$]@ is unusable in 2.60+ but earlier autoconf had no ac_configure_args
43 | if test "${ac_configure_args+set}" != "set" ; then
44 | ac_configure_args=
45 | for ac_arg in ${1+"[$]@"}; do
46 | ac_configure_args="$ac_configure_args '$ac_arg'"
47 | done
48 | fi
49 | ])
50 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/cls_complex_struct.inc:
--------------------------------------------------------------------------------
1 | /* -*-c-*- */
2 | #include "ffitest.h"
3 | #include
4 |
5 | typedef struct Cs {
6 | _Complex T_C_TYPE x;
7 | _Complex T_C_TYPE y;
8 | } Cs;
9 |
10 | Cs gc;
11 |
12 | void
13 | closure_test_fn(Cs p)
14 | {
15 | printf("%.1f,%.1fi %.1f,%.1fi\n",
16 | T_CONV creal (p.x), T_CONV cimag (p.x),
17 | T_CONV creal (p.y), T_CONV cimag (p.y));
18 | gc = p;
19 | }
20 |
21 | void
22 | closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
23 | void** args, void* userdata __UNUSED__)
24 | {
25 | closure_test_fn(*(Cs*)args[0]);
26 | }
27 |
28 | int main(int argc __UNUSED__, char** argv __UNUSED__)
29 | {
30 | ffi_cif cif;
31 |
32 | void *code;
33 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
34 | ffi_type *cl_arg_types[1];
35 |
36 | ffi_type ts1_type;
37 | ffi_type* ts1_type_elements[4];
38 |
39 | Cs arg = { 1.0 + 11.0 * I, 2.0 + 22.0 * I};
40 |
41 | ts1_type.size = 0;
42 | ts1_type.alignment = 0;
43 | ts1_type.type = FFI_TYPE_STRUCT;
44 | ts1_type.elements = ts1_type_elements;
45 |
46 | ts1_type_elements[0] = &T_FFI_TYPE;
47 | ts1_type_elements[1] = &T_FFI_TYPE;
48 | ts1_type_elements[2] = NULL;
49 |
50 | cl_arg_types[0] = &ts1_type;
51 |
52 | /* Initialize the cif */
53 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
54 | &ffi_type_void, cl_arg_types) == FFI_OK);
55 |
56 | CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
57 |
58 | gc.x = 0.0 + 0.0 * I;
59 | gc.y = 0.0 + 0.0 * I;
60 | ((void*(*)(Cs))(code))(arg);
61 | /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */
62 | CHECK (gc.x == arg.x && gc.y == arg.y);
63 |
64 | gc.x = 0.0 + 0.0 * I;
65 | gc.y = 0.0 + 0.0 * I;
66 | closure_test_fn(arg);
67 | /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */
68 | CHECK (gc.x == arg.x && gc.y == arg.y);
69 |
70 | return 0;
71 | }
72 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/many_mixed.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check return value double, with many arguments
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | static double many(double f1,
15 | double f2,
16 | long int i1,
17 | double f3,
18 | double f4,
19 | long int i2,
20 | double f5,
21 | double f6,
22 | long int i3,
23 | double f7,
24 | double f8,
25 | long int i4,
26 | double f9,
27 | double f10,
28 | long int i5,
29 | double f11,
30 | double f12,
31 | long int i6,
32 | double f13)
33 | {
34 | return ((double) (i1 + i2 + i3 + i4 + i5 + i6) + (f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
35 | }
36 |
37 | int main (void)
38 | {
39 | ffi_cif cif;
40 | ffi_type *args[19];
41 | void *values[19];
42 | double fa[19];
43 | long int la[19];
44 | double f, ff;
45 | int i;
46 |
47 | for (i = 0; i < 19; i++)
48 | {
49 | if( (i - 2) % 3 == 0) {
50 | args[i] = &ffi_type_slong;
51 | la[i] = (long int) i;
52 | values[i] = &la[i];
53 | }
54 | else {
55 | args[i] = &ffi_type_double;
56 | fa[i] = (double) i;
57 | values[i] = &fa[i];
58 | }
59 | }
60 |
61 | /* Initialize the cif */
62 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 19,
63 | &ffi_type_double, args) == FFI_OK);
64 |
65 | ffi_call(&cif, FFI_FN(many), &f, values);
66 |
67 | ff = many(fa[0], fa[1], la[2],
68 | fa[3], fa[4], la[5],
69 | fa[6], fa[7], la[8],
70 | fa[9], fa[10], la[11],
71 | fa[12], fa[13], la[14],
72 | fa[15], fa[16], la[17],
73 | fa[18]);
74 | if (fabs(f - ff) < FLT_EPSILON)
75 | exit(0);
76 | else
77 | abort();
78 | }
79 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/call.exp:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2003, 2006, 2009, 2010, 2014, 2019 Free Software Foundation, Inc.
2 |
3 | # This program is free software; you can redistribute it and/or modify
4 | # it under the terms of the GNU General Public License as published by
5 | # the Free Software Foundation; either version 3 of the License, or
6 | # (at your option) any later version.
7 | #
8 | # This program is distributed in the hope that it will be useful,
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | # GNU General Public License for more details.
12 | #
13 | # You should have received a copy of the GNU General Public License
14 | # along with this program; see the file COPYING3. If not see
15 | # .
16 |
17 | dg-init
18 | libffi-init
19 |
20 | global srcdir subdir
21 |
22 | if { [string match $compiler_vendor "microsoft"] } {
23 | # -wd4005 macro redefinition
24 | # -wd4244 implicit conversion to type of smaller size
25 | # -wd4305 truncation to smaller type
26 | # -wd4477 printf %lu of uintptr_t
27 | # -wd4312 implicit conversion to type of greater size
28 | # -wd4311 pointer truncation to unsigned long
29 | # -EHsc C++ Exception Handling (no SEH exceptions)
30 | set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc";
31 | } else {
32 | set additional_options "";
33 | }
34 |
35 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]]
36 |
37 | run-many-tests $tlist $additional_options
38 |
39 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]]
40 |
41 | # No C++ for or1k
42 | if { [istarget "or1k-*-*"] } {
43 | foreach test $tlist {
44 | unsupported "$test"
45 | }
46 | } else {
47 | run-many-tests $tlist $additional_options
48 | }
49 |
50 | dg-finish
51 |
52 | # Local Variables:
53 | # tcl-indent-level:4
54 | # End:
55 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/struct7.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check structures.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | typedef struct
10 | {
11 | float f1;
12 | float f2;
13 | double d;
14 | } test_structure_7;
15 |
16 | static test_structure_7 ABI_ATTR struct7 (test_structure_7 ts)
17 | {
18 | ts.f1 += 1;
19 | ts.f2 += 1;
20 | ts.d += 1;
21 |
22 | return ts;
23 | }
24 |
25 | int main (void)
26 | {
27 | ffi_cif cif;
28 | ffi_type *args[MAX_ARGS];
29 | void *values[MAX_ARGS];
30 | ffi_type ts7_type;
31 | ffi_type *ts7_type_elements[4];
32 |
33 | test_structure_7 ts7_arg;
34 |
35 | /* This is a hack to get a properly aligned result buffer */
36 | test_structure_7 *ts7_result =
37 | (test_structure_7 *) malloc (sizeof(test_structure_7));
38 |
39 | ts7_type.size = 0;
40 | ts7_type.alignment = 0;
41 | ts7_type.type = FFI_TYPE_STRUCT;
42 | ts7_type.elements = ts7_type_elements;
43 | ts7_type_elements[0] = &ffi_type_float;
44 | ts7_type_elements[1] = &ffi_type_float;
45 | ts7_type_elements[2] = &ffi_type_double;
46 | ts7_type_elements[3] = NULL;
47 |
48 | args[0] = &ts7_type;
49 | values[0] = &ts7_arg;
50 |
51 | /* Initialize the cif */
52 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts7_type, args) == FFI_OK);
53 |
54 | ts7_arg.f1 = 5.55f;
55 | ts7_arg.f2 = 55.5f;
56 | ts7_arg.d = 6.66;
57 |
58 | printf ("%g\n", ts7_arg.f1);
59 | printf ("%g\n", ts7_arg.f2);
60 | printf ("%g\n", ts7_arg.d);
61 |
62 | ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
63 |
64 | printf ("%g\n", ts7_result->f1);
65 | printf ("%g\n", ts7_result->f2);
66 | printf ("%g\n", ts7_result->d);
67 |
68 | CHECK(ts7_result->f1 == 5.55f + 1);
69 | CHECK(ts7_result->f2 == 55.5f + 1);
70 | CHECK(ts7_result->d == 6.66 + 1);
71 |
72 | free (ts7_result);
73 | exit(0);
74 | }
75 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_many_mixed_float_double.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check register allocation for closure calls with many float and double arguments
3 | Limitations: none.
4 | PR: none.
5 | Originator: */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | #include
10 | #include
11 |
12 | #define NARGS 16
13 |
14 | static void cls_mixed_float_double_fn(ffi_cif* cif , void* ret, void** args,
15 | void* userdata __UNUSED__)
16 | {
17 | double r = 0;
18 | unsigned int i;
19 | double t;
20 | for(i=0; i < cif->nargs; i++)
21 | {
22 | if(cif->arg_types[i] == &ffi_type_double) {
23 | t = *(((double**)(args))[i]);
24 | } else {
25 | t = *(((float**)(args))[i]);
26 | }
27 | r += t;
28 | }
29 | *((double*)ret) = r;
30 | }
31 | typedef double (*cls_mixed)(double, float, double, double, double, double, double, float, float, double, float, float);
32 |
33 | int main (void)
34 | {
35 | ffi_cif cif;
36 | ffi_closure *closure;
37 | void* code;
38 | ffi_type *argtypes[12] = {&ffi_type_double, &ffi_type_float, &ffi_type_double,
39 | &ffi_type_double, &ffi_type_double, &ffi_type_double,
40 | &ffi_type_double, &ffi_type_float, &ffi_type_float,
41 | &ffi_type_double, &ffi_type_float, &ffi_type_float};
42 |
43 |
44 | closure = ffi_closure_alloc(sizeof(ffi_closure), (void**)&code);
45 | if(closure ==NULL)
46 | abort();
47 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 12, &ffi_type_double, argtypes) == FFI_OK);
48 | CHECK(ffi_prep_closure_loc(closure, &cif, cls_mixed_float_double_fn, NULL, code) == FFI_OK);
49 | 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);
50 | ffi_closure_free(closure);
51 | if(fabs(ret - 7.8) < FLT_EPSILON)
52 | exit(0);
53 | else
54 | abort();
55 | }
56 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/testclosure.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check return value float.
3 | Limitations: none.
4 | PR: 41908.
5 | Originator: 20091102 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | typedef struct cls_struct_combined {
11 | float a;
12 | float b;
13 | float c;
14 | float d;
15 | } cls_struct_combined;
16 |
17 | void cls_struct_combined_fn(struct cls_struct_combined arg)
18 | {
19 | printf("%g %g %g %g\n",
20 | arg.a, arg.b,
21 | arg.c, arg.d);
22 | fflush(stdout);
23 | }
24 |
25 | static void
26 | cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
27 | void** args, void* userdata __UNUSED__)
28 | {
29 | struct cls_struct_combined a0;
30 |
31 | a0 = *(struct cls_struct_combined*)(args[0]);
32 |
33 | cls_struct_combined_fn(a0);
34 | }
35 |
36 |
37 | int main (void)
38 | {
39 | ffi_cif cif;
40 | void *code;
41 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
42 | ffi_type* cls_struct_fields0[5];
43 | ffi_type cls_struct_type0;
44 | ffi_type* dbl_arg_types[5];
45 |
46 | struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
47 |
48 | cls_struct_type0.size = 0;
49 | cls_struct_type0.alignment = 0;
50 | cls_struct_type0.type = FFI_TYPE_STRUCT;
51 | cls_struct_type0.elements = cls_struct_fields0;
52 |
53 | cls_struct_fields0[0] = &ffi_type_float;
54 | cls_struct_fields0[1] = &ffi_type_float;
55 | cls_struct_fields0[2] = &ffi_type_float;
56 | cls_struct_fields0[3] = &ffi_type_float;
57 | cls_struct_fields0[4] = NULL;
58 |
59 | dbl_arg_types[0] = &cls_struct_type0;
60 | dbl_arg_types[1] = NULL;
61 |
62 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void,
63 | dbl_arg_types) == FFI_OK);
64 |
65 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
66 |
67 | ((void(*)(cls_struct_combined)) (code))(g_dbl);
68 | /* { dg-output "4 5 1 8" } */
69 | exit(0);
70 | }
71 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_multi_schar.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check passing of multiple signed char values.
3 | Limitations: none.
4 | PR: PR13221.
5 | Originator: 20031129 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | signed char test_func_fn(signed char a1, signed char a2)
11 | {
12 | signed char result;
13 |
14 | result = a1 + a2;
15 |
16 | printf("%d %d: %d\n", a1, a2, result);
17 |
18 | return result;
19 |
20 | }
21 |
22 | static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
23 | void *data __UNUSED__)
24 | {
25 | signed char a1, a2;
26 |
27 | a1 = *(signed char *)avals[0];
28 | a2 = *(signed char *)avals[1];
29 |
30 | *(ffi_arg *)rval = test_func_fn(a1, a2);
31 |
32 | }
33 |
34 | typedef signed char (*test_type)(signed char, signed char);
35 |
36 | int main (void)
37 | {
38 | ffi_cif cif;
39 | void *code;
40 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
41 | void * args_dbl[3];
42 | ffi_type * cl_arg_types[3];
43 | ffi_arg res_call;
44 | signed char a, b, res_closure;
45 |
46 | a = 2;
47 | b = 125;
48 |
49 | args_dbl[0] = &a;
50 | args_dbl[1] = &b;
51 | args_dbl[2] = NULL;
52 |
53 | cl_arg_types[0] = &ffi_type_schar;
54 | cl_arg_types[1] = &ffi_type_schar;
55 | cl_arg_types[2] = NULL;
56 |
57 | /* Initialize the cif */
58 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
59 | &ffi_type_schar, cl_arg_types) == FFI_OK);
60 |
61 | ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
62 | /* { dg-output "2 125: 127" } */
63 | printf("res: %d\n", (signed char)res_call);
64 | /* { dg-output "\nres: 127" } */
65 |
66 | CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
67 |
68 | res_closure = (*((test_type)code))(2, 125);
69 | /* { dg-output "\n2 125: 127" } */
70 | printf("res: %d\n", res_closure);
71 | /* { dg-output "\nres: 127" } */
72 |
73 | exit(0);
74 | }
75 |
--------------------------------------------------------------------------------
/src/nios2/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* libffi target includes for Altera Nios II.
2 |
3 | Copyright (c) 2013 Mentor Graphics.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | ``Software''), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
23 |
24 |
25 | #ifndef LIBFFI_TARGET_H
26 | #define LIBFFI_TARGET_H
27 |
28 | #ifndef LIBFFI_H
29 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
30 | #endif
31 |
32 | #ifndef LIBFFI_ASM
33 | typedef unsigned long ffi_arg;
34 | typedef signed long ffi_sarg;
35 |
36 | typedef enum ffi_abi {
37 | FFI_FIRST_ABI = 0,
38 | FFI_SYSV,
39 | FFI_LAST_ABI,
40 | FFI_DEFAULT_ABI = FFI_SYSV
41 | } ffi_abi;
42 | #endif
43 |
44 | /* Structures have a 4-byte alignment even if all the fields have lesser
45 | alignment requirements. */
46 | #define FFI_AGGREGATE_ALIGNMENT 4
47 |
48 | #define FFI_CLOSURES 1
49 | #define FFI_TRAMPOLINE_SIZE 28 /* 7 instructions */
50 | #define FFI_NATIVE_RAW_API 0
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_multi_sshort.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check passing of multiple signed short values.
3 | Limitations: none.
4 | PR: PR13221.
5 | Originator: 20031129 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | signed short test_func_fn(signed short a1, signed short a2)
11 | {
12 | signed short result;
13 |
14 | result = a1 + a2;
15 |
16 | printf("%d %d: %d\n", a1, a2, result);
17 |
18 | return result;
19 |
20 | }
21 |
22 | static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
23 | void *data __UNUSED__)
24 | {
25 | signed short a1, a2;
26 |
27 | a1 = *(signed short *)avals[0];
28 | a2 = *(signed short *)avals[1];
29 |
30 | *(ffi_arg *)rval = test_func_fn(a1, a2);
31 |
32 | }
33 |
34 | typedef signed short (*test_type)(signed short, signed short);
35 |
36 | int main (void)
37 | {
38 | ffi_cif cif;
39 | void *code;
40 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
41 | void * args_dbl[3];
42 | ffi_type * cl_arg_types[3];
43 | ffi_arg res_call;
44 | unsigned short a, b, res_closure;
45 |
46 | a = 2;
47 | b = 32765;
48 |
49 | args_dbl[0] = &a;
50 | args_dbl[1] = &b;
51 | args_dbl[2] = NULL;
52 |
53 | cl_arg_types[0] = &ffi_type_sshort;
54 | cl_arg_types[1] = &ffi_type_sshort;
55 | cl_arg_types[2] = NULL;
56 |
57 | /* Initialize the cif */
58 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
59 | &ffi_type_sshort, cl_arg_types) == FFI_OK);
60 |
61 | ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
62 | /* { dg-output "2 32765: 32767" } */
63 | printf("res: %d\n", (unsigned short)res_call);
64 | /* { dg-output "\nres: 32767" } */
65 |
66 | CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
67 |
68 | res_closure = (*((test_type)code))(2, 32765);
69 | /* { dg-output "\n2 32765: 32767" } */
70 | printf("res: %d\n", res_closure);
71 | /* { dg-output "\nres: 32767" } */
72 |
73 | exit(0);
74 | }
75 |
--------------------------------------------------------------------------------
/src/microblaze/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 | ffitarget.h - Copyright (c) 2012, 2013 Xilinx, Inc
3 |
4 | Target configuration macros for MicroBlaze.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | ``Software''), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 | ----------------------------------------------------------------------- */
26 |
27 | #ifndef LIBFFI_TARGET_H
28 | #define LIBFFI_TARGET_H
29 |
30 | #ifndef LIBFFI_H
31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
32 | #endif
33 |
34 | #ifndef LIBFFI_ASM
35 | typedef unsigned long ffi_arg;
36 | typedef signed long ffi_sarg;
37 |
38 | typedef enum ffi_abi {
39 | FFI_FIRST_ABI = 0,
40 | FFI_SYSV,
41 | FFI_LAST_ABI,
42 | FFI_DEFAULT_ABI = FFI_SYSV
43 | } ffi_abi;
44 | #endif
45 |
46 | /* Definitions for closures */
47 |
48 | #define FFI_CLOSURES 1
49 | #define FFI_NATIVE_RAW_API 0
50 |
51 | #define FFI_TRAMPOLINE_SIZE (4*8)
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_multi_ushort.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check passing of multiple unsigned short values.
3 | Limitations: none.
4 | PR: PR13221.
5 | Originator: 20031129 */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 |
10 | unsigned short test_func_fn(unsigned short a1, unsigned short a2)
11 | {
12 | unsigned short result;
13 |
14 | result = a1 + a2;
15 |
16 | printf("%d %d: %d\n", a1, a2, result);
17 |
18 | return result;
19 |
20 | }
21 |
22 | static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
23 | void *data __UNUSED__)
24 | {
25 | unsigned short a1, a2;
26 |
27 | a1 = *(unsigned short *)avals[0];
28 | a2 = *(unsigned short *)avals[1];
29 |
30 | *(ffi_arg *)rval = test_func_fn(a1, a2);
31 |
32 | }
33 |
34 | typedef unsigned short (*test_type)(unsigned short, unsigned short);
35 |
36 | int main (void)
37 | {
38 | ffi_cif cif;
39 | void *code;
40 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
41 | void * args_dbl[3];
42 | ffi_type * cl_arg_types[3];
43 | ffi_arg res_call;
44 | unsigned short a, b, res_closure;
45 |
46 | a = 2;
47 | b = 32765;
48 |
49 | args_dbl[0] = &a;
50 | args_dbl[1] = &b;
51 | args_dbl[2] = NULL;
52 |
53 | cl_arg_types[0] = &ffi_type_ushort;
54 | cl_arg_types[1] = &ffi_type_ushort;
55 | cl_arg_types[2] = NULL;
56 |
57 | /* Initialize the cif */
58 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
59 | &ffi_type_ushort, cl_arg_types) == FFI_OK);
60 |
61 | ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
62 | /* { dg-output "2 32765: 32767" } */
63 | printf("res: %d\n", (unsigned short)res_call);
64 | /* { dg-output "\nres: 32767" } */
65 |
66 | CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
67 |
68 | res_closure = (*((test_type)code))(2, 32765);
69 | /* { dg-output "\n2 32765: 32767" } */
70 | printf("res: %d\n", res_closure);
71 | /* { dg-output "\nres: 32767" } */
72 |
73 | exit(0);
74 | }
75 |
--------------------------------------------------------------------------------
/testsuite/lib/wrapper.exp:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2004, 2007 Free Software Foundation, Inc.
2 |
3 | # This program is free software; you can redistribute it and/or modify
4 | # it under the terms of the GNU General Public License as published by
5 | # the Free Software Foundation; either version 3 of the License, or
6 | # (at your option) any later version.
7 | #
8 | # This program is distributed in the hope that it will be useful,
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | # GNU General Public License for more details.
12 | #
13 | # You should have received a copy of the GNU General Public License
14 | # along with GCC; see the file COPYING3. If not see
15 | # .
16 |
17 | # This file contains GCC-specifics for status wrappers for test programs.
18 |
19 | # ${tool}_maybe_build_wrapper -- Build wrapper object if the target
20 | # needs it. FILENAME is the path to the wrapper file. If there are
21 | # additional arguments, they are command-line options to provide to
22 | # the compiler when compiling FILENAME.
23 |
24 | proc ${tool}_maybe_build_wrapper { filename args } {
25 | global gluefile wrap_flags
26 |
27 | if { [target_info needs_status_wrapper] != "" \
28 | && [target_info needs_status_wrapper] != "0" \
29 | && ![info exists gluefile] } {
30 | set saved_wrap_compile_flags [target_info wrap_compile_flags]
31 | set flags [join $args " "]
32 | # The wrapper code may contain code that gcc objects on. This
33 | # became true for dejagnu-1.4.4. The set of warnings and code
34 | # that gcc objects on may change, so just make sure -w is always
35 | # passed to turn off all warnings.
36 | set_currtarget_info wrap_compile_flags \
37 | "$saved_wrap_compile_flags -w $flags"
38 | set result [build_wrapper $filename]
39 | set_currtarget_info wrap_compile_flags "$saved_wrap_compile_flags"
40 | if { $result != "" } {
41 | set gluefile [lindex $result 0]
42 | set wrap_flags [lindex $result 1]
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_many_mixed_args.c:
--------------------------------------------------------------------------------
1 | /* Area: closure_call
2 | Purpose: Check closures called with many args of mixed types
3 | Limitations: none.
4 | PR: none.
5 | Originator: */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | #include
10 | #include
11 |
12 | #define NARGS 16
13 |
14 | static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
15 | void* userdata __UNUSED__)
16 | {
17 | int i;
18 | double r = 0;
19 | double t;
20 | for(i = 0; i < NARGS; i++)
21 | {
22 | if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
23 | {
24 | t = *(long int *)args[i];
25 | CHECK(t == i+1);
26 | }
27 | else
28 | {
29 | t = *(double *)args[i];
30 | CHECK(fabs(t - ((i+1) * 0.1)) < FLT_EPSILON);
31 | }
32 | r += t;
33 | }
34 | *(double *)resp = r;
35 | }
36 | typedef double (*cls_ret_double)(double, double, double, double, long int,
37 | double, double, double, double, long int, double, long int, double, long int,
38 | double, long int);
39 |
40 | int main (void)
41 | {
42 | ffi_cif cif;
43 | void *code;
44 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
45 | ffi_type * cl_arg_types[NARGS];
46 | double res;
47 | int i;
48 | double expected = 64.9;
49 |
50 | for(i = 0; i < NARGS; i++)
51 | {
52 | if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
53 | cl_arg_types[i] = &ffi_type_slong;
54 | else
55 | cl_arg_types[i] = &ffi_type_double;
56 | }
57 |
58 | /* Initialize the cif */
59 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NARGS,
60 | &ffi_type_double, cl_arg_types) == FFI_OK);
61 |
62 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK);
63 |
64 | res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10,
65 | 1.1, 12, 1.3, 14, 1.5, 16);
66 | if (fabs(res - expected) < FLT_EPSILON)
67 | exit(0);
68 | else
69 | abort();
70 | }
71 |
--------------------------------------------------------------------------------
/src/ia64/ia64_flags.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 | ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company
3 |
4 | IA64/unix Foreign Function Interface
5 |
6 | Original author: Hans Boehm, HP Labs
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | ``Software''), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 | DEALINGS IN THE SOFTWARE.
27 | ----------------------------------------------------------------------- */
28 |
29 | /* "Type" codes used between assembly and C. When used as a part of
30 | a cfi->flags value, the low byte will be these extra type codes,
31 | and bits 8-31 will be the actual size of the type. */
32 |
33 | /* Small structures containing N words in integer registers. */
34 | #define FFI_IA64_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 1)
35 |
36 | /* Homogeneous Floating Point Aggregates (HFAs) which are returned
37 | in FP registers. */
38 | #define FFI_IA64_TYPE_HFA_FLOAT (FFI_TYPE_LAST + 2)
39 | #define FFI_IA64_TYPE_HFA_DOUBLE (FFI_TYPE_LAST + 3)
40 | #define FFI_IA64_TYPE_HFA_LDOUBLE (FFI_TYPE_LAST + 4)
41 |
--------------------------------------------------------------------------------
/src/xtensa/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------*-C-*-
2 | ffitarget.h - Copyright (c) 2013 Tensilica, Inc.
3 | Target configuration macros for XTENSA.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | ``Software''), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included
14 | in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 | ----------------------------------------------------------------------- */
25 |
26 | #ifndef LIBFFI_TARGET_H
27 | #define LIBFFI_TARGET_H
28 |
29 | #ifndef LIBFFI_H
30 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
31 | #endif
32 |
33 | #ifndef LIBFFI_ASM
34 | typedef unsigned long ffi_arg;
35 | typedef signed long ffi_sarg;
36 |
37 | typedef enum ffi_abi {
38 | FFI_FIRST_ABI = 0,
39 | FFI_SYSV,
40 | FFI_LAST_ABI,
41 | FFI_DEFAULT_ABI = FFI_SYSV
42 | } ffi_abi;
43 | #endif
44 |
45 | #define FFI_REGISTER_NARGS 6
46 |
47 | /* ---- Definitions for closures ----------------------------------------- */
48 |
49 | #define FFI_CLOSURES 1
50 | #define FFI_NATIVE_RAW_API 0
51 | #define FFI_TRAMPOLINE_SIZE 24
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/src/metag/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------*-C-*-
2 | ffitarget.h - Copyright (c) 2013 Imagination Technologies Ltd.
3 | Target configuration macros for Meta
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | ``Software''), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included
14 | in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 |
25 | ----------------------------------------------------------------------- */
26 |
27 | #ifndef LIBFFI_TARGET_H
28 | #define LIBFFI_TARGET_H
29 |
30 | #ifndef LIBFFI_H
31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
32 | #endif
33 |
34 | #ifndef LIBFFI_ASM
35 | typedef unsigned long ffi_arg;
36 | typedef signed long ffi_sarg;
37 |
38 | typedef enum ffi_abi {
39 | FFI_FIRST_ABI = 0,
40 | FFI_SYSV,
41 | FFI_DEFAULT_ABI = FFI_SYSV,
42 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1,
43 | } ffi_abi;
44 | #endif
45 |
46 | /* ---- Definitions for closures ----------------------------------------- */
47 |
48 | #define FFI_CLOSURES 1
49 | #define FFI_TRAMPOLINE_SIZE 48
50 | #define FFI_NATIVE_RAW_API 0
51 |
52 | #endif
53 |
54 |
--------------------------------------------------------------------------------
/src/arc/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 | ffitarget.h - Copyright (c) 2012 Anthony Green
3 | Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com)
4 | Target configuration macros for ARC.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | ``Software''), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 | OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | ----------------------------------------------------------------------- */
26 |
27 | #ifndef LIBFFI_TARGET_H
28 | #define LIBFFI_TARGET_H
29 |
30 | #ifndef LIBFFI_H
31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
32 | #endif
33 |
34 | /* ---- Generic type definitions ----------------------------------------- */
35 |
36 | #ifndef LIBFFI_ASM
37 | typedef unsigned long ffi_arg;
38 | typedef signed long ffi_sarg;
39 |
40 | typedef enum ffi_abi
41 | {
42 | FFI_FIRST_ABI = 0,
43 | FFI_ARCOMPACT,
44 | FFI_LAST_ABI,
45 | FFI_DEFAULT_ABI = FFI_ARCOMPACT
46 | } ffi_abi;
47 | #endif
48 |
49 | #define FFI_CLOSURES 1
50 | #define FFI_TRAMPOLINE_SIZE 12
51 | #define FFI_NATIVE_RAW_API 0
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/src/m32r/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------*-C-*-
2 | ffitarget.h - Copyright (c) 2012 Anthony Green
3 | Copyright (c) 2004 Renesas Technology.
4 | Target configuration macros for M32R.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | ``Software''), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 | OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | ----------------------------------------------------------------------- */
26 |
27 | #ifndef LIBFFI_TARGET_H
28 | #define LIBFFI_TARGET_H
29 |
30 | #ifndef LIBFFI_H
31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
32 | #endif
33 |
34 | /* ---- Generic type definitions ----------------------------------------- */
35 |
36 | #ifndef LIBFFI_ASM
37 | typedef unsigned long ffi_arg;
38 | typedef signed long ffi_sarg;
39 |
40 | typedef enum ffi_abi
41 | {
42 | FFI_FIRST_ABI = 0,
43 | FFI_SYSV,
44 | FFI_LAST_ABI,
45 | FFI_DEFAULT_ABI = FFI_SYSV
46 | } ffi_abi;
47 | #endif
48 |
49 | #define FFI_CLOSURES 0
50 | #define FFI_TRAMPOLINE_SIZE 24
51 | #define FFI_NATIVE_RAW_API 0
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/src/moxie/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------*-C-*-
2 | ffitarget.h - Copyright (c) 2012, 2013 Anthony Green
3 | Target configuration macros for Moxie
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | ``Software''), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included
14 | in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 |
25 | ----------------------------------------------------------------------- */
26 |
27 | #ifndef LIBFFI_TARGET_H
28 | #define LIBFFI_TARGET_H
29 |
30 | /* ---- System specific configurations ----------------------------------- */
31 |
32 | #ifndef LIBFFI_ASM
33 | typedef unsigned long ffi_arg;
34 | typedef signed long ffi_sarg;
35 |
36 | typedef enum ffi_abi {
37 | FFI_FIRST_ABI = 0,
38 | FFI_EABI,
39 | FFI_DEFAULT_ABI = FFI_EABI,
40 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
41 | } ffi_abi;
42 | #endif
43 |
44 | /* ---- Definitions for closures ----------------------------------------- */
45 |
46 | #define FFI_CLOSURES 1
47 | #define FFI_NATIVE_RAW_API 0
48 |
49 | /* Trampolines are 12-bytes long. See ffi_prep_closure_loc. */
50 | #define FFI_TRAMPOLINE_SIZE (12)
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/src/sh/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------*-C-*-
2 | ffitarget.h - Copyright (c) 2012 Anthony Green
3 | Copyright (c) 1996-2003 Red Hat, Inc.
4 | Target configuration macros for SuperH.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | ``Software''), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 |
26 | ----------------------------------------------------------------------- */
27 |
28 | #ifndef LIBFFI_TARGET_H
29 | #define LIBFFI_TARGET_H
30 |
31 | #ifndef LIBFFI_H
32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
33 | #endif
34 |
35 | /* ---- Generic type definitions ----------------------------------------- */
36 |
37 | #ifndef LIBFFI_ASM
38 | typedef unsigned long ffi_arg;
39 | typedef signed long ffi_sarg;
40 |
41 | typedef enum ffi_abi {
42 | FFI_FIRST_ABI = 0,
43 | FFI_SYSV,
44 | FFI_LAST_ABI,
45 | FFI_DEFAULT_ABI = FFI_SYSV
46 | } ffi_abi;
47 | #endif
48 |
49 | #define FFI_CLOSURES 1
50 | #define FFI_TRAMPOLINE_SIZE 16
51 | #define FFI_NATIVE_RAW_API 0
52 |
53 | #endif
54 |
55 |
--------------------------------------------------------------------------------
/include/ffi_cfi.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 | ffi_cfi.h - Copyright (c) 2014 Red Hat, Inc.
3 |
4 | Conditionally assemble cfi directives. Only necessary for building libffi.
5 | ----------------------------------------------------------------------- */
6 |
7 | #ifndef FFI_CFI_H
8 | #define FFI_CFI_H
9 |
10 | #ifdef HAVE_AS_CFI_PSEUDO_OP
11 |
12 | # define cfi_startproc .cfi_startproc
13 | # define cfi_endproc .cfi_endproc
14 | # define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off
15 | # define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg
16 | # define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off
17 | # define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
18 | # define cfi_offset(reg, off) .cfi_offset reg, off
19 | # define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
20 | # define cfi_register(r1, r2) .cfi_register r1, r2
21 | # define cfi_return_column(reg) .cfi_return_column reg
22 | # define cfi_restore(reg) .cfi_restore reg
23 | # define cfi_same_value(reg) .cfi_same_value reg
24 | # define cfi_undefined(reg) .cfi_undefined reg
25 | # define cfi_remember_state .cfi_remember_state
26 | # define cfi_restore_state .cfi_restore_state
27 | # define cfi_window_save .cfi_window_save
28 | # define cfi_personality(enc, exp) .cfi_personality enc, exp
29 | # define cfi_lsda(enc, exp) .cfi_lsda enc, exp
30 | # define cfi_escape(...) .cfi_escape __VA_ARGS__
31 |
32 | #else
33 |
34 | # define cfi_startproc
35 | # define cfi_endproc
36 | # define cfi_def_cfa(reg, off)
37 | # define cfi_def_cfa_register(reg)
38 | # define cfi_def_cfa_offset(off)
39 | # define cfi_adjust_cfa_offset(off)
40 | # define cfi_offset(reg, off)
41 | # define cfi_rel_offset(reg, off)
42 | # define cfi_register(r1, r2)
43 | # define cfi_return_column(reg)
44 | # define cfi_restore(reg)
45 | # define cfi_same_value(reg)
46 | # define cfi_undefined(reg)
47 | # define cfi_remember_state
48 | # define cfi_restore_state
49 | # define cfi_window_save
50 | # define cfi_personality(enc, exp)
51 | # define cfi_lsda(enc, exp)
52 | # define cfi_escape(...)
53 |
54 | #endif /* HAVE_AS_CFI_PSEUDO_OP */
55 | #endif /* FFI_CFI_H */
56 |
--------------------------------------------------------------------------------
/src/m68k/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------*-C-*-
2 | ffitarget.h - Copyright (c) 2012 Anthony Green
3 | Copyright (c) 1996-2003 Red Hat, Inc.
4 | Target configuration macros for Motorola 68K.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | ``Software''), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 |
26 | ----------------------------------------------------------------------- */
27 |
28 | #ifndef LIBFFI_TARGET_H
29 | #define LIBFFI_TARGET_H
30 |
31 | #ifndef LIBFFI_H
32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
33 | #endif
34 |
35 | #ifndef LIBFFI_ASM
36 | typedef unsigned long ffi_arg;
37 | typedef signed long ffi_sarg;
38 |
39 | typedef enum ffi_abi {
40 | FFI_FIRST_ABI = 0,
41 | FFI_SYSV,
42 | FFI_LAST_ABI,
43 | FFI_DEFAULT_ABI = FFI_SYSV
44 | } ffi_abi;
45 | #endif
46 |
47 | /* ---- Definitions for closures ----------------------------------------- */
48 |
49 | #define FFI_CLOSURES 1
50 | #define FFI_TRAMPOLINE_SIZE 16
51 | #define FFI_NATIVE_RAW_API 0
52 |
53 | #endif
54 |
55 |
--------------------------------------------------------------------------------
/testsuite/libffi.call/struct8.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call
2 | Purpose: Check structures.
3 | Limitations: none.
4 | PR: none.
5 | Originator: From the original ffitest.c */
6 |
7 | /* { dg-do run } */
8 | #include "ffitest.h"
9 | typedef struct
10 | {
11 | float f1;
12 | float f2;
13 | float f3;
14 | float f4;
15 | } test_structure_8;
16 |
17 | static test_structure_8 ABI_ATTR struct8 (test_structure_8 ts)
18 | {
19 | ts.f1 += 1;
20 | ts.f2 += 1;
21 | ts.f3 += 1;
22 | ts.f4 += 1;
23 |
24 | return ts;
25 | }
26 |
27 | int main (void)
28 | {
29 | ffi_cif cif;
30 | ffi_type *args[MAX_ARGS];
31 | void *values[MAX_ARGS];
32 | ffi_type ts8_type;
33 | ffi_type *ts8_type_elements[5];
34 |
35 | test_structure_8 ts8_arg;
36 |
37 | /* This is a hack to get a properly aligned result buffer */
38 | test_structure_8 *ts8_result =
39 | (test_structure_8 *) malloc (sizeof(test_structure_8));
40 |
41 | ts8_type.size = 0;
42 | ts8_type.alignment = 0;
43 | ts8_type.type = FFI_TYPE_STRUCT;
44 | ts8_type.elements = ts8_type_elements;
45 | ts8_type_elements[0] = &ffi_type_float;
46 | ts8_type_elements[1] = &ffi_type_float;
47 | ts8_type_elements[2] = &ffi_type_float;
48 | ts8_type_elements[3] = &ffi_type_float;
49 | ts8_type_elements[4] = NULL;
50 |
51 | args[0] = &ts8_type;
52 | values[0] = &ts8_arg;
53 |
54 | /* Initialize the cif */
55 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts8_type, args) == FFI_OK);
56 |
57 | ts8_arg.f1 = 5.55f;
58 | ts8_arg.f2 = 55.5f;
59 | ts8_arg.f3 = -5.55f;
60 | ts8_arg.f4 = -55.5f;
61 |
62 | printf ("%g\n", ts8_arg.f1);
63 | printf ("%g\n", ts8_arg.f2);
64 | printf ("%g\n", ts8_arg.f3);
65 | printf ("%g\n", ts8_arg.f4);
66 |
67 | ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
68 |
69 | printf ("%g\n", ts8_result->f1);
70 | printf ("%g\n", ts8_result->f2);
71 | printf ("%g\n", ts8_result->f3);
72 | printf ("%g\n", ts8_result->f4);
73 |
74 | CHECK(ts8_result->f1 == 5.55f + 1);
75 | CHECK(ts8_result->f2 == 55.5f + 1);
76 | CHECK(ts8_result->f3 == -5.55f + 1);
77 | CHECK(ts8_result->f4 == -55.5f + 1);
78 |
79 | free (ts8_result);
80 | exit(0);
81 | }
82 |
--------------------------------------------------------------------------------
/src/avr32/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------*-C-*-
2 | ffitarget.h - Copyright (c) 2012 Anthony Green
3 | Copyright (c) 2009 Bradley Smith
4 | Target configuration macros for AVR32.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | ``Software''), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 |
26 | ----------------------------------------------------------------------- */
27 |
28 | #ifndef LIBFFI_TARGET_H
29 | #define LIBFFI_TARGET_H
30 |
31 | #ifndef LIBFFI_H
32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
33 | #endif
34 |
35 | #ifndef LIBFFI_ASM
36 | typedef unsigned long ffi_arg;
37 | typedef signed long ffi_sarg;
38 |
39 | typedef enum ffi_abi {
40 | FFI_FIRST_ABI = 0,
41 | FFI_SYSV,
42 | FFI_LAST_ABI,
43 | FFI_DEFAULT_ABI = FFI_SYSV
44 | } ffi_abi;
45 | #endif
46 |
47 | #define FFI_EXTRA_CIF_FIELDS unsigned int rstruct_flag
48 |
49 | /* Definitions for closures */
50 |
51 | #define FFI_CLOSURES 1
52 | #define FFI_TRAMPOLINE_SIZE 36
53 | #define FFI_NATIVE_RAW_API 0
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/cls_pointer.c:
--------------------------------------------------------------------------------
1 | /* Area: ffi_call, closure_call
2 | Purpose: Check pointer arguments.
3 | Limitations: none.
4 | PR: none.
5 | Originator: Blake Chaffin 6/6/2007 */
6 |
7 | /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
8 | #include "ffitest.h"
9 |
10 | void* cls_pointer_fn(void* a1, void* a2)
11 | {
12 | void* result = (void*)((intptr_t)a1 + (intptr_t)a2);
13 |
14 | printf("0x%08x 0x%08x: 0x%08x\n",
15 | (unsigned int)(uintptr_t) a1,
16 | (unsigned int)(uintptr_t) a2,
17 | (unsigned int)(uintptr_t) result);
18 |
19 | return result;
20 | }
21 |
22 | static void
23 | cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp,
24 | void** args, void* userdata __UNUSED__)
25 | {
26 | void* a1 = *(void**)(args[0]);
27 | void* a2 = *(void**)(args[1]);
28 |
29 | *(void**)resp = cls_pointer_fn(a1, a2);
30 | }
31 |
32 | int main (void)
33 | {
34 | ffi_cif cif;
35 | void *code;
36 | ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
37 | void* args[3];
38 | /* ffi_type cls_pointer_type; */
39 | ffi_type* arg_types[3];
40 |
41 | /* cls_pointer_type.size = sizeof(void*);
42 | cls_pointer_type.alignment = 0;
43 | cls_pointer_type.type = FFI_TYPE_POINTER;
44 | cls_pointer_type.elements = NULL;*/
45 |
46 | void* arg1 = (void*)0x12345678;
47 | void* arg2 = (void*)0x89abcdef;
48 | ffi_arg res = 0;
49 |
50 | arg_types[0] = &ffi_type_pointer;
51 | arg_types[1] = &ffi_type_pointer;
52 | arg_types[2] = NULL;
53 |
54 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
55 | arg_types) == FFI_OK);
56 |
57 | args[0] = &arg1;
58 | args[1] = &arg2;
59 | args[2] = NULL;
60 |
61 | ffi_call(&cif, FFI_FN(cls_pointer_fn), &res, args);
62 | /* { dg-output "0x12345678 0x89abcdef: 0x9be02467" } */
63 | printf("res: 0x%08x\n", (unsigned int) res);
64 | /* { dg-output "\nres: 0x9be02467" } */
65 |
66 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
67 |
68 | res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
69 | /* { dg-output "\n0x12345678 0x89abcdef: 0x9be02467" } */
70 | printf("res: 0x%08x\n", (unsigned int) res);
71 | /* { dg-output "\nres: 0x9be02467" } */
72 |
73 | exit(0);
74 | }
75 |
--------------------------------------------------------------------------------
/testsuite/libffi.closures/closure.exp:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2003, 2006, 2009, 2010, 2014, 2019 Free Software Foundation, Inc.
2 | # Copyright (C) 2019 Anthony Green
3 |
4 | # This program is free software; you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation; either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program; see the file COPYING3. If not see
16 | # .
17 |
18 | dg-init
19 | libffi-init
20 |
21 | global srcdir subdir
22 |
23 | if { [string match $compiler_vendor "microsoft"] } {
24 | # -wd4005 macro redefinition
25 | # -wd4244 implicit conversion to type of smaller size
26 | # -wd4305 truncation to smaller type
27 | # -wd4477 printf %lu of uintptr_t
28 | # -wd4312 implicit conversion to type of greater size
29 | # -wd4311 pointer truncation to unsigned long
30 | # -EHsc C++ Exception Handling (no SEH exceptions)
31 | set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc";
32 | } else {
33 | set additional_options "";
34 | }
35 |
36 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]]
37 |
38 | if { [libffi_feature_test "#if FFI_CLOSURES"] } {
39 | run-many-tests $tlist ""
40 | } else {
41 | foreach test $tlist {
42 | unsupported "$test"
43 | }
44 | }
45 |
46 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]]
47 |
48 | # No C++ for or1k
49 | if { [istarget "or1k-*-*"] } {
50 | foreach test $tlist {
51 | unsupported "$test"
52 | }
53 | } else {
54 | if { [libffi_feature_test "#if FFI_CLOSURES"] } {
55 | run-many-tests $tlist $additional_options
56 | } else {
57 | foreach test $tlist {
58 | unsupported "$test"
59 | }
60 | }
61 | }
62 |
63 | dg-finish
64 |
65 | # Local Variables:
66 | # tcl-indent-level:4
67 | # End:
68 |
--------------------------------------------------------------------------------
/src/alpha/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------*-C-*-
2 | ffitarget.h - Copyright (c) 2012 Anthony Green
3 | Copyright (c) 1996-2003 Red Hat, Inc.
4 | Target configuration macros for Alpha.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | ``Software''), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 |
26 | ----------------------------------------------------------------------- */
27 |
28 | #ifndef LIBFFI_TARGET_H
29 | #define LIBFFI_TARGET_H
30 |
31 | #ifndef LIBFFI_H
32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
33 | #endif
34 |
35 | #ifndef LIBFFI_ASM
36 | typedef unsigned long ffi_arg;
37 | typedef signed long ffi_sarg;
38 |
39 | typedef enum ffi_abi {
40 | FFI_FIRST_ABI = 0,
41 | FFI_OSF,
42 | FFI_LAST_ABI,
43 | FFI_DEFAULT_ABI = FFI_OSF
44 | } ffi_abi;
45 | #endif
46 |
47 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
48 | #define FFI_TARGET_HAS_COMPLEX_TYPE
49 |
50 | /* ---- Definitions for closures ----------------------------------------- */
51 |
52 | #define FFI_CLOSURES 1
53 | #define FFI_GO_CLOSURES 1
54 | #define FFI_TRAMPOLINE_SIZE 24
55 | #define FFI_NATIVE_RAW_API 0
56 |
57 | #endif
58 |
--------------------------------------------------------------------------------
/testsuite/libffi.complex/many_complex.inc:
--------------------------------------------------------------------------------
1 | /* -*-c-*- */
2 | #include "ffitest.h"
3 |
4 | #include
5 | #include
6 |
7 | static _Complex T_C_TYPE many(_Complex T_C_TYPE c1,
8 | _Complex T_C_TYPE c2,
9 | _Complex T_C_TYPE c3,
10 | _Complex T_C_TYPE c4,
11 | _Complex T_C_TYPE c5,
12 | _Complex T_C_TYPE c6,
13 | _Complex T_C_TYPE c7,
14 | _Complex T_C_TYPE c8,
15 | _Complex T_C_TYPE c9,
16 | _Complex T_C_TYPE c10,
17 | _Complex T_C_TYPE c11,
18 | _Complex T_C_TYPE c12,
19 | _Complex T_C_TYPE c13)
20 | {
21 | printf("0 :%f,%fi\n"
22 | "1 :%f,%fi\n"
23 | "2 :%f,%fi\n"
24 | "3 :%f,%fi\n"
25 | "4 :%f,%fi\n"
26 | "5 :%f,%fi\n"
27 | "6 :%f,%fi\n"
28 | "7 :%f,%fi\n"
29 | "8 :%f,%fi\n"
30 | "9 :%f,%fi\n"
31 | "10:%f,%fi\n"
32 | "11:%f,%fi\n"
33 | "12:%f,%fi\n",
34 | T_CONV creal (c1), T_CONV cimag (c1),
35 | T_CONV creal (c2), T_CONV cimag (c2),
36 | T_CONV creal (c3), T_CONV cimag (c3),
37 | T_CONV creal (c4), T_CONV cimag (c4),
38 | T_CONV creal (c5), T_CONV cimag (c5),
39 | T_CONV creal (c6), T_CONV cimag (c6),
40 | T_CONV creal (c7), T_CONV cimag (c7),
41 | T_CONV creal (c8), T_CONV cimag (c8),
42 | T_CONV creal (c9), T_CONV cimag (c9),
43 | T_CONV creal (c10), T_CONV cimag (c10),
44 | T_CONV creal (c11), T_CONV cimag (c11),
45 | T_CONV creal (c12), T_CONV cimag (c12),
46 | T_CONV creal (c13), T_CONV cimag (c13));
47 |
48 | return (c1+c2-c3-c4+c5+c6+c7-c8-c9-c10-c11+c12+c13);
49 | }
50 |
51 | int main (void)
52 | {
53 | ffi_cif cif;
54 | ffi_type *args[13];
55 | void *values[13];
56 | _Complex T_C_TYPE ca[13];
57 | _Complex T_C_TYPE c, cc;
58 | int i;
59 |
60 | for (i = 0; i < 13; i++)
61 | {
62 | args[i] = &T_FFI_TYPE;
63 | values[i] = &ca[i];
64 | ca[i] = i + (-20 - i) * I;
65 | }
66 |
67 | /* Initialize the cif */
68 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, &T_FFI_TYPE, args) == FFI_OK);
69 |
70 | ffi_call(&cif, FFI_FN(many), &c, values);
71 |
72 | cc = many(ca[0], ca[1], ca[2], ca[3], ca[4], ca[5], ca[6], ca[7], ca[8],
73 | ca[9], ca[10], ca[11], ca[12]);
74 | CHECK(creal (cc) == creal (c));
75 | CHECK(cimag (cc) == cimag (c));
76 |
77 | exit(0);
78 | }
79 |
--------------------------------------------------------------------------------
/src/or1k/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 | ffitarget.h - Copyright (c) 2014 Sebastian Macke
3 |
4 | OpenRISC Target configuration macros
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | ``Software''), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 | ----------------------------------------------------------------------- */
26 |
27 | #ifndef LIBFFI_TARGET_H
28 | #define LIBFFI_TARGET_H
29 |
30 | #ifndef LIBFFI_H
31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
32 | #endif
33 |
34 | /* ---- System specific configurations ----------------------------------- */
35 |
36 | #ifndef LIBFFI_ASM
37 | typedef unsigned long ffi_arg;
38 | typedef signed long ffi_sarg;
39 |
40 | typedef enum ffi_abi {
41 | FFI_FIRST_ABI = 0,
42 | FFI_SYSV,
43 | FFI_LAST_ABI,
44 | FFI_DEFAULT_ABI = FFI_SYSV
45 | } ffi_abi;
46 | #endif
47 |
48 | /* ---- Definitions for closures ----------------------------------------- */
49 |
50 | #define FFI_CLOSURES 1
51 | #define FFI_NATIVE_RAW_API 0
52 | #define FFI_TRAMPOLINE_SIZE (24)
53 |
54 | #define FFI_TARGET_SPECIFIC_VARIADIC 1
55 | #define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs;
56 |
57 | #endif
58 |
59 |
--------------------------------------------------------------------------------
/src/sh64/ffitarget.h:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------*-C-*-
2 | ffitarget.h - Copyright (c) 2012 Anthony Green
3 | Copyright (c) 1996-2003 Red Hat, Inc.
4 | Target configuration macros for SuperH - SHmedia.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | ``Software''), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 |
26 | ----------------------------------------------------------------------- */
27 |
28 | #ifndef LIBFFI_TARGET_H
29 | #define LIBFFI_TARGET_H
30 |
31 | #ifndef LIBFFI_H
32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
33 | #endif
34 |
35 | /* ---- Generic type definitions ----------------------------------------- */
36 |
37 | #ifndef LIBFFI_ASM
38 | typedef unsigned long ffi_arg;
39 | typedef signed long ffi_sarg;
40 |
41 | typedef enum ffi_abi {
42 | FFI_FIRST_ABI = 0,
43 | FFI_SYSV,
44 | FFI_LAST_ABI,
45 | FFI_DEFAULT_ABI = FFI_SYSV
46 | } ffi_abi;
47 |
48 | #define FFI_EXTRA_CIF_FIELDS long long flags2
49 | #endif
50 |
51 | /* ---- Definitions for closures ----------------------------------------- */
52 |
53 | #define FFI_CLOSURES 1
54 | #define FFI_TRAMPOLINE_SIZE 32
55 | #define FFI_NATIVE_RAW_API 0
56 |
57 | #endif
58 |
59 |
--------------------------------------------------------------------------------
/m4/ax_check_compile_flag.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
8 | #
9 | # DESCRIPTION
10 | #
11 | # Check whether the given FLAG works with the current language's compiler
12 | # or gives an error. (Warnings, however, are ignored)
13 | #
14 | # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
15 | # success/failure.
16 | #
17 | # If EXTRA-FLAGS is defined, it is added to the current language's default
18 | # flags (e.g. CFLAGS) when the check is done. The check is thus made with
19 | # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
20 | # force the compiler to issue an error when a bad flag is given.
21 | #
22 | # INPUT gives an alternative input source to AC_COMPILE_IFELSE.
23 | #
24 | # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
25 | # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
26 | #
27 | # LICENSE
28 | #
29 | # Copyright (c) 2008 Guido U. Draheim
30 | # Copyright (c) 2011 Maarten Bosmans
31 | #
32 | # Copying and distribution of this file, with or without modification, are
33 | # permitted in any medium without royalty provided the copyright notice
34 | # and this notice are preserved. This file is offered as-is, without any
35 | # warranty.
36 |
37 | #serial 6
38 |
39 | AC_DEFUN([AX_CHECK_COMPILE_FLAG],
40 | [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
41 | AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
42 | AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
43 | ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
44 | _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
45 | AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
46 | [AS_VAR_SET(CACHEVAR,[yes])],
47 | [AS_VAR_SET(CACHEVAR,[no])])
48 | _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
49 | AS_VAR_IF(CACHEVAR,yes,
50 | [m4_default([$2], :)],
51 | [m4_default([$3], :)])
52 | AS_VAR_POPDEF([CACHEVAR])dnl
53 | ])dnl AX_CHECK_COMPILE_FLAGS
54 |
--------------------------------------------------------------------------------