ffi 1.9.18-x64-mingw32 → 1.9.21-x64-mingw32
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 +5 -5
- data/README.md +3 -2
- data/Rakefile +14 -4
- 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/Makefile.in +923 -938
- data/ext/ffi_c/libffi/README +164 -52
- data/ext/ffi_c/libffi/acinclude.m4 +381 -0
- data/ext/ffi_c/libffi/aclocal.m4 +645 -384
- data/ext/ffi_c/libffi/autogen.sh +2 -0
- data/ext/ffi_c/libffi/autom4te.cache/output.0 +21972 -0
- data/ext/ffi_c/libffi/autom4te.cache/output.1 +21972 -0
- data/ext/ffi_c/libffi/autom4te.cache/output.2 +21972 -0
- data/ext/ffi_c/libffi/autom4te.cache/output.3 +21972 -0
- data/ext/ffi_c/libffi/autom4te.cache/requests +331 -0
- data/ext/ffi_c/libffi/autom4te.cache/traces.0 +4010 -0
- data/ext/ffi_c/libffi/autom4te.cache/traces.1 +1005 -0
- data/ext/ffi_c/libffi/autom4te.cache/traces.2 +4010 -0
- data/ext/ffi_c/libffi/autom4te.cache/traces.3 +4010 -0
- data/ext/ffi_c/libffi/compile +218 -14
- data/ext/ffi_c/libffi/config.guess +329 -368
- data/ext/ffi_c/libffi/config.sub +232 -112
- data/ext/ffi_c/libffi/configure +6970 -2189
- data/ext/ffi_c/libffi/configure.ac +148 -256
- data/ext/ffi_c/libffi/configure.host +265 -4
- data/ext/ffi_c/libffi/depcomp +346 -185
- data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
- data/ext/ffi_c/libffi/doc/Makefile.in +811 -0
- data/ext/ffi_c/libffi/doc/libffi.texi +430 -45
- data/ext/ffi_c/libffi/{mdate-sh → doc/mdate-sh} +40 -13
- data/ext/ffi_c/libffi/{texinfo.tex → doc/texinfo.tex} +3990 -1121
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +24 -13
- data/ext/ffi_c/libffi/fficonfig.h.in~ +210 -0
- 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/Makefile.in +188 -71
- 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/install-sh +190 -202
- 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/ltmain.sh +3553 -2033
- 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/m4/libtool.m4 +1691 -1135
- data/ext/ffi_c/libffi/m4/ltoptions.m4 +104 -36
- data/ext/ffi_c/libffi/m4/ltsugar.m4 +4 -3
- data/ext/ffi_c/libffi/m4/ltversion.m4 +6 -6
- data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +4 -3
- data/ext/ffi_c/libffi/man/Makefile.am +2 -2
- data/ext/ffi_c/libffi/man/Makefile.in +141 -49
- 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/missing +150 -311
- 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/Makefile.in +218 -111
- 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/2.0/ffi_c.so +0 -0
- data/lib/2.1/ffi_c.so +0 -0
- data/lib/2.2/ffi_c.so +0 -0
- data/lib/2.3/ffi_c.so +0 -0
- data/lib/2.4/ffi_c.so +0 -0
- data/lib/2.5/ffi_c.so +0 -0
- 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/embed-test/ext/Makefile +242 -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 +158 -32
- data/ext/ffi_c/libffi/Makefile.vc +0 -141
- data/ext/ffi_c/libffi/Makefile.vc64 +0 -141
- data/ext/ffi_c/libffi/build-ios.sh +0 -67
- 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/include/ffi.h.vc +0 -427
- data/ext/ffi_c/libffi/include/ffi.h.vc64 +0 -427
- 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/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
@@ -1,5 +1,5 @@
|
|
1
1
|
/* -----------------------------------------------------------------------
|
2
|
-
prep_cif.c - Copyright (c) 2011 Anthony Green
|
2
|
+
prep_cif.c - Copyright (c) 2011, 2012 Anthony Green
|
3
3
|
Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining
|
@@ -29,12 +29,12 @@
|
|
29
29
|
|
30
30
|
/* Round up to FFI_SIZEOF_ARG. */
|
31
31
|
|
32
|
-
#define STACK_ARG_SIZE(x)
|
32
|
+
#define STACK_ARG_SIZE(x) FFI_ALIGN(x, FFI_SIZEOF_ARG)
|
33
33
|
|
34
34
|
/* Perform machine independent initialization of aggregate type
|
35
35
|
specifications. */
|
36
36
|
|
37
|
-
static ffi_status initialize_aggregate(ffi_type *arg)
|
37
|
+
static ffi_status initialize_aggregate(ffi_type *arg, size_t *offsets)
|
38
38
|
{
|
39
39
|
ffi_type **ptr;
|
40
40
|
|
@@ -52,13 +52,15 @@ static ffi_status initialize_aggregate(ffi_type *arg)
|
|
52
52
|
while ((*ptr) != NULL)
|
53
53
|
{
|
54
54
|
if (UNLIKELY(((*ptr)->size == 0)
|
55
|
-
&& (initialize_aggregate((*ptr)) != FFI_OK)))
|
55
|
+
&& (initialize_aggregate((*ptr), NULL) != FFI_OK)))
|
56
56
|
return FFI_BAD_TYPEDEF;
|
57
57
|
|
58
58
|
/* Perform a sanity check on the argument type */
|
59
59
|
FFI_ASSERT_VALID_TYPE(*ptr);
|
60
60
|
|
61
|
-
arg->size =
|
61
|
+
arg->size = FFI_ALIGN(arg->size, (*ptr)->alignment);
|
62
|
+
if (offsets)
|
63
|
+
*offsets++ = arg->size;
|
62
64
|
arg->size += (*ptr)->size;
|
63
65
|
|
64
66
|
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
|
@@ -74,7 +76,14 @@ static ffi_status initialize_aggregate(ffi_type *arg)
|
|
74
76
|
struct A { long a; char b; }; struct B { struct A x; char y; };
|
75
77
|
should find y at an offset of 2*sizeof(long) and result in a
|
76
78
|
total size of 3*sizeof(long). */
|
77
|
-
arg->size =
|
79
|
+
arg->size = FFI_ALIGN (arg->size, arg->alignment);
|
80
|
+
|
81
|
+
/* On some targets, the ABI defines that structures have an additional
|
82
|
+
alignment beyond the "natural" one based on their elements. */
|
83
|
+
#ifdef FFI_AGGREGATE_ALIGNMENT
|
84
|
+
if (FFI_AGGREGATE_ALIGNMENT > arg->alignment)
|
85
|
+
arg->alignment = FFI_AGGREGATE_ALIGNMENT;
|
86
|
+
#endif
|
78
87
|
|
79
88
|
if (arg->size == 0)
|
80
89
|
return FFI_BAD_TYPEDEF;
|
@@ -90,37 +99,65 @@ static ffi_status initialize_aggregate(ffi_type *arg)
|
|
90
99
|
/* Perform machine independent ffi_cif preparation, then call
|
91
100
|
machine dependent routine. */
|
92
101
|
|
93
|
-
|
94
|
-
|
102
|
+
/* For non variadic functions isvariadic should be 0 and
|
103
|
+
nfixedargs==ntotalargs.
|
104
|
+
|
105
|
+
For variadic calls, isvariadic should be 1 and nfixedargs
|
106
|
+
and ntotalargs set as appropriate. nfixedargs must always be >=1 */
|
107
|
+
|
108
|
+
|
109
|
+
ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
|
110
|
+
unsigned int isvariadic,
|
111
|
+
unsigned int nfixedargs,
|
112
|
+
unsigned int ntotalargs,
|
113
|
+
ffi_type *rtype, ffi_type **atypes)
|
95
114
|
{
|
96
115
|
unsigned bytes = 0;
|
97
116
|
unsigned int i;
|
98
117
|
ffi_type **ptr;
|
99
118
|
|
100
119
|
FFI_ASSERT(cif != NULL);
|
120
|
+
FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));
|
121
|
+
FFI_ASSERT(nfixedargs <= ntotalargs);
|
122
|
+
|
101
123
|
if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
|
102
124
|
return FFI_BAD_ABI;
|
103
125
|
|
104
126
|
cif->abi = abi;
|
105
127
|
cif->arg_types = atypes;
|
106
|
-
cif->nargs =
|
128
|
+
cif->nargs = ntotalargs;
|
107
129
|
cif->rtype = rtype;
|
108
130
|
|
109
131
|
cif->flags = 0;
|
110
132
|
|
133
|
+
#if HAVE_LONG_DOUBLE_VARIANT
|
134
|
+
ffi_prep_types (abi);
|
135
|
+
#endif
|
136
|
+
|
111
137
|
/* Initialize the return type if necessary */
|
112
|
-
if ((cif->rtype->size == 0)
|
138
|
+
if ((cif->rtype->size == 0)
|
139
|
+
&& (initialize_aggregate(cif->rtype, NULL) != FFI_OK))
|
113
140
|
return FFI_BAD_TYPEDEF;
|
114
141
|
|
142
|
+
#ifndef FFI_TARGET_HAS_COMPLEX_TYPE
|
143
|
+
if (rtype->type == FFI_TYPE_COMPLEX)
|
144
|
+
abort();
|
145
|
+
#endif
|
115
146
|
/* Perform a sanity check on the return type */
|
116
147
|
FFI_ASSERT_VALID_TYPE(cif->rtype);
|
117
148
|
|
118
149
|
/* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
|
119
|
-
#if !defined
|
150
|
+
#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
120
151
|
/* Make space for the return structure pointer */
|
121
152
|
if (cif->rtype->type == FFI_TYPE_STRUCT
|
122
|
-
#ifdef
|
123
|
-
&& (cif->
|
153
|
+
#ifdef TILE
|
154
|
+
&& (cif->rtype->size > 10 * FFI_SIZEOF_ARG)
|
155
|
+
#endif
|
156
|
+
#ifdef XTENSA
|
157
|
+
&& (cif->rtype->size > 16)
|
158
|
+
#endif
|
159
|
+
#ifdef NIOS2
|
160
|
+
&& (cif->rtype->size > 8)
|
124
161
|
#endif
|
125
162
|
)
|
126
163
|
bytes = STACK_ARG_SIZE(sizeof(void*));
|
@@ -130,26 +167,37 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
|
|
130
167
|
{
|
131
168
|
|
132
169
|
/* Initialize any uninitialized aggregate type definitions */
|
133
|
-
if (((*ptr)->size == 0)
|
170
|
+
if (((*ptr)->size == 0)
|
171
|
+
&& (initialize_aggregate((*ptr), NULL) != FFI_OK))
|
134
172
|
return FFI_BAD_TYPEDEF;
|
135
173
|
|
174
|
+
#ifndef FFI_TARGET_HAS_COMPLEX_TYPE
|
175
|
+
if ((*ptr)->type == FFI_TYPE_COMPLEX)
|
176
|
+
abort();
|
177
|
+
#endif
|
136
178
|
/* Perform a sanity check on the argument type, do this
|
137
179
|
check after the initialization. */
|
138
180
|
FFI_ASSERT_VALID_TYPE(*ptr);
|
139
181
|
|
140
|
-
#if !defined
|
141
|
-
#ifdef SPARC
|
142
|
-
if (((*ptr)->type == FFI_TYPE_STRUCT
|
143
|
-
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
|
144
|
-
|| ((*ptr)->type == FFI_TYPE_LONGDOUBLE
|
145
|
-
&& cif->abi != FFI_V9))
|
146
|
-
bytes += sizeof(void*);
|
147
|
-
else
|
148
|
-
#endif
|
182
|
+
#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
149
183
|
{
|
150
184
|
/* Add any padding if necessary */
|
151
185
|
if (((*ptr)->alignment - 1) & bytes)
|
152
|
-
bytes =
|
186
|
+
bytes = (unsigned)FFI_ALIGN(bytes, (*ptr)->alignment);
|
187
|
+
|
188
|
+
#ifdef TILE
|
189
|
+
if (bytes < 10 * FFI_SIZEOF_ARG &&
|
190
|
+
bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG)
|
191
|
+
{
|
192
|
+
/* An argument is never split between the 10 parameter
|
193
|
+
registers and the stack. */
|
194
|
+
bytes = 10 * FFI_SIZEOF_ARG;
|
195
|
+
}
|
196
|
+
#endif
|
197
|
+
#ifdef XTENSA
|
198
|
+
if (bytes <= 6*4 && bytes + STACK_ARG_SIZE((*ptr)->size) > 6*4)
|
199
|
+
bytes = 6*4;
|
200
|
+
#endif
|
153
201
|
|
154
202
|
bytes += STACK_ARG_SIZE((*ptr)->size);
|
155
203
|
}
|
@@ -159,10 +207,31 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
|
|
159
207
|
cif->bytes = bytes;
|
160
208
|
|
161
209
|
/* Perform machine dependent cif processing */
|
210
|
+
#ifdef FFI_TARGET_SPECIFIC_VARIADIC
|
211
|
+
if (isvariadic)
|
212
|
+
return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs);
|
213
|
+
#endif
|
214
|
+
|
162
215
|
return ffi_prep_cif_machdep(cif);
|
163
216
|
}
|
164
217
|
#endif /* not __CRIS__ */
|
165
218
|
|
219
|
+
ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
|
220
|
+
ffi_type *rtype, ffi_type **atypes)
|
221
|
+
{
|
222
|
+
return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes);
|
223
|
+
}
|
224
|
+
|
225
|
+
ffi_status ffi_prep_cif_var(ffi_cif *cif,
|
226
|
+
ffi_abi abi,
|
227
|
+
unsigned int nfixedargs,
|
228
|
+
unsigned int ntotalargs,
|
229
|
+
ffi_type *rtype,
|
230
|
+
ffi_type **atypes)
|
231
|
+
{
|
232
|
+
return ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes);
|
233
|
+
}
|
234
|
+
|
166
235
|
#if FFI_CLOSURES
|
167
236
|
|
168
237
|
ffi_status
|
@@ -175,3 +244,18 @@ ffi_prep_closure (ffi_closure* closure,
|
|
175
244
|
}
|
176
245
|
|
177
246
|
#endif
|
247
|
+
|
248
|
+
ffi_status
|
249
|
+
ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets)
|
250
|
+
{
|
251
|
+
if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
|
252
|
+
return FFI_BAD_ABI;
|
253
|
+
if (struct_type->type != FFI_TYPE_STRUCT)
|
254
|
+
return FFI_BAD_TYPEDEF;
|
255
|
+
|
256
|
+
#if HAVE_LONG_DOUBLE_VARIANT
|
257
|
+
ffi_prep_types (abi);
|
258
|
+
#endif
|
259
|
+
|
260
|
+
return initialize_aggregate(struct_type, offsets);
|
261
|
+
}
|
@@ -43,10 +43,10 @@ ffi_raw_size (ffi_cif *cif)
|
|
43
43
|
{
|
44
44
|
#if !FFI_NO_STRUCTS
|
45
45
|
if ((*at)->type == FFI_TYPE_STRUCT)
|
46
|
-
result +=
|
46
|
+
result += FFI_ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
|
47
47
|
else
|
48
48
|
#endif
|
49
|
-
result +=
|
49
|
+
result += FFI_ALIGN ((*at)->size, FFI_SIZEOF_ARG);
|
50
50
|
}
|
51
51
|
|
52
52
|
return result;
|
@@ -88,13 +88,17 @@ ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
|
|
88
88
|
break;
|
89
89
|
#endif
|
90
90
|
|
91
|
+
case FFI_TYPE_COMPLEX:
|
92
|
+
*args = (raw++)->ptr;
|
93
|
+
break;
|
94
|
+
|
91
95
|
case FFI_TYPE_POINTER:
|
92
96
|
*args = (void*) &(raw++)->ptr;
|
93
97
|
break;
|
94
98
|
|
95
99
|
default:
|
96
100
|
*args = raw;
|
97
|
-
raw +=
|
101
|
+
raw += FFI_ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
|
98
102
|
}
|
99
103
|
}
|
100
104
|
|
@@ -112,9 +116,14 @@ ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
|
|
112
116
|
}
|
113
117
|
else
|
114
118
|
#endif
|
119
|
+
if ((*tp)->type == FFI_TYPE_COMPLEX)
|
120
|
+
{
|
121
|
+
*args = (raw++)->ptr;
|
122
|
+
}
|
123
|
+
else
|
115
124
|
{
|
116
125
|
*args = (void*) raw;
|
117
|
-
raw +=
|
126
|
+
raw += FFI_ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
|
118
127
|
}
|
119
128
|
}
|
120
129
|
|
@@ -167,13 +176,17 @@ ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
|
|
167
176
|
break;
|
168
177
|
#endif
|
169
178
|
|
179
|
+
case FFI_TYPE_COMPLEX:
|
180
|
+
(raw++)->ptr = *args;
|
181
|
+
break;
|
182
|
+
|
170
183
|
case FFI_TYPE_POINTER:
|
171
184
|
(raw++)->ptr = **(void***) args;
|
172
185
|
break;
|
173
186
|
|
174
187
|
default:
|
175
188
|
memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
|
176
|
-
raw +=
|
189
|
+
raw += FFI_ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
|
177
190
|
}
|
178
191
|
}
|
179
192
|
}
|
@@ -1,9 +1,9 @@
|
|
1
1
|
/* -----------------------------------------------------------------------
|
2
2
|
ffi.c - Copyright (c) 2000, 2007 Software AG
|
3
3
|
Copyright (c) 2008 Red Hat, Inc
|
4
|
-
|
4
|
+
|
5
5
|
S390 Foreign Function Interface
|
6
|
-
|
6
|
+
|
7
7
|
Permission is hereby granted, free of charge, to any person obtaining
|
8
8
|
a copy of this software and associated documentation files (the
|
9
9
|
``Software''), to deal in the Software without restriction, including
|
@@ -11,10 +11,10 @@
|
|
11
11
|
distribute, sublicense, and/or sell copies of the Software, and to
|
12
12
|
permit persons to whom the Software is furnished to do so, subject to
|
13
13
|
the following conditions:
|
14
|
-
|
14
|
+
|
15
15
|
The above copyright notice and this permission notice shall be included
|
16
16
|
in all copies or substantial portions of the Software.
|
17
|
-
|
17
|
+
|
18
18
|
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
19
19
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
20
20
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
@@ -27,24 +27,23 @@
|
|
27
27
|
/* Includes */
|
28
28
|
/* -------- */
|
29
29
|
/*====================================================================*/
|
30
|
-
|
30
|
+
|
31
31
|
#include <ffi.h>
|
32
32
|
#include <ffi_common.h>
|
33
|
-
|
34
|
-
#include
|
35
|
-
|
36
|
-
|
33
|
+
#include <stdint.h>
|
34
|
+
#include "internal.h"
|
35
|
+
|
37
36
|
/*====================== End of Includes =============================*/
|
38
|
-
|
37
|
+
|
39
38
|
/*====================================================================*/
|
40
39
|
/* Defines */
|
41
40
|
/* ------- */
|
42
41
|
/*====================================================================*/
|
43
42
|
|
44
|
-
/* Maximum number of GPRs available for argument passing. */
|
43
|
+
/* Maximum number of GPRs available for argument passing. */
|
45
44
|
#define MAX_GPRARGS 5
|
46
45
|
|
47
|
-
/* Maximum number of FPRs available for argument passing. */
|
46
|
+
/* Maximum number of FPRs available for argument passing. */
|
48
47
|
#ifdef __s390x__
|
49
48
|
#define MAX_FPRARGS 4
|
50
49
|
#else
|
@@ -54,47 +53,30 @@
|
|
54
53
|
/* Round to multiple of 16. */
|
55
54
|
#define ROUND_SIZE(size) (((size) + 15) & ~15)
|
56
55
|
|
57
|
-
/* If these values change, sysv.S must be adapted! */
|
58
|
-
#define FFI390_RET_VOID 0
|
59
|
-
#define FFI390_RET_STRUCT 1
|
60
|
-
#define FFI390_RET_FLOAT 2
|
61
|
-
#define FFI390_RET_DOUBLE 3
|
62
|
-
#define FFI390_RET_INT32 4
|
63
|
-
#define FFI390_RET_INT64 5
|
64
|
-
|
65
56
|
/*===================== End of Defines ===============================*/
|
66
|
-
|
67
|
-
/*====================================================================*/
|
68
|
-
/* Prototypes */
|
69
|
-
/* ---------- */
|
70
|
-
/*====================================================================*/
|
71
|
-
|
72
|
-
static void ffi_prep_args (unsigned char *, extended_cif *);
|
73
|
-
void
|
74
|
-
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
75
|
-
__attribute__ ((visibility ("hidden")))
|
76
|
-
#endif
|
77
|
-
ffi_closure_helper_SYSV (ffi_closure *, unsigned long *,
|
78
|
-
unsigned long long *, unsigned long *);
|
79
57
|
|
80
|
-
/*====================== End of Prototypes ===========================*/
|
81
|
-
|
82
58
|
/*====================================================================*/
|
83
59
|
/* Externals */
|
84
60
|
/* --------- */
|
85
61
|
/*====================================================================*/
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
62
|
+
|
63
|
+
struct call_frame
|
64
|
+
{
|
65
|
+
void *back_chain;
|
66
|
+
void *eos;
|
67
|
+
unsigned long gpr_args[5];
|
68
|
+
unsigned long gpr_save[9];
|
69
|
+
unsigned long long fpr_args[4];
|
70
|
+
};
|
71
|
+
|
72
|
+
extern void FFI_HIDDEN ffi_call_SYSV(struct call_frame *, unsigned, void *,
|
73
|
+
void (*fn)(void), void *);
|
93
74
|
|
94
75
|
extern void ffi_closure_SYSV(void);
|
95
|
-
|
76
|
+
extern void ffi_go_closure_SYSV(void);
|
77
|
+
|
96
78
|
/*====================== End of Externals ============================*/
|
97
|
-
|
79
|
+
|
98
80
|
/*====================================================================*/
|
99
81
|
/* */
|
100
82
|
/* Name - ffi_check_struct_type. */
|
@@ -103,7 +85,7 @@ extern void ffi_closure_SYSV(void);
|
|
103
85
|
/* general purpose or floating point register. */
|
104
86
|
/* */
|
105
87
|
/*====================================================================*/
|
106
|
-
|
88
|
+
|
107
89
|
static int
|
108
90
|
ffi_check_struct_type (ffi_type *arg)
|
109
91
|
{
|
@@ -111,7 +93,7 @@ ffi_check_struct_type (ffi_type *arg)
|
|
111
93
|
|
112
94
|
/* If the struct has just one element, look at that element
|
113
95
|
to find out whether to consider the struct as floating point. */
|
114
|
-
while (arg->type == FFI_TYPE_STRUCT
|
96
|
+
while (arg->type == FFI_TYPE_STRUCT
|
115
97
|
&& arg->elements[0] && !arg->elements[1])
|
116
98
|
arg = arg->elements[0];
|
117
99
|
|
@@ -144,190 +126,9 @@ ffi_check_struct_type (ffi_type *arg)
|
|
144
126
|
/* Other structs are passed via a pointer to the data. */
|
145
127
|
return FFI_TYPE_POINTER;
|
146
128
|
}
|
147
|
-
|
148
|
-
/*======================== End of Routine ============================*/
|
149
|
-
|
150
|
-
/*====================================================================*/
|
151
|
-
/* */
|
152
|
-
/* Name - ffi_prep_args. */
|
153
|
-
/* */
|
154
|
-
/* Function - Prepare parameters for call to function. */
|
155
|
-
/* */
|
156
|
-
/* ffi_prep_args is called by the assembly routine once stack space */
|
157
|
-
/* has been allocated for the function's arguments. */
|
158
|
-
/* */
|
159
|
-
/*====================================================================*/
|
160
|
-
|
161
|
-
static void
|
162
|
-
ffi_prep_args (unsigned char *stack, extended_cif *ecif)
|
163
|
-
{
|
164
|
-
/* The stack space will be filled with those areas:
|
165
|
-
|
166
|
-
FPR argument register save area (highest addresses)
|
167
|
-
GPR argument register save area
|
168
|
-
temporary struct copies
|
169
|
-
overflow argument area (lowest addresses)
|
170
|
-
|
171
|
-
We set up the following pointers:
|
172
|
-
|
173
|
-
p_fpr: bottom of the FPR area (growing upwards)
|
174
|
-
p_gpr: bottom of the GPR area (growing upwards)
|
175
|
-
p_ov: bottom of the overflow area (growing upwards)
|
176
|
-
p_struct: top of the struct copy area (growing downwards)
|
177
|
-
|
178
|
-
All areas are kept aligned to twice the word size. */
|
179
|
-
|
180
|
-
int gpr_off = ecif->cif->bytes;
|
181
|
-
int fpr_off = gpr_off + ROUND_SIZE (MAX_GPRARGS * sizeof (long));
|
182
|
-
|
183
|
-
unsigned long long *p_fpr = (unsigned long long *)(stack + fpr_off);
|
184
|
-
unsigned long *p_gpr = (unsigned long *)(stack + gpr_off);
|
185
|
-
unsigned char *p_struct = (unsigned char *)p_gpr;
|
186
|
-
unsigned long *p_ov = (unsigned long *)stack;
|
187
|
-
|
188
|
-
int n_fpr = 0;
|
189
|
-
int n_gpr = 0;
|
190
|
-
int n_ov = 0;
|
191
|
-
|
192
|
-
ffi_type **ptr;
|
193
|
-
void **p_argv = ecif->avalue;
|
194
|
-
int i;
|
195
|
-
|
196
|
-
/* If we returning a structure then we set the first parameter register
|
197
|
-
to the address of where we are returning this structure. */
|
198
|
-
|
199
|
-
if (ecif->cif->flags == FFI390_RET_STRUCT)
|
200
|
-
p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
|
201
|
-
|
202
|
-
/* Now for the arguments. */
|
203
|
-
|
204
|
-
for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
|
205
|
-
i > 0;
|
206
|
-
i--, ptr++, p_argv++)
|
207
|
-
{
|
208
|
-
void *arg = *p_argv;
|
209
|
-
int type = (*ptr)->type;
|
210
|
-
|
211
|
-
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
212
|
-
/* 16-byte long double is passed like a struct. */
|
213
|
-
if (type == FFI_TYPE_LONGDOUBLE)
|
214
|
-
type = FFI_TYPE_STRUCT;
|
215
|
-
#endif
|
216
|
-
|
217
|
-
/* Check how a structure type is passed. */
|
218
|
-
if (type == FFI_TYPE_STRUCT)
|
219
|
-
{
|
220
|
-
type = ffi_check_struct_type (*ptr);
|
221
|
-
|
222
|
-
/* If we pass the struct via pointer, copy the data. */
|
223
|
-
if (type == FFI_TYPE_POINTER)
|
224
|
-
{
|
225
|
-
p_struct -= ROUND_SIZE ((*ptr)->size);
|
226
|
-
memcpy (p_struct, (char *)arg, (*ptr)->size);
|
227
|
-
arg = &p_struct;
|
228
|
-
}
|
229
|
-
}
|
230
|
-
|
231
|
-
/* Now handle all primitive int/pointer/float data types. */
|
232
|
-
switch (type)
|
233
|
-
{
|
234
|
-
case FFI_TYPE_DOUBLE:
|
235
|
-
if (n_fpr < MAX_FPRARGS)
|
236
|
-
p_fpr[n_fpr++] = *(unsigned long long *) arg;
|
237
|
-
else
|
238
|
-
#ifdef __s390x__
|
239
|
-
p_ov[n_ov++] = *(unsigned long *) arg;
|
240
|
-
#else
|
241
|
-
p_ov[n_ov++] = ((unsigned long *) arg)[0],
|
242
|
-
p_ov[n_ov++] = ((unsigned long *) arg)[1];
|
243
|
-
#endif
|
244
|
-
break;
|
245
|
-
|
246
|
-
case FFI_TYPE_FLOAT:
|
247
|
-
if (n_fpr < MAX_FPRARGS)
|
248
|
-
p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
|
249
|
-
else
|
250
|
-
p_ov[n_ov++] = *(unsigned int *) arg;
|
251
|
-
break;
|
252
|
-
|
253
|
-
case FFI_TYPE_POINTER:
|
254
|
-
if (n_gpr < MAX_GPRARGS)
|
255
|
-
p_gpr[n_gpr++] = (unsigned long)*(unsigned char **) arg;
|
256
|
-
else
|
257
|
-
p_ov[n_ov++] = (unsigned long)*(unsigned char **) arg;
|
258
|
-
break;
|
259
|
-
|
260
|
-
case FFI_TYPE_UINT64:
|
261
|
-
case FFI_TYPE_SINT64:
|
262
|
-
#ifdef __s390x__
|
263
|
-
if (n_gpr < MAX_GPRARGS)
|
264
|
-
p_gpr[n_gpr++] = *(unsigned long *) arg;
|
265
|
-
else
|
266
|
-
p_ov[n_ov++] = *(unsigned long *) arg;
|
267
|
-
#else
|
268
|
-
if (n_gpr == MAX_GPRARGS-1)
|
269
|
-
n_gpr = MAX_GPRARGS;
|
270
|
-
if (n_gpr < MAX_GPRARGS)
|
271
|
-
p_gpr[n_gpr++] = ((unsigned long *) arg)[0],
|
272
|
-
p_gpr[n_gpr++] = ((unsigned long *) arg)[1];
|
273
|
-
else
|
274
|
-
p_ov[n_ov++] = ((unsigned long *) arg)[0],
|
275
|
-
p_ov[n_ov++] = ((unsigned long *) arg)[1];
|
276
|
-
#endif
|
277
|
-
break;
|
278
|
-
|
279
|
-
case FFI_TYPE_UINT32:
|
280
|
-
if (n_gpr < MAX_GPRARGS)
|
281
|
-
p_gpr[n_gpr++] = *(unsigned int *) arg;
|
282
|
-
else
|
283
|
-
p_ov[n_ov++] = *(unsigned int *) arg;
|
284
|
-
break;
|
285
|
-
|
286
|
-
case FFI_TYPE_INT:
|
287
|
-
case FFI_TYPE_SINT32:
|
288
|
-
if (n_gpr < MAX_GPRARGS)
|
289
|
-
p_gpr[n_gpr++] = *(signed int *) arg;
|
290
|
-
else
|
291
|
-
p_ov[n_ov++] = *(signed int *) arg;
|
292
|
-
break;
|
293
|
-
|
294
|
-
case FFI_TYPE_UINT16:
|
295
|
-
if (n_gpr < MAX_GPRARGS)
|
296
|
-
p_gpr[n_gpr++] = *(unsigned short *) arg;
|
297
|
-
else
|
298
|
-
p_ov[n_ov++] = *(unsigned short *) arg;
|
299
|
-
break;
|
300
|
-
|
301
|
-
case FFI_TYPE_SINT16:
|
302
|
-
if (n_gpr < MAX_GPRARGS)
|
303
|
-
p_gpr[n_gpr++] = *(signed short *) arg;
|
304
|
-
else
|
305
|
-
p_ov[n_ov++] = *(signed short *) arg;
|
306
|
-
break;
|
307
|
-
|
308
|
-
case FFI_TYPE_UINT8:
|
309
|
-
if (n_gpr < MAX_GPRARGS)
|
310
|
-
p_gpr[n_gpr++] = *(unsigned char *) arg;
|
311
|
-
else
|
312
|
-
p_ov[n_ov++] = *(unsigned char *) arg;
|
313
|
-
break;
|
314
|
-
|
315
|
-
case FFI_TYPE_SINT8:
|
316
|
-
if (n_gpr < MAX_GPRARGS)
|
317
|
-
p_gpr[n_gpr++] = *(signed char *) arg;
|
318
|
-
else
|
319
|
-
p_ov[n_ov++] = *(signed char *) arg;
|
320
|
-
break;
|
321
|
-
|
322
|
-
default:
|
323
|
-
FFI_ASSERT (0);
|
324
|
-
break;
|
325
|
-
}
|
326
|
-
}
|
327
|
-
}
|
328
129
|
|
329
130
|
/*======================== End of Routine ============================*/
|
330
|
-
|
131
|
+
|
331
132
|
/*====================================================================*/
|
332
133
|
/* */
|
333
134
|
/* Name - ffi_prep_cif_machdep. */
|
@@ -335,8 +136,8 @@ ffi_prep_args (unsigned char *stack, extended_cif *ecif)
|
|
335
136
|
/* Function - Perform machine dependent CIF processing. */
|
336
137
|
/* */
|
337
138
|
/*====================================================================*/
|
338
|
-
|
339
|
-
ffi_status
|
139
|
+
|
140
|
+
ffi_status FFI_HIDDEN
|
340
141
|
ffi_prep_cif_machdep(ffi_cif *cif)
|
341
142
|
{
|
342
143
|
size_t struct_size = 0;
|
@@ -347,7 +148,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
347
148
|
ffi_type **ptr;
|
348
149
|
int i;
|
349
150
|
|
350
|
-
/* Determine return value handling. */
|
151
|
+
/* Determine return value handling. */
|
351
152
|
|
352
153
|
switch (cif->rtype->type)
|
353
154
|
{
|
@@ -356,11 +157,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
356
157
|
cif->flags = FFI390_RET_VOID;
|
357
158
|
break;
|
358
159
|
|
359
|
-
/* Structures are returned via a hidden pointer. */
|
160
|
+
/* Structures and complex are returned via a hidden pointer. */
|
360
161
|
case FFI_TYPE_STRUCT:
|
162
|
+
case FFI_TYPE_COMPLEX:
|
361
163
|
cif->flags = FFI390_RET_STRUCT;
|
362
164
|
n_gpr++; /* We need one GPR to pass the pointer. */
|
363
|
-
break;
|
165
|
+
break;
|
364
166
|
|
365
167
|
/* Floating point values are returned in fpr 0. */
|
366
168
|
case FFI_TYPE_FLOAT:
|
@@ -399,14 +201,14 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
399
201
|
cif->flags = FFI390_RET_INT32;
|
400
202
|
#endif
|
401
203
|
break;
|
402
|
-
|
204
|
+
|
403
205
|
default:
|
404
206
|
FFI_ASSERT (0);
|
405
207
|
break;
|
406
208
|
}
|
407
209
|
|
408
210
|
/* Now for the arguments. */
|
409
|
-
|
211
|
+
|
410
212
|
for (ptr = cif->arg_types, i = cif->nargs;
|
411
213
|
i > 0;
|
412
214
|
i--, ptr++)
|
@@ -420,9 +222,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
420
222
|
#endif
|
421
223
|
|
422
224
|
/* Check how a structure type is passed. */
|
423
|
-
if (type == FFI_TYPE_STRUCT)
|
225
|
+
if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
|
424
226
|
{
|
425
|
-
type
|
227
|
+
if (type == FFI_TYPE_COMPLEX)
|
228
|
+
type = FFI_TYPE_POINTER;
|
229
|
+
else
|
230
|
+
type = ffi_check_struct_type (*ptr);
|
426
231
|
|
427
232
|
/* If we pass the struct via pointer, we must reserve space
|
428
233
|
to copy its data for proper call-by-value semantics. */
|
@@ -431,7 +236,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
431
236
|
}
|
432
237
|
|
433
238
|
/* Now handle all primitive int/float data types. */
|
434
|
-
switch (type)
|
239
|
+
switch (type)
|
435
240
|
{
|
436
241
|
/* The first MAX_FPRARGS floating point arguments
|
437
242
|
go in FPRs, the rest overflow to the stack. */
|
@@ -442,7 +247,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
442
247
|
else
|
443
248
|
n_ov += sizeof (double) / sizeof (long);
|
444
249
|
break;
|
445
|
-
|
250
|
+
|
446
251
|
case FFI_TYPE_FLOAT:
|
447
252
|
if (n_fpr < MAX_FPRARGS)
|
448
253
|
n_fpr++;
|
@@ -452,9 +257,9 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
452
257
|
|
453
258
|
/* On 31-bit machines, 64-bit integers are passed in GPR pairs,
|
454
259
|
if one is still available, or else on the stack. If only one
|
455
|
-
register is free, skip the register (it won't be used for any
|
260
|
+
register is free, skip the register (it won't be used for any
|
456
261
|
subsequent argument either). */
|
457
|
-
|
262
|
+
|
458
263
|
#ifndef __s390x__
|
459
264
|
case FFI_TYPE_UINT64:
|
460
265
|
case FFI_TYPE_SINT64:
|
@@ -470,7 +275,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
470
275
|
/* Everything else is passed in GPRs (until MAX_GPRARGS
|
471
276
|
have been used) or overflows to the stack. */
|
472
277
|
|
473
|
-
default:
|
278
|
+
default:
|
474
279
|
if (n_gpr < MAX_GPRARGS)
|
475
280
|
n_gpr++;
|
476
281
|
else
|
@@ -483,12 +288,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
483
288
|
and temporary structure copies. */
|
484
289
|
|
485
290
|
cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
|
486
|
-
|
291
|
+
|
487
292
|
return FFI_OK;
|
488
293
|
}
|
489
|
-
|
294
|
+
|
490
295
|
/*======================== End of Routine ============================*/
|
491
|
-
|
296
|
+
|
492
297
|
/*====================================================================*/
|
493
298
|
/* */
|
494
299
|
/* Name - ffi_call. */
|
@@ -496,42 +301,195 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
496
301
|
/* Function - Call the FFI routine. */
|
497
302
|
/* */
|
498
303
|
/*====================================================================*/
|
499
|
-
|
500
|
-
void
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
304
|
+
|
305
|
+
static void
|
306
|
+
ffi_call_int(ffi_cif *cif,
|
307
|
+
void (*fn)(void),
|
308
|
+
void *rvalue,
|
309
|
+
void **avalue,
|
310
|
+
void *closure)
|
505
311
|
{
|
506
312
|
int ret_type = cif->flags;
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
313
|
+
size_t rsize = 0, bytes = cif->bytes;
|
314
|
+
unsigned char *stack, *p_struct;
|
315
|
+
struct call_frame *frame;
|
316
|
+
unsigned long *p_ov, *p_gpr;
|
317
|
+
unsigned long long *p_fpr;
|
318
|
+
int n_fpr, n_gpr, n_ov, i, n;
|
319
|
+
ffi_type **arg_types;
|
320
|
+
|
321
|
+
FFI_ASSERT (cif->abi == FFI_SYSV);
|
512
322
|
|
513
323
|
/* If we don't have a return value, we need to fake one. */
|
514
324
|
if (rvalue == NULL)
|
515
325
|
{
|
516
|
-
if (ret_type
|
517
|
-
|
326
|
+
if (ret_type & FFI390_RET_IN_MEM)
|
327
|
+
rsize = cif->rtype->size;
|
518
328
|
else
|
519
329
|
ret_type = FFI390_RET_VOID;
|
520
|
-
}
|
330
|
+
}
|
331
|
+
|
332
|
+
/* The stack space will be filled with those areas:
|
333
|
+
|
334
|
+
dummy structure return (highest addresses)
|
335
|
+
FPR argument register save area
|
336
|
+
GPR argument register save area
|
337
|
+
stack frame for ffi_call_SYSV
|
338
|
+
temporary struct copies
|
339
|
+
overflow argument area (lowest addresses)
|
340
|
+
|
341
|
+
We set up the following pointers:
|
342
|
+
|
343
|
+
p_fpr: bottom of the FPR area (growing upwards)
|
344
|
+
p_gpr: bottom of the GPR area (growing upwards)
|
345
|
+
p_ov: bottom of the overflow area (growing upwards)
|
346
|
+
p_struct: top of the struct copy area (growing downwards)
|
347
|
+
|
348
|
+
All areas are kept aligned to twice the word size.
|
349
|
+
|
350
|
+
Note that we're going to create the stack frame for both
|
351
|
+
ffi_call_SYSV _and_ the target function right here. This
|
352
|
+
works because we don't make any function calls with more
|
353
|
+
than 5 arguments (indeed only memcpy and ffi_call_SYSV),
|
354
|
+
and thus we don't have any stacked outgoing parameters. */
|
521
355
|
|
522
|
-
|
356
|
+
stack = alloca (bytes + sizeof(struct call_frame) + rsize);
|
357
|
+
frame = (struct call_frame *)(stack + bytes);
|
358
|
+
if (rsize)
|
359
|
+
rvalue = frame + 1;
|
360
|
+
|
361
|
+
/* Link the new frame back to the one from this function. */
|
362
|
+
frame->back_chain = __builtin_frame_address (0);
|
363
|
+
|
364
|
+
/* Fill in all of the argument stuff. */
|
365
|
+
p_ov = (unsigned long *)stack;
|
366
|
+
p_struct = (unsigned char *)frame;
|
367
|
+
p_gpr = frame->gpr_args;
|
368
|
+
p_fpr = frame->fpr_args;
|
369
|
+
n_fpr = n_gpr = n_ov = 0;
|
370
|
+
|
371
|
+
/* If we returning a structure then we set the first parameter register
|
372
|
+
to the address of where we are returning this structure. */
|
373
|
+
if (cif->flags & FFI390_RET_IN_MEM)
|
374
|
+
p_gpr[n_gpr++] = (uintptr_t) rvalue;
|
375
|
+
|
376
|
+
/* Now for the arguments. */
|
377
|
+
arg_types = cif->arg_types;
|
378
|
+
for (i = 0, n = cif->nargs; i < n; ++i)
|
523
379
|
{
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
380
|
+
ffi_type *ty = arg_types[i];
|
381
|
+
void *arg = avalue[i];
|
382
|
+
int type = ty->type;
|
383
|
+
ffi_arg val;
|
384
|
+
|
385
|
+
restart:
|
386
|
+
switch (type)
|
387
|
+
{
|
388
|
+
case FFI_TYPE_SINT8:
|
389
|
+
val = *(SINT8 *)arg;
|
390
|
+
goto do_int;
|
391
|
+
case FFI_TYPE_UINT8:
|
392
|
+
val = *(UINT8 *)arg;
|
393
|
+
goto do_int;
|
394
|
+
case FFI_TYPE_SINT16:
|
395
|
+
val = *(SINT16 *)arg;
|
396
|
+
goto do_int;
|
397
|
+
case FFI_TYPE_UINT16:
|
398
|
+
val = *(UINT16 *)arg;
|
399
|
+
goto do_int;
|
400
|
+
case FFI_TYPE_INT:
|
401
|
+
case FFI_TYPE_SINT32:
|
402
|
+
val = *(SINT32 *)arg;
|
403
|
+
goto do_int;
|
404
|
+
case FFI_TYPE_UINT32:
|
405
|
+
val = *(UINT32 *)arg;
|
406
|
+
goto do_int;
|
407
|
+
case FFI_TYPE_POINTER:
|
408
|
+
val = *(uintptr_t *)arg;
|
409
|
+
do_int:
|
410
|
+
*(n_gpr < MAX_GPRARGS ? p_gpr + n_gpr++ : p_ov + n_ov++) = val;
|
411
|
+
break;
|
412
|
+
|
413
|
+
case FFI_TYPE_UINT64:
|
414
|
+
case FFI_TYPE_SINT64:
|
415
|
+
#ifdef __s390x__
|
416
|
+
val = *(UINT64 *)arg;
|
417
|
+
goto do_int;
|
418
|
+
#else
|
419
|
+
if (n_gpr == MAX_GPRARGS-1)
|
420
|
+
n_gpr = MAX_GPRARGS;
|
421
|
+
if (n_gpr < MAX_GPRARGS)
|
422
|
+
p_gpr[n_gpr++] = ((UINT32 *) arg)[0],
|
423
|
+
p_gpr[n_gpr++] = ((UINT32 *) arg)[1];
|
424
|
+
else
|
425
|
+
p_ov[n_ov++] = ((UINT32 *) arg)[0],
|
426
|
+
p_ov[n_ov++] = ((UINT32 *) arg)[1];
|
427
|
+
#endif
|
428
|
+
break;
|
429
|
+
|
430
|
+
case FFI_TYPE_DOUBLE:
|
431
|
+
if (n_fpr < MAX_FPRARGS)
|
432
|
+
p_fpr[n_fpr++] = *(UINT64 *) arg;
|
433
|
+
else
|
434
|
+
{
|
435
|
+
#ifdef __s390x__
|
436
|
+
p_ov[n_ov++] = *(UINT64 *) arg;
|
437
|
+
#else
|
438
|
+
p_ov[n_ov++] = ((UINT32 *) arg)[0],
|
439
|
+
p_ov[n_ov++] = ((UINT32 *) arg)[1];
|
440
|
+
#endif
|
441
|
+
}
|
442
|
+
break;
|
443
|
+
|
444
|
+
case FFI_TYPE_FLOAT:
|
445
|
+
val = *(UINT32 *)arg;
|
446
|
+
if (n_fpr < MAX_FPRARGS)
|
447
|
+
p_fpr[n_fpr++] = (UINT64)val << 32;
|
448
|
+
else
|
449
|
+
p_ov[n_ov++] = val;
|
450
|
+
break;
|
451
|
+
|
452
|
+
case FFI_TYPE_STRUCT:
|
453
|
+
/* Check how a structure type is passed. */
|
454
|
+
type = ffi_check_struct_type (ty);
|
455
|
+
/* Some structures are passed via a type they contain. */
|
456
|
+
if (type != FFI_TYPE_POINTER)
|
457
|
+
goto restart;
|
458
|
+
/* ... otherwise, passed by reference. fallthru. */
|
459
|
+
|
460
|
+
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
461
|
+
case FFI_TYPE_LONGDOUBLE:
|
462
|
+
/* 16-byte long double is passed via reference. */
|
463
|
+
#endif
|
464
|
+
case FFI_TYPE_COMPLEX:
|
465
|
+
/* Complex types are passed via reference. */
|
466
|
+
p_struct -= ROUND_SIZE (ty->size);
|
467
|
+
memcpy (p_struct, arg, ty->size);
|
468
|
+
val = (uintptr_t)p_struct;
|
469
|
+
goto do_int;
|
470
|
+
|
471
|
+
default:
|
472
|
+
FFI_ASSERT (0);
|
473
|
+
break;
|
474
|
+
}
|
532
475
|
}
|
476
|
+
|
477
|
+
ffi_call_SYSV (frame, ret_type & FFI360_RET_MASK, rvalue, fn, closure);
|
533
478
|
}
|
534
|
-
|
479
|
+
|
480
|
+
void
|
481
|
+
ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
482
|
+
{
|
483
|
+
ffi_call_int(cif, fn, rvalue, avalue, NULL);
|
484
|
+
}
|
485
|
+
|
486
|
+
void
|
487
|
+
ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
488
|
+
void **avalue, void *closure)
|
489
|
+
{
|
490
|
+
ffi_call_int(cif, fn, rvalue, avalue, closure);
|
491
|
+
}
|
492
|
+
|
535
493
|
/*======================== End of Routine ============================*/
|
536
494
|
|
537
495
|
/*====================================================================*/
|
@@ -541,9 +499,11 @@ ffi_call(ffi_cif *cif,
|
|
541
499
|
/* Function - Call a FFI closure target function. */
|
542
500
|
/* */
|
543
501
|
/*====================================================================*/
|
544
|
-
|
545
|
-
void
|
546
|
-
ffi_closure_helper_SYSV (
|
502
|
+
|
503
|
+
void FFI_HIDDEN
|
504
|
+
ffi_closure_helper_SYSV (ffi_cif *cif,
|
505
|
+
void (*fun)(ffi_cif*,void*,void**,void*),
|
506
|
+
void *user_data,
|
547
507
|
unsigned long *p_gpr,
|
548
508
|
unsigned long long *p_fpr,
|
549
509
|
unsigned long *p_ov)
|
@@ -562,21 +522,16 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|
562
522
|
int i;
|
563
523
|
|
564
524
|
/* Allocate buffer for argument list pointers. */
|
525
|
+
p_arg = avalue = alloca (cif->nargs * sizeof (void *));
|
565
526
|
|
566
|
-
|
567
|
-
|
568
|
-
/* If we returning a structure, pass the structure address
|
569
|
-
directly to the target function. Otherwise, have the target
|
527
|
+
/* If we returning a structure, pass the structure address
|
528
|
+
directly to the target function. Otherwise, have the target
|
570
529
|
function store the return value to the GPR save area. */
|
571
|
-
|
572
|
-
if (closure->cif->flags == FFI390_RET_STRUCT)
|
530
|
+
if (cif->flags & FFI390_RET_IN_MEM)
|
573
531
|
rvalue = (void *) p_gpr[n_gpr++];
|
574
532
|
|
575
533
|
/* Now for the arguments. */
|
576
|
-
|
577
|
-
for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
|
578
|
-
i > 0;
|
579
|
-
i--, p_arg++, ptr++)
|
534
|
+
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, p_arg++, ptr++)
|
580
535
|
{
|
581
536
|
int deref_struct_pointer = 0;
|
582
537
|
int type = (*ptr)->type;
|
@@ -588,11 +543,14 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|
588
543
|
#endif
|
589
544
|
|
590
545
|
/* Check how a structure type is passed. */
|
591
|
-
if (type == FFI_TYPE_STRUCT)
|
546
|
+
if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
|
592
547
|
{
|
593
|
-
type
|
548
|
+
if (type == FFI_TYPE_COMPLEX)
|
549
|
+
type = FFI_TYPE_POINTER;
|
550
|
+
else
|
551
|
+
type = ffi_check_struct_type (*ptr);
|
594
552
|
|
595
|
-
/* If we pass the struct via pointer, remember to
|
553
|
+
/* If we pass the struct via pointer, remember to
|
596
554
|
retrieve the pointer later. */
|
597
555
|
if (type == FFI_TYPE_POINTER)
|
598
556
|
deref_struct_pointer = 1;
|
@@ -600,30 +558,32 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|
600
558
|
|
601
559
|
/* Pointers are passed like UINTs of the same size. */
|
602
560
|
if (type == FFI_TYPE_POINTER)
|
561
|
+
{
|
603
562
|
#ifdef __s390x__
|
604
|
-
|
563
|
+
type = FFI_TYPE_UINT64;
|
605
564
|
#else
|
606
|
-
|
565
|
+
type = FFI_TYPE_UINT32;
|
607
566
|
#endif
|
567
|
+
}
|
608
568
|
|
609
569
|
/* Now handle all primitive int/float data types. */
|
610
|
-
switch (type)
|
570
|
+
switch (type)
|
611
571
|
{
|
612
572
|
case FFI_TYPE_DOUBLE:
|
613
573
|
if (n_fpr < MAX_FPRARGS)
|
614
574
|
*p_arg = &p_fpr[n_fpr++];
|
615
575
|
else
|
616
|
-
*p_arg = &p_ov[n_ov],
|
576
|
+
*p_arg = &p_ov[n_ov],
|
617
577
|
n_ov += sizeof (double) / sizeof (long);
|
618
578
|
break;
|
619
|
-
|
579
|
+
|
620
580
|
case FFI_TYPE_FLOAT:
|
621
581
|
if (n_fpr < MAX_FPRARGS)
|
622
582
|
*p_arg = &p_fpr[n_fpr++];
|
623
583
|
else
|
624
584
|
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
|
625
585
|
break;
|
626
|
-
|
586
|
+
|
627
587
|
case FFI_TYPE_UINT64:
|
628
588
|
case FFI_TYPE_SINT64:
|
629
589
|
#ifdef __s390x__
|
@@ -640,7 +600,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|
640
600
|
*p_arg = &p_ov[n_ov], n_ov += 2;
|
641
601
|
#endif
|
642
602
|
break;
|
643
|
-
|
603
|
+
|
644
604
|
case FFI_TYPE_INT:
|
645
605
|
case FFI_TYPE_UINT32:
|
646
606
|
case FFI_TYPE_SINT32:
|
@@ -649,7 +609,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|
649
609
|
else
|
650
610
|
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
|
651
611
|
break;
|
652
|
-
|
612
|
+
|
653
613
|
case FFI_TYPE_UINT16:
|
654
614
|
case FFI_TYPE_SINT16:
|
655
615
|
if (n_gpr < MAX_GPRARGS)
|
@@ -665,7 +625,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|
665
625
|
else
|
666
626
|
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
|
667
627
|
break;
|
668
|
-
|
628
|
+
|
669
629
|
default:
|
670
630
|
FFI_ASSERT (0);
|
671
631
|
break;
|
@@ -679,14 +639,15 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|
679
639
|
|
680
640
|
|
681
641
|
/* Call the target function. */
|
682
|
-
(
|
642
|
+
(fun) (cif, rvalue, avalue, user_data);
|
683
643
|
|
684
644
|
/* Convert the return value. */
|
685
|
-
switch (
|
645
|
+
switch (cif->rtype->type)
|
686
646
|
{
|
687
647
|
/* Void is easy, and so is struct. */
|
688
648
|
case FFI_TYPE_VOID:
|
689
649
|
case FFI_TYPE_STRUCT:
|
650
|
+
case FFI_TYPE_COMPLEX:
|
690
651
|
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
691
652
|
case FFI_TYPE_LONGDOUBLE:
|
692
653
|
#endif
|
@@ -732,7 +693,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|
732
693
|
break;
|
733
694
|
}
|
734
695
|
}
|
735
|
-
|
696
|
+
|
736
697
|
/*======================== End of Routine ============================*/
|
737
698
|
|
738
699
|
/*====================================================================*/
|
@@ -742,7 +703,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|
742
703
|
/* Function - Prepare a FFI closure. */
|
743
704
|
/* */
|
744
705
|
/*====================================================================*/
|
745
|
-
|
706
|
+
|
746
707
|
ffi_status
|
747
708
|
ffi_prep_closure_loc (ffi_closure *closure,
|
748
709
|
ffi_cif *cif,
|
@@ -750,31 +711,46 @@ ffi_prep_closure_loc (ffi_closure *closure,
|
|
750
711
|
void *user_data,
|
751
712
|
void *codeloc)
|
752
713
|
{
|
753
|
-
|
754
|
-
|
714
|
+
static unsigned short const template[] = {
|
715
|
+
0x0d10, /* basr %r1,0 */
|
755
716
|
#ifndef __s390x__
|
756
|
-
|
757
|
-
*(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */
|
758
|
-
*(short *)&closure->tramp [4] = 0x1006;
|
759
|
-
*(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */
|
760
|
-
*(long *)&closure->tramp [8] = (long)codeloc;
|
761
|
-
*(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
|
717
|
+
0x9801, 0x1006, /* lm %r0,%r1,6(%r1) */
|
762
718
|
#else
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
*(long
|
769
|
-
|
770
|
-
|
771
|
-
|
719
|
+
0xeb01, 0x100e, 0x0004, /* lmg %r0,%r1,14(%r1) */
|
720
|
+
#endif
|
721
|
+
0x07f1 /* br %r1 */
|
722
|
+
};
|
723
|
+
|
724
|
+
unsigned long *tramp = (unsigned long *)&closure->tramp;
|
725
|
+
|
726
|
+
if (cif->abi != FFI_SYSV)
|
727
|
+
return FFI_BAD_ABI;
|
728
|
+
|
729
|
+
memcpy (tramp, template, sizeof(template));
|
730
|
+
tramp[2] = (unsigned long)codeloc;
|
731
|
+
tramp[3] = (unsigned long)&ffi_closure_SYSV;
|
732
|
+
|
772
733
|
closure->cif = cif;
|
773
|
-
closure->user_data = user_data;
|
774
734
|
closure->fun = fun;
|
775
|
-
|
735
|
+
closure->user_data = user_data;
|
736
|
+
|
776
737
|
return FFI_OK;
|
777
738
|
}
|
778
739
|
|
779
740
|
/*======================== End of Routine ============================*/
|
780
|
-
|
741
|
+
|
742
|
+
/* Build a Go language closure. */
|
743
|
+
|
744
|
+
ffi_status
|
745
|
+
ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
|
746
|
+
void (*fun)(ffi_cif*,void*,void**,void*))
|
747
|
+
{
|
748
|
+
if (cif->abi != FFI_SYSV)
|
749
|
+
return FFI_BAD_ABI;
|
750
|
+
|
751
|
+
closure->tramp = ffi_go_closure_SYSV;
|
752
|
+
closure->cif = cif;
|
753
|
+
closure->fun = fun;
|
754
|
+
|
755
|
+
return FFI_OK;
|
756
|
+
}
|