ffi 1.9.18 → 1.9.21
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/Rakefile +14 -3
- data/ext/ffi_c/AbstractMemory.c +6 -1
- data/ext/ffi_c/Platform.c +10 -2
- data/ext/ffi_c/extconf.rb +7 -2
- data/ext/ffi_c/libffi.bsd.mk +9 -3
- data/ext/ffi_c/libffi.darwin.mk +14 -4
- data/ext/ffi_c/libffi.gnu.mk +2 -1
- data/ext/ffi_c/libffi.mk +9 -4
- data/ext/ffi_c/libffi/ChangeLog.libffi +2 -2
- data/ext/ffi_c/libffi/{ChangeLog → ChangeLog.libffi-3.1} +1402 -2
- data/ext/ffi_c/libffi/ChangeLog.v1 +1 -1
- data/ext/ffi_c/libffi/LICENSE +1 -1
- data/ext/ffi_c/libffi/Makefile.am +166 -157
- data/ext/ffi_c/libffi/README +164 -52
- data/ext/ffi_c/libffi/acinclude.m4 +381 -0
- data/ext/ffi_c/libffi/autogen.sh +2 -0
- data/ext/ffi_c/libffi/configure.ac +148 -256
- data/ext/ffi_c/libffi/configure.host +265 -4
- data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
- data/ext/ffi_c/libffi/doc/libffi.texi +430 -45
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +207 -0
- data/ext/ffi_c/libffi/include/Makefile.am +3 -3
- data/ext/ffi_c/libffi/include/ffi.h.in +107 -50
- data/ext/ffi_c/libffi/include/ffi_cfi.h +55 -0
- data/ext/ffi_c/libffi/include/ffi_common.h +32 -11
- data/ext/ffi_c/libffi/libffi.map.in +80 -0
- data/ext/ffi_c/libffi/libffi.pc.in +3 -2
- data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +637 -0
- data/ext/ffi_c/libffi/libtool-ldflags +106 -0
- data/ext/ffi_c/libffi/libtool-version +1 -1
- data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
- data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +69 -0
- data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +13 -8
- data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +31 -104
- data/ext/ffi_c/libffi/m4/{ax_check_compiler_flags.m4 → ax_check_compile_flag.m4} +30 -34
- data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +32 -11
- data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +6 -5
- data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +31 -21
- data/ext/ffi_c/libffi/man/Makefile.am +2 -2
- data/ext/ffi_c/libffi/man/ffi.3 +10 -0
- data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +6 -4
- data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +73 -0
- data/ext/ffi_c/libffi/msvcc.sh +72 -9
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +941 -0
- data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +81 -0
- data/ext/ffi_c/libffi/src/aarch64/internal.h +67 -0
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +438 -0
- data/ext/ffi_c/libffi/src/alpha/ffi.c +335 -98
- data/ext/ffi_c/libffi/src/alpha/ffitarget.h +10 -1
- data/ext/ffi_c/libffi/src/alpha/internal.h +23 -0
- data/ext/ffi_c/libffi/src/alpha/osf.S +161 -266
- data/ext/ffi_c/libffi/src/arc/arcompact.S +135 -0
- data/ext/ffi_c/libffi/src/arc/ffi.c +266 -0
- data/ext/ffi_c/libffi/src/arc/ffitarget.h +53 -0
- data/ext/ffi_c/libffi/src/arm/ffi.c +597 -517
- data/ext/ffi_c/libffi/src/arm/ffitarget.h +24 -7
- data/ext/ffi_c/libffi/src/arm/internal.h +7 -0
- data/ext/ffi_c/libffi/src/arm/sysv.S +303 -417
- data/ext/ffi_c/libffi/src/avr32/ffitarget.h +6 -1
- data/ext/ffi_c/libffi/src/bfin/ffi.c +196 -0
- data/ext/ffi_c/libffi/src/bfin/ffitarget.h +43 -0
- data/ext/ffi_c/libffi/src/bfin/sysv.S +179 -0
- data/ext/ffi_c/libffi/src/closures.c +319 -44
- data/ext/ffi_c/libffi/src/cris/ffi.c +10 -7
- data/ext/ffi_c/libffi/src/cris/ffitarget.h +6 -1
- data/ext/ffi_c/libffi/src/debug.c +6 -1
- data/ext/ffi_c/libffi/src/dlmalloc.c +16 -11
- data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/frv/ffitarget.h +6 -1
- data/ext/ffi_c/libffi/src/ia64/ffi.c +11 -7
- data/ext/ffi_c/libffi/src/ia64/ffitarget.h +6 -1
- data/ext/ffi_c/libffi/src/java_raw_api.c +23 -5
- data/ext/ffi_c/libffi/src/m32r/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/m32r/ffitarget.h +6 -1
- data/ext/ffi_c/libffi/src/m68k/ffi.c +87 -13
- data/ext/ffi_c/libffi/src/m68k/ffitarget.h +6 -1
- data/ext/ffi_c/libffi/src/m68k/sysv.S +119 -32
- data/ext/ffi_c/libffi/src/m88k/ffi.c +400 -0
- data/ext/ffi_c/libffi/src/m88k/ffitarget.h +49 -0
- data/ext/ffi_c/libffi/src/m88k/obsd.S +209 -0
- data/ext/ffi_c/libffi/src/metag/ffi.c +330 -0
- data/ext/ffi_c/libffi/{fficonfig.hw → src/metag/ffitarget.h} +22 -26
- data/ext/ffi_c/libffi/src/metag/sysv.S +311 -0
- data/ext/ffi_c/libffi/src/microblaze/ffi.c +321 -0
- data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +53 -0
- data/ext/ffi_c/libffi/src/microblaze/sysv.S +302 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +95 -28
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +9 -2
- data/ext/ffi_c/libffi/src/mips/n32.S +126 -56
- data/ext/ffi_c/libffi/src/mips/o32.S +148 -27
- data/ext/ffi_c/libffi/src/moxie/eabi.S +55 -82
- data/ext/ffi_c/libffi/src/moxie/ffi.c +40 -44
- data/ext/ffi_c/libffi/src/moxie/ffitarget.h +52 -0
- data/ext/ffi_c/libffi/src/nios2/ffi.c +304 -0
- data/ext/ffi_c/libffi/src/nios2/ffitarget.h +52 -0
- data/ext/ffi_c/libffi/src/nios2/sysv.S +136 -0
- data/ext/ffi_c/libffi/src/or1k/ffi.c +328 -0
- data/ext/ffi_c/libffi/src/or1k/ffitarget.h +58 -0
- data/ext/ffi_c/libffi/src/or1k/sysv.S +107 -0
- data/ext/ffi_c/libffi/src/pa/ffitarget.h +8 -1
- data/ext/ffi_c/libffi/src/powerpc/aix.S +6 -6
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +3 -1
- data/ext/ffi_c/libffi/src/powerpc/asm.h +2 -2
- data/ext/ffi_c/libffi/src/powerpc/darwin.S +2 -7
- data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +22 -26
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +103 -1378
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +25 -25
- data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +945 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +94 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +100 -44
- data/ext/ffi_c/libffi/src/powerpc/linux64.S +100 -59
- data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +360 -108
- data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +138 -68
- data/ext/ffi_c/libffi/src/powerpc/sysv.S +68 -112
- data/ext/ffi_c/libffi/src/prep_cif.c +108 -24
- data/ext/ffi_c/libffi/src/raw_api.c +18 -5
- data/ext/ffi_c/libffi/src/s390/ffi.c +294 -318
- data/ext/ffi_c/libffi/src/s390/ffitarget.h +9 -1
- data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
- data/ext/ffi_c/libffi/src/s390/sysv.S +257 -366
- data/ext/ffi_c/libffi/src/sh/ffi.c +4 -3
- data/ext/ffi_c/libffi/src/sh/ffitarget.h +6 -1
- data/ext/ffi_c/libffi/src/sh64/ffi.c +3 -2
- data/ext/ffi_c/libffi/src/sh64/ffitarget.h +6 -1
- data/ext/ffi_c/libffi/src/sparc/ffi.c +326 -527
- data/ext/ffi_c/libffi/src/sparc/ffi64.c +608 -0
- data/ext/ffi_c/libffi/src/sparc/ffitarget.h +20 -7
- data/ext/ffi_c/libffi/src/sparc/internal.h +26 -0
- data/ext/ffi_c/libffi/src/sparc/v8.S +364 -234
- data/ext/ffi_c/libffi/src/sparc/v9.S +340 -207
- data/ext/ffi_c/libffi/src/tile/ffi.c +355 -0
- data/ext/ffi_c/libffi/src/tile/ffitarget.h +65 -0
- data/ext/ffi_c/libffi/src/tile/tile.S +360 -0
- data/ext/ffi_c/libffi/src/types.c +43 -14
- data/ext/ffi_c/libffi/src/vax/elfbsd.S +195 -0
- data/ext/ffi_c/libffi/src/vax/ffi.c +276 -0
- data/ext/ffi_c/libffi/src/vax/ffitarget.h +49 -0
- data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
- data/ext/ffi_c/libffi/src/x86/ffi.c +589 -500
- data/ext/ffi_c/libffi/src/x86/ffi64.c +338 -116
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +55 -35
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +287 -0
- data/ext/ffi_c/libffi/src/x86/internal.h +29 -0
- data/ext/ffi_c/libffi/src/x86/internal64.h +22 -0
- data/ext/ffi_c/libffi/src/x86/sysv.S +975 -400
- data/ext/ffi_c/libffi/src/x86/unix64.S +398 -299
- data/ext/ffi_c/libffi/src/x86/win64.S +222 -458
- data/ext/ffi_c/libffi/src/x86/win64_intel.S +237 -0
- data/ext/ffi_c/libffi/src/xtensa/ffi.c +298 -0
- data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +53 -0
- data/ext/ffi_c/libffi/src/xtensa/sysv.S +253 -0
- data/ext/ffi_c/libffi/stamp-h.in +1 -0
- data/ext/ffi_c/libffi/testsuite/Makefile.am +78 -73
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +120 -25
- data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +21 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +4 -6
- data/ext/ffi_c/libffi/testsuite/libffi.call/{closure_stdcall.c → closure_simple.c} +7 -16
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +5 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +5 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +4 -6
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +4 -6
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +10 -9
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +3 -3
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +10 -9
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_args.c +70 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c +55 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +11 -9
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_struct_va1.c +114 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar_va.c +44 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint_va.c +45 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulong_va.c +45 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +5 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort_va.c +44 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +2 -2
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +23 -40
- data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +3 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +6 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +4 -2
- data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +107 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +18 -19
- data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +6 -16
- data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +57 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +70 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +78 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +0 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +6 -6
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +8 -8
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +6 -6
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct11.c +121 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +5 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +5 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +5 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +5 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +6 -6
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +5 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +6 -6
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +6 -6
- data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +46 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +127 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +7 -7
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +7 -7
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +5 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +5 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +2 -2
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +49 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +49 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +55 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +9 -7
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +7 -7
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +7 -6
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +9 -8
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +9 -8
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +9 -9
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +9 -9
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +9 -8
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +9 -8
- data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +2 -2
- data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.call}/unwindtest.cc +3 -10
- data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.call}/unwindtest_ffi_call.cc +2 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +196 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +121 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +123 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +125 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +91 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +42 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +71 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +80 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +16 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +10 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.special/special.exp → libffi.complex/complex.exp} +9 -8
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +51 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +7 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +7 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +7 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +86 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +78 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +37 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +41 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +44 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +34 -0
- data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +28 -0
- data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +36 -0
- data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +19 -0
- data/ffi.gemspec +2 -2
- data/lib/ffi/enum.rb +124 -0
- data/lib/ffi/library.rb +65 -13
- data/lib/ffi/platform.rb +7 -2
- data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
- data/lib/ffi/platform/x86_64-windows/types.conf +113 -20
- data/lib/ffi/pointer.rb +1 -0
- data/lib/ffi/struct.rb +0 -2
- data/lib/ffi/version.rb +1 -1
- data/spec/ffi/bitmask_spec.rb +575 -0
- data/spec/ffi/fixtures/BitmaskTest.c +51 -0
- data/spec/ffi/rbx/memory_pointer_spec.rb +4 -0
- data/spec/ffi/struct_spec.rb +0 -4
- metadata +143 -51
- data/ext/ffi_c/libffi/Makefile.in +0 -1820
- data/ext/ffi_c/libffi/Makefile.vc +0 -141
- data/ext/ffi_c/libffi/Makefile.vc64 +0 -141
- data/ext/ffi_c/libffi/aclocal.m4 +0 -1873
- data/ext/ffi_c/libffi/build-ios.sh +0 -67
- data/ext/ffi_c/libffi/compile +0 -143
- data/ext/ffi_c/libffi/config.guess +0 -1501
- data/ext/ffi_c/libffi/config.sub +0 -1705
- data/ext/ffi_c/libffi/configure +0 -17191
- data/ext/ffi_c/libffi/depcomp +0 -630
- data/ext/ffi_c/libffi/doc/libffi.info +0 -593
- data/ext/ffi_c/libffi/doc/stamp-vti +0 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +0 -199
- data/ext/ffi_c/libffi/include/Makefile.in +0 -487
- data/ext/ffi_c/libffi/include/ffi.h.vc +0 -427
- data/ext/ffi_c/libffi/include/ffi.h.vc64 +0 -427
- data/ext/ffi_c/libffi/install-sh +0 -520
- data/ext/ffi_c/libffi/ltmain.sh +0 -9636
- data/ext/ffi_c/libffi/m4/libtool.m4 +0 -7831
- data/ext/ffi_c/libffi/m4/ltoptions.m4 +0 -369
- data/ext/ffi_c/libffi/m4/ltsugar.m4 +0 -123
- data/ext/ffi_c/libffi/m4/ltversion.m4 +0 -23
- data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +0 -98
- data/ext/ffi_c/libffi/man/Makefile.in +0 -466
- data/ext/ffi_c/libffi/mdate-sh +0 -201
- data/ext/ffi_c/libffi/missing +0 -376
- data/ext/ffi_c/libffi/src/arm/gentramp.sh +0 -118
- data/ext/ffi_c/libffi/src/arm/trampoline.S +0 -4450
- data/ext/ffi_c/libffi/src/x86/darwin.S +0 -444
- data/ext/ffi_c/libffi/src/x86/darwin64.S +0 -416
- data/ext/ffi_c/libffi/src/x86/freebsd.S +0 -458
- data/ext/ffi_c/libffi/src/x86/win32.S +0 -1065
- data/ext/ffi_c/libffi/testsuite/Makefile.in +0 -500
- data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +0 -300
- data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +0 -63
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +0 -44
- data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +0 -96
- data/ext/ffi_c/libffi/texinfo.tex +0 -7210
@@ -1,11 +1,272 @@
|
|
1
1
|
# configure.host
|
2
2
|
#
|
3
3
|
# This shell script handles all host based configuration for libffi.
|
4
|
-
#
|
4
|
+
#
|
5
5
|
|
6
6
|
# THIS TABLE IS SORTED. KEEP IT THAT WAY.
|
7
|
+
# Most of the time we can define all the variables all at once...
|
7
8
|
case "${host}" in
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
aarch64*-*-*)
|
10
|
+
TARGET=AARCH64; TARGETDIR=aarch64
|
11
|
+
SOURCES="ffi.c sysv.S"
|
12
|
+
;;
|
13
|
+
|
14
|
+
alpha*-*-*)
|
15
|
+
TARGET=ALPHA; TARGETDIR=alpha;
|
16
|
+
# Support 128-bit long double, changeable via command-line switch.
|
17
|
+
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
|
18
|
+
SOURCES="ffi.c osf.S"
|
19
|
+
;;
|
20
|
+
|
21
|
+
arc*-*-*)
|
22
|
+
TARGET=ARC; TARGETDIR=arc
|
23
|
+
SOURCES="ffi.c arcompact.S"
|
24
|
+
;;
|
25
|
+
|
26
|
+
arm*-*-*)
|
27
|
+
TARGET=ARM; TARGETDIR=arm
|
28
|
+
SOURCES="ffi.c sysv.S"
|
29
|
+
;;
|
30
|
+
|
31
|
+
avr32*-*-*)
|
32
|
+
TARGET=AVR32; TARGETDIR=avr32
|
33
|
+
SOURCES="ffi.c sysv.S"
|
34
|
+
;;
|
35
|
+
|
36
|
+
bfin*)
|
37
|
+
TARGET=BFIN; TARGETDIR=bfin
|
38
|
+
SOURCES="ffi.c sysv.S"
|
39
|
+
;;
|
40
|
+
|
41
|
+
cris-*-*)
|
42
|
+
TARGET=LIBFFI_CRIS; TARGETDIR=cris
|
43
|
+
SOURCES="ffi.c sysv.S"
|
44
|
+
;;
|
45
|
+
|
46
|
+
frv-*-*)
|
47
|
+
TARGET=FRV; TARGETDIR=frv
|
48
|
+
SOURCES="ffi.c eabi.S"
|
49
|
+
;;
|
50
|
+
|
51
|
+
hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
|
52
|
+
TARGET=PA_LINUX; TARGETDIR=pa
|
53
|
+
SOURCES="ffi.c linux.S"
|
54
|
+
;;
|
55
|
+
hppa*64-*-hpux*)
|
56
|
+
TARGET=PA64_HPUX; TARGETDIR=pa
|
57
|
+
;;
|
58
|
+
hppa*-*-hpux*)
|
59
|
+
TARGET=PA_HPUX; TARGETDIR=pa
|
60
|
+
SOURCES="ffi.c hpux32.S"
|
61
|
+
;;
|
62
|
+
|
63
|
+
i?86-*-freebsd* | i?86-*-openbsd*)
|
64
|
+
TARGET=X86_FREEBSD; TARGETDIR=x86
|
65
|
+
;;
|
66
|
+
|
67
|
+
i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix* \
|
68
|
+
| x86_64-*-cygwin* | x86_64-*-mingw* | x86_64-*-win* )
|
69
|
+
TARGETDIR=x86
|
70
|
+
if test $ac_cv_sizeof_size_t = 4; then
|
71
|
+
TARGET=X86_WIN32
|
72
|
+
else
|
73
|
+
TARGET=X86_WIN64
|
74
|
+
fi
|
75
|
+
if test "${ax_cv_c_compiler_vendor}" = "microsoft"; then
|
76
|
+
MSVC=1
|
77
|
+
if test $ac_cv_sizeof_size_t = 4; then
|
78
|
+
# libffi does not support microsoft tools for 32-bit windows
|
79
|
+
# hosts. Try porting src/x86/sysv.S to intel assembly
|
80
|
+
# format.
|
81
|
+
UNSUPPORTED=1
|
82
|
+
fi
|
83
|
+
fi
|
84
|
+
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
|
85
|
+
# We must also check with_cross_host to decide if this is a native
|
86
|
+
# or cross-build and select where to install dlls appropriately.
|
87
|
+
if test -n "$with_cross_host" &&
|
88
|
+
test x"$with_cross_host" != x"no"; then
|
89
|
+
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
|
90
|
+
else
|
91
|
+
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
|
92
|
+
fi
|
93
|
+
;;
|
94
|
+
|
95
|
+
i?86-*-darwin* | x86_64-*-darwin*)
|
96
|
+
TARGETDIR=x86
|
97
|
+
if test $ac_cv_sizeof_size_t = 4; then
|
98
|
+
TARGET=X86_DARWIN
|
99
|
+
else
|
100
|
+
TARGET=X86_64
|
101
|
+
fi
|
102
|
+
;;
|
103
|
+
|
104
|
+
i?86-*-* | x86_64-*-* | amd64-*)
|
105
|
+
TARGETDIR=x86
|
106
|
+
if test $ac_cv_sizeof_size_t = 4; then
|
107
|
+
case "$host" in
|
108
|
+
x86_64-*x32|x86_64-x32-*)
|
109
|
+
TARGET=X86_64
|
110
|
+
;;
|
111
|
+
*)
|
112
|
+
TARGET=X86
|
113
|
+
;;
|
114
|
+
esac
|
115
|
+
else
|
116
|
+
TARGET=X86_64;
|
117
|
+
fi
|
118
|
+
;;
|
119
|
+
|
120
|
+
ia64*-*-*)
|
121
|
+
TARGET=IA64; TARGETDIR=ia64
|
122
|
+
SOURCES="ffi.c unix.S"
|
123
|
+
;;
|
124
|
+
|
125
|
+
m32r*-*-*)
|
126
|
+
TARGET=M32R; TARGETDIR=m32r
|
127
|
+
SOURCES="ffi.c sysv.S"
|
128
|
+
;;
|
129
|
+
|
130
|
+
m68k-*-*)
|
131
|
+
TARGET=M68K; TARGETDIR=m68k
|
132
|
+
SOURCES="ffi.c sysv.S"
|
133
|
+
;;
|
134
|
+
|
135
|
+
m88k-*-*)
|
136
|
+
TARGET=M88K; TARGETDIR=m88k
|
137
|
+
SOURCES="ffi.c obsd.S"
|
138
|
+
;;
|
139
|
+
|
140
|
+
microblaze*-*-*)
|
141
|
+
TARGET=MICROBLAZE; TARGETDIR=microblaze
|
142
|
+
SOURCES="ffi.c sysv.S"
|
143
|
+
;;
|
144
|
+
|
145
|
+
moxie-*-*)
|
146
|
+
TARGET=MOXIE; TARGETDIR=moxie
|
147
|
+
SOURCES="ffi.c eabi.S"
|
148
|
+
;;
|
149
|
+
|
150
|
+
metag-*-*)
|
151
|
+
TARGET=METAG; TARGETDIR=metag
|
152
|
+
SOURCES="ffi.c sysv.S"
|
153
|
+
;;
|
154
|
+
|
155
|
+
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
|
156
|
+
TARGET=MIPS; TARGETDIR=mips
|
157
|
+
;;
|
158
|
+
mips*-*linux* | mips*-*-openbsd*)
|
159
|
+
# Support 128-bit long double for NewABI.
|
160
|
+
HAVE_LONG_DOUBLE='defined(__mips64)'
|
161
|
+
TARGET=MIPS; TARGETDIR=mips
|
162
|
+
;;
|
163
|
+
|
164
|
+
nios2*-linux*)
|
165
|
+
TARGET=NIOS2; TARGETDIR=nios2
|
166
|
+
SOURCES="ffi.c sysv.S"
|
167
|
+
;;
|
168
|
+
|
169
|
+
or1k*-linux*)
|
170
|
+
TARGET=OR1K; TARGETDIR=or1k
|
171
|
+
SOURCES="ffi.c sysv.S"
|
172
|
+
;;
|
173
|
+
|
174
|
+
powerpc*-*-linux* | powerpc-*-sysv*)
|
175
|
+
TARGET=POWERPC; TARGETDIR=powerpc
|
176
|
+
HAVE_LONG_DOUBLE_VARIANT=1
|
177
|
+
;;
|
178
|
+
powerpc-*-amigaos*)
|
179
|
+
TARGET=POWERPC; TARGETDIR=powerpc
|
180
|
+
;;
|
181
|
+
powerpc-*-beos*)
|
182
|
+
TARGET=POWERPC; TARGETDIR=powerpc
|
183
|
+
;;
|
184
|
+
powerpc-*-darwin* | powerpc64-*-darwin*)
|
185
|
+
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
|
186
|
+
;;
|
187
|
+
powerpc-*-aix* | rs6000-*-aix*)
|
188
|
+
TARGET=POWERPC_AIX; TARGETDIR=powerpc
|
189
|
+
;;
|
190
|
+
powerpc-*-freebsd* | powerpc-*-openbsd* | powerpc-*-netbsd*)
|
191
|
+
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
|
192
|
+
HAVE_LONG_DOUBLE_VARIANT=1
|
193
|
+
;;
|
194
|
+
powerpc64-*-freebsd*)
|
195
|
+
TARGET=POWERPC; TARGETDIR=powerpc
|
196
|
+
;;
|
197
|
+
powerpc*-*-rtems*)
|
198
|
+
TARGET=POWERPC; TARGETDIR=powerpc
|
199
|
+
;;
|
200
|
+
|
201
|
+
s390-*-* | s390x-*-*)
|
202
|
+
TARGET=S390; TARGETDIR=s390
|
203
|
+
SOURCES="ffi.c sysv.S"
|
204
|
+
;;
|
205
|
+
|
206
|
+
sh-*-* | sh[34]*-*-*)
|
207
|
+
TARGET=SH; TARGETDIR=sh
|
208
|
+
SOURCES="ffi.c sysv.S"
|
209
|
+
;;
|
210
|
+
sh64-*-* | sh5*-*-*)
|
211
|
+
TARGET=SH64; TARGETDIR=sh64
|
212
|
+
SOURCES="ffi.c sysv.S"
|
213
|
+
;;
|
214
|
+
|
215
|
+
sparc*-*-*)
|
216
|
+
TARGET=SPARC; TARGETDIR=sparc
|
217
|
+
SOURCES="ffi.c ffi64.c v8.S v9.S"
|
218
|
+
;;
|
219
|
+
|
220
|
+
tile*-*)
|
221
|
+
TARGET=TILE; TARGETDIR=tile
|
222
|
+
SOURCES="ffi.c tile.S"
|
223
|
+
;;
|
224
|
+
|
225
|
+
vax-*-*)
|
226
|
+
TARGET=VAX; TARGETDIR=vax
|
227
|
+
SOURCES="ffi.c elfbsd.S"
|
228
|
+
;;
|
229
|
+
|
230
|
+
xtensa*-*)
|
231
|
+
TARGET=XTENSA; TARGETDIR=xtensa
|
232
|
+
SOURCES="ffi.c sysv.S"
|
233
|
+
;;
|
234
|
+
esac
|
235
|
+
|
236
|
+
# ... but some of the cases above share configury.
|
237
|
+
case "${TARGET}" in
|
238
|
+
MIPS)
|
239
|
+
SOURCES="ffi.c o32.S n32.S"
|
240
|
+
;;
|
241
|
+
POWERPC)
|
242
|
+
SOURCES="ffi.c ffi_sysv.c ffi_linux64.c sysv.S ppc_closure.S"
|
243
|
+
SOURCES="${SOURCES} linux64.S linux64_closure.S"
|
244
|
+
;;
|
245
|
+
POWERPC_AIX)
|
246
|
+
SOURCES="ffi_darwin.c aix.S aix_closure.S"
|
247
|
+
;;
|
248
|
+
POWERPC_DARWIN)
|
249
|
+
SOURCES="ffi_darwin.c darwin.S darwin_closure.S"
|
250
|
+
;;
|
251
|
+
POWERPC_FREEBSD)
|
252
|
+
SOURCES="ffi.c ffi_sysv.c sysv.S ppc_closure.S"
|
253
|
+
;;
|
254
|
+
X86 | X86_DARWIN | X86_FREEBSD | X86_WIN32)
|
255
|
+
SOURCES="ffi.c sysv.S"
|
256
|
+
;;
|
257
|
+
X86_64)
|
258
|
+
SOURCES="ffi64.c unix64.S ffiw64.c win64.S"
|
259
|
+
;;
|
260
|
+
X86_WIN64)
|
261
|
+
if test "$MSVC" = 1; then
|
262
|
+
SOURCES="ffiw64.c win64_intel.S"
|
263
|
+
else
|
264
|
+
SOURCES="ffiw64.c win64.S"
|
265
|
+
fi
|
266
|
+
;;
|
11
267
|
esac
|
268
|
+
|
269
|
+
# If we failed to configure SOURCES, we can't do anything.
|
270
|
+
if test -z "${SOURCES}"; then
|
271
|
+
UNSUPPORTED=1
|
272
|
+
fi
|
@@ -19,7 +19,7 @@
|
|
19
19
|
This manual is for Libffi, a portable foreign-function interface
|
20
20
|
library.
|
21
21
|
|
22
|
-
Copyright @copyright{} 2008, 2010 Red Hat, Inc.
|
22
|
+
Copyright @copyright{} 2008, 2010, 2011 Red Hat, Inc.
|
23
23
|
|
24
24
|
@quotation
|
25
25
|
Permission is granted to copy, distribute and/or modify this document
|
@@ -107,6 +107,7 @@ values passed between the two languages.
|
|
107
107
|
* Multiple ABIs:: Different passing styles on one platform.
|
108
108
|
* The Closure API:: Writing a generic function.
|
109
109
|
* Closure Example:: A closure example.
|
110
|
+
* Thread Safety:: Thread safety.
|
110
111
|
@end menu
|
111
112
|
|
112
113
|
|
@@ -133,8 +134,6 @@ This initializes @var{cif} according to the given parameters.
|
|
133
134
|
you want. @ref{Multiple ABIs} for more information.
|
134
135
|
|
135
136
|
@var{nargs} is the number of arguments that this function accepts.
|
136
|
-
@samp{libffi} does not yet handle varargs functions; see @ref{Missing
|
137
|
-
Features} for more information.
|
138
137
|
|
139
138
|
@var{rtype} is a pointer to an @code{ffi_type} structure that
|
140
139
|
describes the return type of the function. @xref{Types}.
|
@@ -150,6 +149,34 @@ objects is incorrect; or @code{FFI_BAD_ABI} if the @var{abi} parameter
|
|
150
149
|
is invalid.
|
151
150
|
@end defun
|
152
151
|
|
152
|
+
If the function being called is variadic (varargs) then
|
153
|
+
@code{ffi_prep_cif_var} must be used instead of @code{ffi_prep_cif}.
|
154
|
+
|
155
|
+
@findex ffi_prep_cif_var
|
156
|
+
@defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nfixedargs}, unsigned int @var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
|
157
|
+
This initializes @var{cif} according to the given parameters for
|
158
|
+
a call to a variadic function. In general its operation is the
|
159
|
+
same as for @code{ffi_prep_cif} except that:
|
160
|
+
|
161
|
+
@var{nfixedargs} is the number of fixed arguments, prior to any
|
162
|
+
variadic arguments. It must be greater than zero.
|
163
|
+
|
164
|
+
@var{ntotalargs} the total number of arguments, including variadic
|
165
|
+
and fixed arguments. @var{argtypes} must have this many elements.
|
166
|
+
|
167
|
+
Note that, different cif's must be prepped for calls to the same
|
168
|
+
function when different numbers of arguments are passed.
|
169
|
+
|
170
|
+
Also note that a call to @code{ffi_prep_cif_var} with
|
171
|
+
@var{nfixedargs}=@var{nototalargs} is NOT equivalent to a call to
|
172
|
+
@code{ffi_prep_cif}.
|
173
|
+
|
174
|
+
@end defun
|
175
|
+
|
176
|
+
Note that the resulting @code{ffi_cif} holds pointers to all the
|
177
|
+
@code{ffi_type} objects that were used during initialization. You
|
178
|
+
must ensure that these type objects have a lifetime at least as long
|
179
|
+
as that of the @code{ffi_cif}.
|
153
180
|
|
154
181
|
To call a function using an initialized @code{ffi_cif}, use the
|
155
182
|
@code{ffi_call} function:
|
@@ -162,11 +189,21 @@ This calls the function @var{fn} according to the description given in
|
|
162
189
|
|
163
190
|
@var{rvalue} is a pointer to a chunk of memory that will hold the
|
164
191
|
result of the function call. This must be large enough to hold the
|
165
|
-
result
|
192
|
+
result, no smaller than the system register size (generally 32 or 64
|
193
|
+
bits), and must be suitably aligned; it is the caller's responsibility
|
166
194
|
to ensure this. If @var{cif} declares that the function returns
|
167
195
|
@code{void} (using @code{ffi_type_void}), then @var{rvalue} is
|
168
|
-
ignored.
|
169
|
-
|
196
|
+
ignored.
|
197
|
+
|
198
|
+
In most situations, @samp{libffi} will handle promotion according to
|
199
|
+
the ABI. However, for historical reasons, there is a special case
|
200
|
+
with return values that must be handled by your code. In particular,
|
201
|
+
for integral (not @code{struct}) types that are narrower than the
|
202
|
+
system register size, the return value will be widened by
|
203
|
+
@samp{libffi}. @samp{libffi} provides a type, @code{ffi_arg}, that
|
204
|
+
can be used as the return type. For example, if the CIF was defined
|
205
|
+
with a return type of @code{char}, @samp{libffi} will try to store a
|
206
|
+
full @code{ffi_arg} into the return value.
|
170
207
|
|
171
208
|
@var{avalues} is a vector of @code{void *} pointers that point to the
|
172
209
|
memory locations holding the argument values for a call. If @var{cif}
|
@@ -174,6 +211,13 @@ declares that the function has no arguments (i.e., @var{nargs} was 0),
|
|
174
211
|
then @var{avalues} is ignored. Note that argument values may be
|
175
212
|
modified by the callee (for instance, structs passed by value); the
|
176
213
|
burden of copying pass-by-value arguments is placed on the caller.
|
214
|
+
|
215
|
+
Note that while the return value must be register-sized, arguments
|
216
|
+
should exactly match their declared type. For example, if an argument
|
217
|
+
is a @code{short}, then the entry in @var{avalues} should point to an
|
218
|
+
object declared as @code{short}; but if the return type is
|
219
|
+
@code{short}, then @var{rvalue} should point to an object declared as
|
220
|
+
a larger type -- usually @code{ffi_arg}.
|
177
221
|
@end defun
|
178
222
|
|
179
223
|
|
@@ -192,7 +236,7 @@ int main()
|
|
192
236
|
ffi_type *args[1];
|
193
237
|
void *values[1];
|
194
238
|
char *s;
|
195
|
-
|
239
|
+
ffi_arg rc;
|
196
240
|
|
197
241
|
/* Initialize the argument info vectors */
|
198
242
|
args[0] = &ffi_type_pointer;
|
@@ -200,7 +244,7 @@ int main()
|
|
200
244
|
|
201
245
|
/* Initialize the cif */
|
202
246
|
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
203
|
-
&
|
247
|
+
&ffi_type_sint, args) == FFI_OK)
|
204
248
|
@{
|
205
249
|
s = "Hello World!";
|
206
250
|
ffi_call(&cif, puts, &rc, values);
|
@@ -224,7 +268,11 @@ int main()
|
|
224
268
|
@menu
|
225
269
|
* Primitive Types:: Built-in types.
|
226
270
|
* Structures:: Structure types.
|
271
|
+
* Size and Alignment:: Size and alignment of types.
|
272
|
+
* Arrays Unions Enums:: Arrays, unions, and enumerations.
|
227
273
|
* Type Example:: Structure type example.
|
274
|
+
* Complex:: Complex types.
|
275
|
+
* Complex Type Example:: Complex type example.
|
228
276
|
@end menu
|
229
277
|
|
230
278
|
@node Primitive Types
|
@@ -323,6 +371,20 @@ On other platforms, it is not.
|
|
323
371
|
@tindex ffi_type_pointer
|
324
372
|
A generic @code{void *} pointer. You should use this for all
|
325
373
|
pointers, regardless of their real type.
|
374
|
+
|
375
|
+
@item ffi_type_complex_float
|
376
|
+
@tindex ffi_type_complex_float
|
377
|
+
The C @code{_Complex float} type.
|
378
|
+
|
379
|
+
@item ffi_type_complex_double
|
380
|
+
@tindex ffi_type_complex_double
|
381
|
+
The C @code{_Complex double} type.
|
382
|
+
|
383
|
+
@item ffi_type_complex_longdouble
|
384
|
+
@tindex ffi_type_complex_longdouble
|
385
|
+
The C @code{_Complex long double} type.
|
386
|
+
On platforms that have a C @code{long double} type, this is defined.
|
387
|
+
On other platforms, it is not.
|
326
388
|
@end table
|
327
389
|
|
328
390
|
Each of these is of type @code{ffi_type}, so you must take the address
|
@@ -332,13 +394,12 @@ when passing to @code{ffi_prep_cif}.
|
|
332
394
|
@node Structures
|
333
395
|
@subsection Structures
|
334
396
|
|
335
|
-
|
336
|
-
bit-fields, it is perfectly happy passing structures back and forth.
|
397
|
+
@samp{libffi} is perfectly happy passing structures back and forth.
|
337
398
|
You must first describe the structure to @samp{libffi} by creating a
|
338
399
|
new @code{ffi_type} object for it.
|
339
400
|
|
340
401
|
@tindex ffi_type
|
341
|
-
@deftp ffi_type
|
402
|
+
@deftp {Data type} ffi_type
|
342
403
|
The @code{ffi_type} has the following members:
|
343
404
|
@table @code
|
344
405
|
@item size_t size
|
@@ -353,9 +414,166 @@ For a structure, this should be set to @code{FFI_TYPE_STRUCT}.
|
|
353
414
|
@item ffi_type **elements
|
354
415
|
This is a @samp{NULL}-terminated array of pointers to @code{ffi_type}
|
355
416
|
objects. There is one element per field of the struct.
|
417
|
+
|
418
|
+
Note that @samp{libffi} has no special support for bit-fields. You
|
419
|
+
must manage these manually.
|
356
420
|
@end table
|
357
421
|
@end deftp
|
358
422
|
|
423
|
+
The @code{size} and @code{alignment} fields will be filled in by
|
424
|
+
@code{ffi_prep_cif} or @code{ffi_prep_cif_var}, as needed.
|
425
|
+
|
426
|
+
@node Size and Alignment
|
427
|
+
@subsection Size and Alignment
|
428
|
+
|
429
|
+
@code{libffi} will set the @code{size} and @code{alignment} fields of
|
430
|
+
an @code{ffi_type} object for you. It does so using its knowledge of
|
431
|
+
the ABI.
|
432
|
+
|
433
|
+
You might expect that you can simply read these fields for a type that
|
434
|
+
has been laid out by @code{libffi}. However, there are some caveats.
|
435
|
+
|
436
|
+
@itemize @bullet
|
437
|
+
@item
|
438
|
+
The size or alignment of some of the built-in types may vary depending
|
439
|
+
on the chosen ABI.
|
440
|
+
|
441
|
+
@item
|
442
|
+
The size and alignment of a new structure type will not be set by
|
443
|
+
@code{libffi} until it has been passed to @code{ffi_prep_cif} or
|
444
|
+
@code{ffi_get_struct_offsets}.
|
445
|
+
|
446
|
+
@item
|
447
|
+
A structure type cannot be shared across ABIs. Instead each ABI needs
|
448
|
+
its own copy of the structure type.
|
449
|
+
@end itemize
|
450
|
+
|
451
|
+
So, before examining these fields, it is safest to pass the
|
452
|
+
@code{ffi_type} object to @code{ffi_prep_cif} or
|
453
|
+
@code{ffi_get_struct_offsets} first. This function will do all the
|
454
|
+
needed setup.
|
455
|
+
|
456
|
+
@example
|
457
|
+
ffi_type *desired_type;
|
458
|
+
ffi_abi desired_abi;
|
459
|
+
@dots{}
|
460
|
+
ffi_cif cif;
|
461
|
+
if (ffi_prep_cif (&cif, desired_abi, 0, desired_type, NULL) == FFI_OK)
|
462
|
+
@{
|
463
|
+
size_t size = desired_type->size;
|
464
|
+
unsigned short alignment = desired_type->alignment;
|
465
|
+
@}
|
466
|
+
@end example
|
467
|
+
|
468
|
+
@code{libffi} also provides a way to get the offsets of the members of
|
469
|
+
a structure.
|
470
|
+
|
471
|
+
@findex ffi_get_struct_offsets
|
472
|
+
@defun ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets)
|
473
|
+
Compute the offset of each element of the given structure type.
|
474
|
+
@var{abi} is the ABI to use; this is needed because in some cases the
|
475
|
+
layout depends on the ABI.
|
476
|
+
|
477
|
+
@var{offsets} is an out parameter. The caller is responsible for
|
478
|
+
providing enough space for all the results to be written -- one
|
479
|
+
element per element type in @var{struct_type}. If @var{offsets} is
|
480
|
+
@code{NULL}, then the type will be laid out but not otherwise
|
481
|
+
modified. This can be useful for accessing the type's size or layout,
|
482
|
+
as mentioned above.
|
483
|
+
|
484
|
+
This function returns @code{FFI_OK} on success; @code{FFI_BAD_ABI} if
|
485
|
+
@var{abi} is invalid; or @code{FFI_BAD_TYPEDEF} if @var{struct_type}
|
486
|
+
is invalid in some way. Note that only @code{FFI_STRUCT} types are
|
487
|
+
valid here.
|
488
|
+
@end defun
|
489
|
+
|
490
|
+
@node Arrays Unions Enums
|
491
|
+
@subsection Arrays, Unions, and Enumerations
|
492
|
+
|
493
|
+
@subsubsection Arrays
|
494
|
+
|
495
|
+
@samp{libffi} does not have direct support for arrays or unions.
|
496
|
+
However, they can be emulated using structures.
|
497
|
+
|
498
|
+
To emulate an array, simply create an @code{ffi_type} using
|
499
|
+
@code{FFI_TYPE_STRUCT} with as many members as there are elements in
|
500
|
+
the array.
|
501
|
+
|
502
|
+
@example
|
503
|
+
ffi_type array_type;
|
504
|
+
ffi_type **elements
|
505
|
+
int i;
|
506
|
+
|
507
|
+
elements = malloc ((n + 1) * sizeof (ffi_type *));
|
508
|
+
for (i = 0; i < n; ++i)
|
509
|
+
elements[i] = array_element_type;
|
510
|
+
elements[n] = NULL;
|
511
|
+
|
512
|
+
array_type.size = array_type.alignment = 0;
|
513
|
+
array_type.type = FFI_TYPE_STRUCT;
|
514
|
+
array_type.elements = elements;
|
515
|
+
@end example
|
516
|
+
|
517
|
+
Note that arrays cannot be passed or returned by value in C --
|
518
|
+
structure types created like this should only be used to refer to
|
519
|
+
members of real @code{FFI_TYPE_STRUCT} objects.
|
520
|
+
|
521
|
+
However, a phony array type like this will not cause any errors from
|
522
|
+
@samp{libffi} if you use it as an argument or return type. This may
|
523
|
+
be confusing.
|
524
|
+
|
525
|
+
@subsubsection Unions
|
526
|
+
|
527
|
+
A union can also be emulated using @code{FFI_TYPE_STRUCT}. In this
|
528
|
+
case, however, you must make sure that the size and alignment match
|
529
|
+
the real requirements of the union.
|
530
|
+
|
531
|
+
One simple way to do this is to ensue that each element type is laid
|
532
|
+
out. Then, give the new structure type a single element; the size of
|
533
|
+
the largest element; and the largest alignment seen as well.
|
534
|
+
|
535
|
+
This example uses the @code{ffi_prep_cif} trick to ensure that each
|
536
|
+
element type is laid out.
|
537
|
+
|
538
|
+
@example
|
539
|
+
ffi_abi desired_abi;
|
540
|
+
ffi_type union_type;
|
541
|
+
ffi_type **union_elements;
|
542
|
+
|
543
|
+
int i;
|
544
|
+
ffi_type element_types[2];
|
545
|
+
|
546
|
+
element_types[1] = NULL;
|
547
|
+
|
548
|
+
union_type.size = union_type.alignment = 0;
|
549
|
+
union_type.type = FFI_TYPE_STRUCT;
|
550
|
+
union_type.elements = element_types;
|
551
|
+
|
552
|
+
for (i = 0; union_elements[i]; ++i)
|
553
|
+
@{
|
554
|
+
ffi_cif cif;
|
555
|
+
if (ffi_prep_cif (&cif, desired_abi, 0, union_elements[i], NULL) == FFI_OK)
|
556
|
+
@{
|
557
|
+
if (union_elements[i]->size > union_type.size)
|
558
|
+
@{
|
559
|
+
union_type.size = union_elements[i];
|
560
|
+
size = union_elements[i]->size;
|
561
|
+
@}
|
562
|
+
if (union_elements[i]->alignment > union_type.alignment)
|
563
|
+
union_type.alignment = union_elements[i]->alignment;
|
564
|
+
@}
|
565
|
+
@}
|
566
|
+
@end example
|
567
|
+
|
568
|
+
@subsubsection Enumerations
|
569
|
+
|
570
|
+
@code{libffi} does not have any special support for C @code{enum}s.
|
571
|
+
Although any given @code{enum} is implemented using a specific
|
572
|
+
underlying integral type, exactly which type will be used cannot be
|
573
|
+
determined by @code{libffi} -- it may depend on the values in the
|
574
|
+
enumeration or on compiler flags such as @option{-fshort-enums}.
|
575
|
+
@xref{Structures unions enumerations and bit-fields implementation, , , gcc},
|
576
|
+
for more information about how GCC handles enumerations.
|
359
577
|
|
360
578
|
@node Type Example
|
361
579
|
@subsection Type Example
|
@@ -392,6 +610,7 @@ Here is the corresponding code to describe this struct to
|
|
392
610
|
int i;
|
393
611
|
|
394
612
|
tm_type.size = tm_type.alignment = 0;
|
613
|
+
tm_type.type = FFI_TYPE_STRUCT;
|
395
614
|
tm_type.elements = &tm_type_elements;
|
396
615
|
|
397
616
|
for (i = 0; i < 9; i++)
|
@@ -406,6 +625,135 @@ Here is the corresponding code to describe this struct to
|
|
406
625
|
@}
|
407
626
|
@end example
|
408
627
|
|
628
|
+
@node Complex
|
629
|
+
@subsection Complex Types
|
630
|
+
|
631
|
+
@samp{libffi} supports the complex types defined by the C99
|
632
|
+
standard (@code{_Complex float}, @code{_Complex double} and
|
633
|
+
@code{_Complex long double} with the built-in type descriptors
|
634
|
+
@code{ffi_type_complex_float}, @code{ffi_type_complex_double} and
|
635
|
+
@code{ffi_type_complex_longdouble}.
|
636
|
+
|
637
|
+
Custom complex types like @code{_Complex int} can also be used.
|
638
|
+
An @code{ffi_type} object has to be defined to describe the
|
639
|
+
complex type to @samp{libffi}.
|
640
|
+
|
641
|
+
@tindex ffi_type
|
642
|
+
@deftp {Data type} ffi_type
|
643
|
+
@table @code
|
644
|
+
@item size_t size
|
645
|
+
This must be manually set to the size of the complex type.
|
646
|
+
|
647
|
+
@item unsigned short alignment
|
648
|
+
This must be manually set to the alignment of the complex type.
|
649
|
+
|
650
|
+
@item unsigned short type
|
651
|
+
For a complex type, this must be set to @code{FFI_TYPE_COMPLEX}.
|
652
|
+
|
653
|
+
@item ffi_type **elements
|
654
|
+
|
655
|
+
This is a @samp{NULL}-terminated array of pointers to
|
656
|
+
@code{ffi_type} objects. The first element is set to the
|
657
|
+
@code{ffi_type} of the complex's base type. The second element
|
658
|
+
must be set to @code{NULL}.
|
659
|
+
@end table
|
660
|
+
@end deftp
|
661
|
+
|
662
|
+
The section @ref{Complex Type Example} shows a way to determine
|
663
|
+
the @code{size} and @code{alignment} members in a platform
|
664
|
+
independent way.
|
665
|
+
|
666
|
+
For platforms that have no complex support in @code{libffi} yet,
|
667
|
+
the functions @code{ffi_prep_cif} and @code{ffi_prep_args} abort
|
668
|
+
the program if they encounter a complex type.
|
669
|
+
|
670
|
+
@node Complex Type Example
|
671
|
+
@subsection Complex Type Example
|
672
|
+
|
673
|
+
This example demonstrates how to use complex types:
|
674
|
+
|
675
|
+
@example
|
676
|
+
#include <stdio.h>
|
677
|
+
#include <ffi.h>
|
678
|
+
#include <complex.h>
|
679
|
+
|
680
|
+
void complex_fn(_Complex float cf,
|
681
|
+
_Complex double cd,
|
682
|
+
_Complex long double cld)
|
683
|
+
@{
|
684
|
+
printf("cf=%f+%fi\ncd=%f+%fi\ncld=%f+%fi\n",
|
685
|
+
(float)creal (cf), (float)cimag (cf),
|
686
|
+
(float)creal (cd), (float)cimag (cd),
|
687
|
+
(float)creal (cld), (float)cimag (cld));
|
688
|
+
@}
|
689
|
+
|
690
|
+
int main()
|
691
|
+
@{
|
692
|
+
ffi_cif cif;
|
693
|
+
ffi_type *args[3];
|
694
|
+
void *values[3];
|
695
|
+
_Complex float cf;
|
696
|
+
_Complex double cd;
|
697
|
+
_Complex long double cld;
|
698
|
+
|
699
|
+
/* Initialize the argument info vectors */
|
700
|
+
args[0] = &ffi_type_complex_float;
|
701
|
+
args[1] = &ffi_type_complex_double;
|
702
|
+
args[2] = &ffi_type_complex_longdouble;
|
703
|
+
values[0] = &cf;
|
704
|
+
values[1] = &cd;
|
705
|
+
values[2] = &cld;
|
706
|
+
|
707
|
+
/* Initialize the cif */
|
708
|
+
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
|
709
|
+
&ffi_type_void, args) == FFI_OK)
|
710
|
+
@{
|
711
|
+
cf = 1.0 + 20.0 * I;
|
712
|
+
cd = 300.0 + 4000.0 * I;
|
713
|
+
cld = 50000.0 + 600000.0 * I;
|
714
|
+
/* Call the function */
|
715
|
+
ffi_call(&cif, (void (*)(void))complex_fn, 0, values);
|
716
|
+
@}
|
717
|
+
|
718
|
+
return 0;
|
719
|
+
@}
|
720
|
+
@end example
|
721
|
+
|
722
|
+
This is an example for defining a custom complex type descriptor
|
723
|
+
for compilers that support them:
|
724
|
+
|
725
|
+
@example
|
726
|
+
/*
|
727
|
+
* This macro can be used to define new complex type descriptors
|
728
|
+
* in a platform independent way.
|
729
|
+
*
|
730
|
+
* name: Name of the new descriptor is ffi_type_complex_<name>.
|
731
|
+
* type: The C base type of the complex type.
|
732
|
+
*/
|
733
|
+
#define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \
|
734
|
+
static ffi_type *ffi_elements_complex_##name [2] = @{ \
|
735
|
+
(ffi_type *)(&ffitype), NULL \
|
736
|
+
@}; \
|
737
|
+
struct struct_align_complex_##name @{ \
|
738
|
+
char c; \
|
739
|
+
_Complex type x; \
|
740
|
+
@}; \
|
741
|
+
ffi_type ffi_type_complex_##name = @{ \
|
742
|
+
sizeof(_Complex type), \
|
743
|
+
offsetof(struct struct_align_complex_##name, x), \
|
744
|
+
FFI_TYPE_COMPLEX, \
|
745
|
+
(ffi_type **)ffi_elements_complex_##name \
|
746
|
+
@}
|
747
|
+
|
748
|
+
/* Define new complex type descriptors using the macro: */
|
749
|
+
/* ffi_type_complex_sint */
|
750
|
+
FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint);
|
751
|
+
/* ffi_type_complex_uchar */
|
752
|
+
FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8);
|
753
|
+
@end example
|
754
|
+
|
755
|
+
The new type descriptors can then be used like one of the built-in
|
756
|
+
type descriptors in the previous example.
|
409
757
|
|
410
758
|
@node Multiple ABIs
|
411
759
|
@section Multiple ABIs
|
@@ -462,30 +810,47 @@ the closure function:
|
|
462
810
|
|
463
811
|
@findex ffi_prep_closure_loc
|
464
812
|
@defun ffi_status ffi_prep_closure_loc (ffi_closure *@var{closure}, ffi_cif *@var{cif}, void (*@var{fun}) (ffi_cif *@var{cif}, void *@var{ret}, void **@var{args}, void *@var{user_data}), void *@var{user_data}, void *@var{codeloc})
|
465
|
-
Prepare a closure function.
|
813
|
+
Prepare a closure function. The arguments to
|
814
|
+
@code{ffi_prep_closure_loc} are:
|
466
815
|
|
467
|
-
@
|
468
|
-
|
816
|
+
@table @var
|
817
|
+
@item closure
|
818
|
+
The address of a @code{ffi_closure} object; this is the writable
|
819
|
+
address returned by @code{ffi_closure_alloc}.
|
469
820
|
|
470
|
-
@
|
821
|
+
@item cif
|
822
|
+
The @code{ffi_cif} describing the function parameters. Note that this
|
823
|
+
object, and the types to which it refers, must be kept alive until the
|
824
|
+
closure itself is freed.
|
471
825
|
|
472
|
-
@
|
473
|
-
to your closure
|
826
|
+
@item user_data
|
827
|
+
An arbitrary datum that is passed, uninterpreted, to your closure
|
828
|
+
function.
|
829
|
+
|
830
|
+
@item codeloc
|
831
|
+
The executable address returned by @code{ffi_closure_alloc}.
|
474
832
|
|
475
|
-
@
|
476
|
-
|
833
|
+
@item fun
|
834
|
+
The function which will be called when the closure is invoked. It is
|
835
|
+
called with the arguments:
|
477
836
|
|
478
|
-
@var{fun} is the function which will be called when the closure is
|
479
|
-
invoked. It is called with the arguments:
|
480
837
|
@table @var
|
481
838
|
@item cif
|
482
839
|
The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}.
|
483
840
|
|
484
841
|
@item ret
|
485
842
|
A pointer to the memory used for the function's return value.
|
486
|
-
|
487
|
-
@code{void}
|
488
|
-
|
843
|
+
|
844
|
+
If the function is declared as returning @code{void}, then this value
|
845
|
+
is garbage and should not be used.
|
846
|
+
|
847
|
+
Otherwise, @var{fun} must fill the object to which this points,
|
848
|
+
following the same special promotion behavior as @code{ffi_call}.
|
849
|
+
That is, in most cases, @var{ret} points to an object of exactly the
|
850
|
+
size of the type specified when @var{cif} was constructed. However,
|
851
|
+
integral types narrower than the system register size are widened. In
|
852
|
+
these cases your program may assume that @var{ret} points to an
|
853
|
+
@code{ffi_arg} object.
|
489
854
|
|
490
855
|
@item args
|
491
856
|
A vector of pointers to memory holding the arguments to the function.
|
@@ -494,10 +859,10 @@ A vector of pointers to memory holding the arguments to the function.
|
|
494
859
|
The same @var{user_data} that was passed to
|
495
860
|
@code{ffi_prep_closure_loc}.
|
496
861
|
@end table
|
862
|
+
@end table
|
497
863
|
|
498
864
|
@code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything
|
499
|
-
went ok, and
|
500
|
-
@c FIXME: what?
|
865
|
+
went ok, and one of the other @code{ffi_status} values on error.
|
501
866
|
|
502
867
|
After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc}
|
503
868
|
to the appropriate pointer-to-function type.
|
@@ -511,28 +876,30 @@ writable and executable addresses.
|
|
511
876
|
@section Closure Example
|
512
877
|
|
513
878
|
A trivial example that creates a new @code{puts} by binding
|
514
|
-
@code{fputs} with @code{
|
879
|
+
@code{fputs} with @code{stdout}.
|
515
880
|
|
516
881
|
@example
|
517
882
|
#include <stdio.h>
|
518
883
|
#include <ffi.h>
|
519
884
|
|
520
885
|
/* Acts like puts with the file given at time of enclosure. */
|
521
|
-
void puts_binding(ffi_cif *cif,
|
522
|
-
|
886
|
+
void puts_binding(ffi_cif *cif, void *ret, void* args[],
|
887
|
+
void *stream)
|
523
888
|
@{
|
524
|
-
*ret = fputs(*(char **)args[0], stream);
|
889
|
+
*(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream);
|
525
890
|
@}
|
526
891
|
|
892
|
+
typedef int (*puts_t)(char *);
|
893
|
+
|
527
894
|
int main()
|
528
895
|
@{
|
529
896
|
ffi_cif cif;
|
530
897
|
ffi_type *args[1];
|
531
898
|
ffi_closure *closure;
|
532
899
|
|
533
|
-
|
900
|
+
void *bound_puts;
|
534
901
|
int rc;
|
535
|
-
|
902
|
+
|
536
903
|
/* Allocate closure and bound_puts */
|
537
904
|
closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);
|
538
905
|
|
@@ -543,13 +910,13 @@ int main()
|
|
543
910
|
|
544
911
|
/* Initialize the cif */
|
545
912
|
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
546
|
-
&
|
913
|
+
&ffi_type_sint, args) == FFI_OK)
|
547
914
|
@{
|
548
915
|
/* Initialize the closure, setting stream to stdout */
|
549
|
-
if (ffi_prep_closure_loc(closure, &cif, puts_binding,
|
916
|
+
if (ffi_prep_closure_loc(closure, &cif, puts_binding,
|
550
917
|
stdout, bound_puts) == FFI_OK)
|
551
918
|
@{
|
552
|
-
rc = bound_puts("Hello World!");
|
919
|
+
rc = ((puts_t)bound_puts)("Hello World!");
|
553
920
|
/* rc now holds the result of the call to fputs */
|
554
921
|
@}
|
555
922
|
@}
|
@@ -563,6 +930,28 @@ int main()
|
|
563
930
|
|
564
931
|
@end example
|
565
932
|
|
933
|
+
@node Thread Safety
|
934
|
+
@section Thread Safety
|
935
|
+
|
936
|
+
@code{libffi} is not completely thread-safe. However, many parts are,
|
937
|
+
and if you follow some simple rules, you can use it safely in a
|
938
|
+
multi-threaded program.
|
939
|
+
|
940
|
+
@itemize @bullet
|
941
|
+
@item
|
942
|
+
@code{ffi_prep_cif} may modify the @code{ffi_type} objects passed to
|
943
|
+
it. It is best to ensure that only a single thread prepares a given
|
944
|
+
@code{ffi_cif} at a time.
|
945
|
+
|
946
|
+
@item
|
947
|
+
On some platforms, @code{ffi_prep_cif} may modify the size and
|
948
|
+
alignment of some types, depending on the chosen ABI. On these
|
949
|
+
platforms, if you switch between ABIs, you must ensure that there is
|
950
|
+
only one call to @code{ffi_prep_cif} at a time.
|
951
|
+
|
952
|
+
Currently the only affected platform is PowerPC and the only affected
|
953
|
+
type is @code{long double}.
|
954
|
+
@end itemize
|
566
955
|
|
567
956
|
@node Missing Features
|
568
957
|
@chapter Missing Features
|
@@ -572,25 +961,21 @@ support for these.
|
|
572
961
|
|
573
962
|
@itemize @bullet
|
574
963
|
@item
|
575
|
-
|
576
|
-
some platforms, depending on how the ABI is defined, but it is not
|
577
|
-
reliable.
|
964
|
+
Variadic closures.
|
578
965
|
|
579
966
|
@item
|
580
967
|
There is no support for bit fields in structures.
|
581
968
|
|
582
|
-
@item
|
583
|
-
The closure API is
|
584
|
-
|
585
|
-
@c FIXME: ...
|
586
|
-
|
587
969
|
@item
|
588
970
|
The ``raw'' API is undocumented.
|
589
|
-
@c argument promotion?
|
590
|
-
@c unions?
|
591
971
|
@c anything else?
|
972
|
+
|
973
|
+
@item
|
974
|
+
The Go API is undocumented.
|
592
975
|
@end itemize
|
593
976
|
|
977
|
+
Note that variadic support is very new and tested on a relatively
|
978
|
+
small number of platforms.
|
594
979
|
|
595
980
|
@node Index
|
596
981
|
@unnumbered Index
|