ffi 1.9.18 → 1.9.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +22 -0
- data/.gitmodules +3 -0
- data/.travis.yml +52 -0
- data/.yardopts +5 -0
- data/Gemfile +15 -0
- data/{spec/ffi/LICENSE.SPECS → LICENSE.SPECS} +1 -1
- data/README.md +3 -4
- data/Rakefile +41 -5
- data/appveyor.yml +22 -0
- data/ext/ffi_c/AbstractMemory.c +6 -1
- data/ext/ffi_c/Call.c +1 -22
- data/ext/ffi_c/Call.h +0 -9
- data/ext/ffi_c/Closure.c +54 -0
- data/ext/ffi_c/{ClosurePool.h → Closure.h} +13 -23
- data/ext/ffi_c/Function.c +16 -25
- data/ext/ffi_c/Function.h +1 -2
- data/ext/ffi_c/FunctionInfo.c +0 -4
- data/ext/ffi_c/MethodHandle.c +33 -268
- data/ext/ffi_c/Platform.c +10 -2
- data/ext/ffi_c/extconf.rb +10 -5
- data/ext/ffi_c/ffi.c +2 -2
- data/ext/ffi_c/libffi/.appveyor.yml +48 -0
- data/ext/ffi_c/libffi/.gitignore +36 -0
- data/ext/ffi_c/libffi/.travis/install.sh +14 -0
- data/ext/ffi_c/libffi/.travis.yml +30 -0
- 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 +169 -158
- data/ext/ffi_c/libffi/Makefile.in +927 -938
- data/ext/ffi_c/libffi/README +164 -52
- data/ext/ffi_c/libffi/acinclude.m4 +387 -0
- data/ext/ffi_c/libffi/autogen.sh +2 -0
- data/ext/ffi_c/libffi/config.guess +336 -371
- data/ext/ffi_c/libffi/config.sub +246 -115
- data/ext/ffi_c/libffi/configure +6976 -2189
- data/ext/ffi_c/libffi/configure.ac +148 -256
- data/ext/ffi_c/libffi/configure.host +277 -4
- 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/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +24 -13
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +203 -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 +112 -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 +1043 -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/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 +964 -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 +608 -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 +366 -45
- 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/ia64/unix.S +2 -0
- 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 +103 -28
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +10 -3
- data/ext/ffi_c/libffi/src/mips/n32.S +128 -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 +245 -7
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +253 -4
- 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 +111 -30
- 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 +103 -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 +591 -500
- data/ext/ffi_c/libffi/src/x86/ffi64.c +359 -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 +79 -73
- data/ext/ffi_c/libffi/testsuite/Makefile.in +219 -111
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +121 -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_3float.c +95 -0
- 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/ext/ffi_c/libffi.bsd.mk +11 -5
- data/ext/ffi_c/libffi.darwin.mk +14 -4
- data/ext/ffi_c/libffi.gnu.mk +3 -2
- data/ext/ffi_c/libffi.mk +10 -5
- data/ext/ffi_c/libffi.vc.mk +1 -1
- data/ext/ffi_c/libffi.vc64.mk +1 -1
- data/ffi.gemspec +16 -3
- data/lib/ffi/enum.rb +124 -0
- data/lib/ffi/library.rb +66 -14
- data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
- data/lib/ffi/platform/x86_64-windows/types.conf +113 -20
- data/lib/ffi/platform.rb +7 -2
- data/lib/ffi/pointer.rb +1 -0
- data/lib/ffi/struct.rb +0 -2
- data/lib/ffi/version.rb +1 -2
- data/samples/getlogin.rb +8 -0
- data/samples/getpid.rb +8 -0
- data/samples/gettimeofday.rb +18 -0
- data/samples/hello.rb +7 -0
- data/samples/inotify.rb +60 -0
- data/samples/pty.rb +76 -0
- data/samples/qsort.rb +21 -0
- data/samples/sample_helper.rb +6 -0
- metadata +164 -115
- data/ext/ffi_c/ClosurePool.c +0 -283
- 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/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/include/ffi.h.vc +0 -427
- data/ext/ffi_c/libffi/include/ffi.h.vc64 +0 -427
- 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/mdate-sh +0 -201
- 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
- data/ext/ffi_c/libffi/texinfo.tex +0 -7210
- data/gen/Rakefile +0 -30
- data/libtest/Benchmark.c +0 -52
- data/libtest/BoolTest.c +0 -34
- data/libtest/BufferTest.c +0 -31
- data/libtest/ClosureTest.c +0 -205
- data/libtest/EnumTest.c +0 -51
- data/libtest/FunctionTest.c +0 -70
- data/libtest/GNUmakefile +0 -149
- data/libtest/GlobalVariable.c +0 -62
- data/libtest/LastErrorTest.c +0 -21
- data/libtest/NumberTest.c +0 -132
- data/libtest/PointerTest.c +0 -63
- data/libtest/ReferenceTest.c +0 -23
- data/libtest/StringTest.c +0 -34
- data/libtest/StructTest.c +0 -243
- data/libtest/UnionTest.c +0 -43
- data/libtest/VariadicTest.c +0 -99
- data/spec/ffi/async_callback_spec.rb +0 -35
- data/spec/ffi/bool_spec.rb +0 -32
- data/spec/ffi/buffer_spec.rb +0 -279
- data/spec/ffi/callback_spec.rb +0 -773
- data/spec/ffi/custom_param_type.rb +0 -37
- data/spec/ffi/custom_type_spec.rb +0 -74
- data/spec/ffi/dup_spec.rb +0 -52
- data/spec/ffi/enum_spec.rb +0 -423
- data/spec/ffi/errno_spec.rb +0 -20
- data/spec/ffi/ffi_spec.rb +0 -28
- data/spec/ffi/fixtures/Benchmark.c +0 -52
- data/spec/ffi/fixtures/BoolTest.c +0 -34
- data/spec/ffi/fixtures/BufferTest.c +0 -31
- data/spec/ffi/fixtures/ClosureTest.c +0 -205
- data/spec/ffi/fixtures/EnumTest.c +0 -51
- data/spec/ffi/fixtures/FunctionTest.c +0 -142
- data/spec/ffi/fixtures/GNUmakefile +0 -149
- data/spec/ffi/fixtures/GlobalVariable.c +0 -62
- data/spec/ffi/fixtures/LastErrorTest.c +0 -21
- data/spec/ffi/fixtures/NumberTest.c +0 -132
- data/spec/ffi/fixtures/PipeHelper.h +0 -21
- data/spec/ffi/fixtures/PipeHelperPosix.c +0 -41
- data/spec/ffi/fixtures/PipeHelperWindows.c +0 -72
- data/spec/ffi/fixtures/PointerTest.c +0 -63
- data/spec/ffi/fixtures/ReferenceTest.c +0 -23
- data/spec/ffi/fixtures/StringTest.c +0 -34
- data/spec/ffi/fixtures/StructTest.c +0 -243
- data/spec/ffi/fixtures/UnionTest.c +0 -43
- data/spec/ffi/fixtures/VariadicTest.c +0 -99
- data/spec/ffi/fixtures/classes.rb +0 -438
- data/spec/ffi/function_spec.rb +0 -97
- data/spec/ffi/io_spec.rb +0 -16
- data/spec/ffi/library_spec.rb +0 -286
- data/spec/ffi/long_double.rb +0 -30
- data/spec/ffi/managed_struct_spec.rb +0 -68
- data/spec/ffi/memorypointer_spec.rb +0 -78
- data/spec/ffi/number_spec.rb +0 -247
- data/spec/ffi/platform_spec.rb +0 -114
- data/spec/ffi/pointer_spec.rb +0 -285
- data/spec/ffi/rbx/attach_function_spec.rb +0 -34
- data/spec/ffi/rbx/memory_pointer_spec.rb +0 -194
- data/spec/ffi/rbx/spec_helper.rb +0 -6
- data/spec/ffi/rbx/struct_spec.rb +0 -18
- data/spec/ffi/spec_helper.rb +0 -93
- data/spec/ffi/string_spec.rb +0 -118
- data/spec/ffi/strptr_spec.rb +0 -50
- data/spec/ffi/struct_by_ref_spec.rb +0 -43
- data/spec/ffi/struct_callback_spec.rb +0 -69
- data/spec/ffi/struct_initialize_spec.rb +0 -35
- data/spec/ffi/struct_packed_spec.rb +0 -50
- data/spec/ffi/struct_spec.rb +0 -886
- data/spec/ffi/typedef_spec.rb +0 -91
- data/spec/ffi/union_spec.rb +0 -67
- data/spec/ffi/variadic_spec.rb +0 -132
- data/spec/spec.opts +0 -4
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/* -----------------------------------------------------------------------
|
|
2
|
-
ffi.c - Copyright (c) 2011
|
|
2
|
+
ffi.c - Copyright (c) 2011 Timothy Wall
|
|
3
|
+
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
|
|
3
4
|
Copyright (c) 2011 Anthony Green
|
|
4
5
|
Copyright (c) 2011 Free Software Foundation
|
|
5
6
|
Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
|
|
6
|
-
|
|
7
|
-
ARM Foreign Function Interface
|
|
7
|
+
|
|
8
|
+
ARM Foreign Function Interface
|
|
8
9
|
|
|
9
10
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
10
11
|
a copy of this software and associated documentation files (the
|
|
@@ -27,660 +28,745 @@
|
|
|
27
28
|
DEALINGS IN THE SOFTWARE.
|
|
28
29
|
----------------------------------------------------------------------- */
|
|
29
30
|
|
|
31
|
+
#include <fficonfig.h>
|
|
30
32
|
#include <ffi.h>
|
|
31
33
|
#include <ffi_common.h>
|
|
32
|
-
|
|
34
|
+
#include <stdint.h>
|
|
33
35
|
#include <stdlib.h>
|
|
36
|
+
#include "internal.h"
|
|
37
|
+
|
|
38
|
+
#if FFI_EXEC_TRAMPOLINE_TABLE
|
|
39
|
+
|
|
40
|
+
#ifdef __MACH__
|
|
41
|
+
#include <mach/machine/vm_param.h>
|
|
42
|
+
#endif
|
|
43
|
+
|
|
44
|
+
#else
|
|
45
|
+
extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN;
|
|
46
|
+
#endif
|
|
34
47
|
|
|
35
48
|
/* Forward declares. */
|
|
36
|
-
static int vfp_type_p (ffi_type *);
|
|
49
|
+
static int vfp_type_p (const ffi_type *);
|
|
37
50
|
static void layout_vfp_args (ffi_cif *);
|
|
38
51
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
52
|
+
static void *
|
|
53
|
+
ffi_align (ffi_type *ty, void *p)
|
|
54
|
+
{
|
|
55
|
+
/* Align if necessary */
|
|
56
|
+
size_t alignment;
|
|
57
|
+
#ifdef _WIN32_WCE
|
|
58
|
+
alignment = 4;
|
|
59
|
+
#else
|
|
60
|
+
alignment = ty->alignment;
|
|
61
|
+
if (alignment < 4)
|
|
62
|
+
alignment = 4;
|
|
63
|
+
#endif
|
|
64
|
+
return (void *) FFI_ALIGN (p, alignment);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static size_t
|
|
68
|
+
ffi_put_arg (ffi_type *ty, void *src, void *dst)
|
|
69
|
+
{
|
|
70
|
+
size_t z = ty->size;
|
|
71
|
+
|
|
72
|
+
switch (ty->type)
|
|
73
|
+
{
|
|
74
|
+
case FFI_TYPE_SINT8:
|
|
75
|
+
*(UINT32 *)dst = *(SINT8 *)src;
|
|
76
|
+
break;
|
|
77
|
+
case FFI_TYPE_UINT8:
|
|
78
|
+
*(UINT32 *)dst = *(UINT8 *)src;
|
|
79
|
+
break;
|
|
80
|
+
case FFI_TYPE_SINT16:
|
|
81
|
+
*(UINT32 *)dst = *(SINT16 *)src;
|
|
82
|
+
break;
|
|
83
|
+
case FFI_TYPE_UINT16:
|
|
84
|
+
*(UINT32 *)dst = *(UINT16 *)src;
|
|
85
|
+
break;
|
|
86
|
+
|
|
87
|
+
case FFI_TYPE_INT:
|
|
88
|
+
case FFI_TYPE_SINT32:
|
|
89
|
+
case FFI_TYPE_UINT32:
|
|
90
|
+
case FFI_TYPE_POINTER:
|
|
91
|
+
case FFI_TYPE_FLOAT:
|
|
92
|
+
*(UINT32 *)dst = *(UINT32 *)src;
|
|
93
|
+
break;
|
|
94
|
+
|
|
95
|
+
case FFI_TYPE_SINT64:
|
|
96
|
+
case FFI_TYPE_UINT64:
|
|
97
|
+
case FFI_TYPE_DOUBLE:
|
|
98
|
+
*(UINT64 *)dst = *(UINT64 *)src;
|
|
99
|
+
break;
|
|
100
|
+
|
|
101
|
+
case FFI_TYPE_STRUCT:
|
|
102
|
+
case FFI_TYPE_COMPLEX:
|
|
103
|
+
memcpy (dst, src, z);
|
|
104
|
+
break;
|
|
105
|
+
|
|
106
|
+
default:
|
|
107
|
+
abort();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return FFI_ALIGN (z, 4);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* ffi_prep_args is called once stack space has been allocated
|
|
114
|
+
for the function's arguments.
|
|
115
|
+
|
|
42
116
|
The vfp_space parameter is the load area for VFP regs, the return
|
|
43
117
|
value is cif->vfp_used (word bitset of VFP regs used for passing
|
|
44
118
|
arguments). These are only used for the VFP hard-float ABI.
|
|
45
119
|
*/
|
|
46
|
-
|
|
120
|
+
static void
|
|
121
|
+
ffi_prep_args_SYSV (ffi_cif *cif, int flags, void *rvalue,
|
|
122
|
+
void **avalue, char *argp)
|
|
47
123
|
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
register char *argp;
|
|
51
|
-
register ffi_type **p_arg;
|
|
124
|
+
ffi_type **arg_types = cif->arg_types;
|
|
125
|
+
int i, n;
|
|
52
126
|
|
|
53
|
-
|
|
127
|
+
if (flags == ARM_TYPE_STRUCT)
|
|
128
|
+
{
|
|
129
|
+
*(void **) argp = rvalue;
|
|
130
|
+
argp += 4;
|
|
131
|
+
}
|
|
54
132
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
133
|
+
for (i = 0, n = cif->nargs; i < n; i++)
|
|
134
|
+
{
|
|
135
|
+
ffi_type *ty = arg_types[i];
|
|
136
|
+
argp = ffi_align (ty, argp);
|
|
137
|
+
argp += ffi_put_arg (ty, avalue[i], argp);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
59
140
|
|
|
60
|
-
|
|
141
|
+
static void
|
|
142
|
+
ffi_prep_args_VFP (ffi_cif *cif, int flags, void *rvalue,
|
|
143
|
+
void **avalue, char *stack, char *vfp_space)
|
|
144
|
+
{
|
|
145
|
+
ffi_type **arg_types = cif->arg_types;
|
|
146
|
+
int i, n, vi = 0;
|
|
147
|
+
char *argp, *regp, *eo_regp;
|
|
148
|
+
char stack_used = 0;
|
|
149
|
+
char done_with_regs = 0;
|
|
150
|
+
|
|
151
|
+
/* The first 4 words on the stack are used for values
|
|
152
|
+
passed in core registers. */
|
|
153
|
+
regp = stack;
|
|
154
|
+
eo_regp = argp = regp + 16;
|
|
155
|
+
|
|
156
|
+
/* If the function returns an FFI_TYPE_STRUCT in memory,
|
|
157
|
+
that address is passed in r0 to the function. */
|
|
158
|
+
if (flags == ARM_TYPE_STRUCT)
|
|
159
|
+
{
|
|
160
|
+
*(void **) regp = rvalue;
|
|
161
|
+
regp += 4;
|
|
162
|
+
}
|
|
61
163
|
|
|
62
|
-
for (i =
|
|
63
|
-
(i != 0);
|
|
64
|
-
i--, p_arg++)
|
|
164
|
+
for (i = 0, n = cif->nargs; i < n; i++)
|
|
65
165
|
{
|
|
66
|
-
|
|
166
|
+
ffi_type *ty = arg_types[i];
|
|
167
|
+
void *a = avalue[i];
|
|
168
|
+
int is_vfp_type = vfp_type_p (ty);
|
|
67
169
|
|
|
68
170
|
/* Allocated in VFP registers. */
|
|
69
|
-
if (
|
|
70
|
-
&& vi < ecif->cif->vfp_nargs && vfp_type_p (*p_arg))
|
|
171
|
+
if (vi < cif->vfp_nargs && is_vfp_type)
|
|
71
172
|
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
*((float*)vfp_slot) = *((float*)*p_argv);
|
|
75
|
-
else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
|
|
76
|
-
*((double*)vfp_slot) = *((double*)*p_argv);
|
|
77
|
-
else
|
|
78
|
-
memcpy(vfp_slot, *p_argv, (*p_arg)->size);
|
|
79
|
-
p_argv++;
|
|
173
|
+
char *vfp_slot = vfp_space + cif->vfp_args[vi++] * 4;
|
|
174
|
+
ffi_put_arg (ty, a, vfp_slot);
|
|
80
175
|
continue;
|
|
81
176
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
z = (*p_arg)->size;
|
|
92
|
-
if (z < sizeof(int))
|
|
93
|
-
{
|
|
94
|
-
z = sizeof(int);
|
|
95
|
-
switch ((*p_arg)->type)
|
|
96
|
-
{
|
|
97
|
-
case FFI_TYPE_SINT8:
|
|
98
|
-
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
|
|
99
|
-
break;
|
|
100
|
-
|
|
101
|
-
case FFI_TYPE_UINT8:
|
|
102
|
-
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
|
|
103
|
-
break;
|
|
104
|
-
|
|
105
|
-
case FFI_TYPE_SINT16:
|
|
106
|
-
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
|
|
107
|
-
break;
|
|
108
|
-
|
|
109
|
-
case FFI_TYPE_UINT16:
|
|
110
|
-
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
|
|
111
|
-
break;
|
|
112
|
-
|
|
113
|
-
case FFI_TYPE_STRUCT:
|
|
114
|
-
memcpy(argp, *p_argv, (*p_arg)->size);
|
|
115
|
-
break;
|
|
116
|
-
|
|
117
|
-
default:
|
|
118
|
-
FFI_ASSERT(0);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
else if (z == sizeof(int))
|
|
177
|
+
/* Try allocating in core registers. */
|
|
178
|
+
else if (!done_with_regs && !is_vfp_type)
|
|
179
|
+
{
|
|
180
|
+
char *tregp = ffi_align (ty, regp);
|
|
181
|
+
size_t size = ty->size;
|
|
182
|
+
size = (size < 4) ? 4 : size; // pad
|
|
183
|
+
/* Check if there is space left in the aligned register
|
|
184
|
+
area to place the argument. */
|
|
185
|
+
if (tregp + size <= eo_regp)
|
|
122
186
|
{
|
|
123
|
-
|
|
187
|
+
regp = tregp + ffi_put_arg (ty, a, tregp);
|
|
188
|
+
done_with_regs = (regp == argp);
|
|
189
|
+
// ensure we did not write into the stack area
|
|
190
|
+
FFI_ASSERT (regp <= argp);
|
|
191
|
+
continue;
|
|
124
192
|
}
|
|
125
|
-
|
|
193
|
+
/* In case there are no arguments in the stack area yet,
|
|
194
|
+
the argument is passed in the remaining core registers
|
|
195
|
+
and on the stack. */
|
|
196
|
+
else if (!stack_used)
|
|
126
197
|
{
|
|
127
|
-
|
|
198
|
+
stack_used = 1;
|
|
199
|
+
done_with_regs = 1;
|
|
200
|
+
argp = tregp + ffi_put_arg (ty, a, tregp);
|
|
201
|
+
FFI_ASSERT (eo_regp < argp);
|
|
202
|
+
continue;
|
|
128
203
|
}
|
|
129
|
-
|
|
130
|
-
|
|
204
|
+
}
|
|
205
|
+
/* Base case, arguments are passed on the stack */
|
|
206
|
+
stack_used = 1;
|
|
207
|
+
argp = ffi_align (ty, argp);
|
|
208
|
+
argp += ffi_put_arg (ty, a, argp);
|
|
131
209
|
}
|
|
132
|
-
|
|
133
|
-
/* Indicate the VFP registers used. */
|
|
134
|
-
return ecif->cif->vfp_used;
|
|
135
210
|
}
|
|
136
211
|
|
|
137
212
|
/* Perform machine dependent cif processing */
|
|
138
|
-
ffi_status
|
|
213
|
+
ffi_status
|
|
214
|
+
ffi_prep_cif_machdep (ffi_cif *cif)
|
|
139
215
|
{
|
|
140
|
-
int
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
216
|
+
int flags = 0, cabi = cif->abi;
|
|
217
|
+
size_t bytes = cif->bytes;
|
|
218
|
+
|
|
219
|
+
/* Map out the register placements of VFP register args. The VFP
|
|
220
|
+
hard-float calling conventions are slightly more sophisticated
|
|
221
|
+
than the base calling conventions, so we do it here instead of
|
|
222
|
+
in ffi_prep_args(). */
|
|
223
|
+
if (cabi == FFI_VFP)
|
|
224
|
+
layout_vfp_args (cif);
|
|
145
225
|
|
|
146
226
|
/* Set the return type flag */
|
|
147
227
|
switch (cif->rtype->type)
|
|
148
228
|
{
|
|
149
229
|
case FFI_TYPE_VOID:
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
230
|
+
flags = ARM_TYPE_VOID;
|
|
231
|
+
break;
|
|
232
|
+
|
|
233
|
+
case FFI_TYPE_INT:
|
|
234
|
+
case FFI_TYPE_UINT8:
|
|
235
|
+
case FFI_TYPE_SINT8:
|
|
236
|
+
case FFI_TYPE_UINT16:
|
|
237
|
+
case FFI_TYPE_SINT16:
|
|
238
|
+
case FFI_TYPE_UINT32:
|
|
239
|
+
case FFI_TYPE_SINT32:
|
|
240
|
+
case FFI_TYPE_POINTER:
|
|
241
|
+
flags = ARM_TYPE_INT;
|
|
153
242
|
break;
|
|
154
243
|
|
|
155
244
|
case FFI_TYPE_SINT64:
|
|
156
245
|
case FFI_TYPE_UINT64:
|
|
157
|
-
|
|
246
|
+
flags = ARM_TYPE_INT64;
|
|
247
|
+
break;
|
|
248
|
+
|
|
249
|
+
case FFI_TYPE_FLOAT:
|
|
250
|
+
flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_S : ARM_TYPE_INT);
|
|
251
|
+
break;
|
|
252
|
+
case FFI_TYPE_DOUBLE:
|
|
253
|
+
flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_D : ARM_TYPE_INT64);
|
|
158
254
|
break;
|
|
159
255
|
|
|
160
256
|
case FFI_TYPE_STRUCT:
|
|
161
|
-
|
|
162
|
-
|
|
257
|
+
case FFI_TYPE_COMPLEX:
|
|
258
|
+
if (cabi == FFI_VFP)
|
|
163
259
|
{
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
260
|
+
int h = vfp_type_p (cif->rtype);
|
|
261
|
+
|
|
262
|
+
flags = ARM_TYPE_VFP_N;
|
|
263
|
+
if (h == 0x100 + FFI_TYPE_FLOAT)
|
|
264
|
+
flags = ARM_TYPE_VFP_S;
|
|
265
|
+
if (h == 0x100 + FFI_TYPE_DOUBLE)
|
|
266
|
+
flags = ARM_TYPE_VFP_D;
|
|
267
|
+
if (h != 0)
|
|
268
|
+
break;
|
|
167
269
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
270
|
+
|
|
271
|
+
/* A Composite Type not larger than 4 bytes is returned in r0.
|
|
272
|
+
A Composite Type larger than 4 bytes, or whose size cannot
|
|
273
|
+
be determined statically ... is stored in memory at an
|
|
274
|
+
address passed [in r0]. */
|
|
275
|
+
if (cif->rtype->size <= 4)
|
|
276
|
+
flags = ARM_TYPE_INT;
|
|
171
277
|
else
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
278
|
+
{
|
|
279
|
+
flags = ARM_TYPE_STRUCT;
|
|
280
|
+
bytes += 4;
|
|
281
|
+
}
|
|
176
282
|
break;
|
|
177
283
|
|
|
178
284
|
default:
|
|
179
|
-
|
|
180
|
-
break;
|
|
285
|
+
abort();
|
|
181
286
|
}
|
|
182
287
|
|
|
183
|
-
/*
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
288
|
+
/* Round the stack up to a multiple of 8 bytes. This isn't needed
|
|
289
|
+
everywhere, but it is on some platforms, and it doesn't harm anything
|
|
290
|
+
when it isn't needed. */
|
|
291
|
+
bytes = FFI_ALIGN (bytes, 8);
|
|
292
|
+
|
|
293
|
+
/* Minimum stack space is the 4 register arguments that we pop. */
|
|
294
|
+
if (bytes < 4*4)
|
|
295
|
+
bytes = 4*4;
|
|
296
|
+
|
|
297
|
+
cif->bytes = bytes;
|
|
298
|
+
cif->flags = flags;
|
|
188
299
|
|
|
189
300
|
return FFI_OK;
|
|
190
301
|
}
|
|
191
302
|
|
|
192
|
-
/*
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
|
303
|
+
/* Perform machine dependent cif processing for variadic calls */
|
|
304
|
+
ffi_status
|
|
305
|
+
ffi_prep_cif_machdep_var (ffi_cif * cif,
|
|
306
|
+
unsigned int nfixedargs, unsigned int ntotalargs)
|
|
197
307
|
{
|
|
198
|
-
|
|
308
|
+
/* VFP variadic calls actually use the SYSV ABI */
|
|
309
|
+
if (cif->abi == FFI_VFP)
|
|
310
|
+
cif->abi = FFI_SYSV;
|
|
199
311
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
int vfp_struct = (cif->flags == FFI_TYPE_STRUCT_VFP_FLOAT
|
|
203
|
-
|| cif->flags == FFI_TYPE_STRUCT_VFP_DOUBLE);
|
|
312
|
+
return ffi_prep_cif_machdep (cif);
|
|
313
|
+
}
|
|
204
314
|
|
|
205
|
-
|
|
206
|
-
ecif.avalue = avalue;
|
|
315
|
+
/* Prototypes for assembly functions, in sysv.S. */
|
|
207
316
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
317
|
+
struct call_frame
|
|
318
|
+
{
|
|
319
|
+
void *fp;
|
|
320
|
+
void *lr;
|
|
321
|
+
void *rvalue;
|
|
322
|
+
int flags;
|
|
323
|
+
void *closure;
|
|
324
|
+
};
|
|
212
325
|
|
|
213
|
-
|
|
214
|
-
|
|
326
|
+
extern void ffi_call_SYSV (void *stack, struct call_frame *,
|
|
327
|
+
void (*fn) (void)) FFI_HIDDEN;
|
|
328
|
+
extern void ffi_call_VFP (void *vfp_space, struct call_frame *,
|
|
329
|
+
void (*fn) (void), unsigned vfp_used) FFI_HIDDEN;
|
|
330
|
+
|
|
331
|
+
static void
|
|
332
|
+
ffi_call_int (ffi_cif * cif, void (*fn) (void), void *rvalue,
|
|
333
|
+
void **avalue, void *closure)
|
|
334
|
+
{
|
|
335
|
+
int flags = cif->flags;
|
|
336
|
+
ffi_type *rtype = cif->rtype;
|
|
337
|
+
size_t bytes, rsize, vfp_size;
|
|
338
|
+
char *stack, *vfp_space, *new_rvalue;
|
|
339
|
+
struct call_frame *frame;
|
|
340
|
+
|
|
341
|
+
rsize = 0;
|
|
342
|
+
if (rvalue == NULL)
|
|
215
343
|
{
|
|
216
|
-
|
|
344
|
+
/* If the return value is a struct and we don't have a return
|
|
345
|
+
value address then we need to make one. Otherwise the return
|
|
346
|
+
value is in registers and we can ignore them. */
|
|
347
|
+
if (flags == ARM_TYPE_STRUCT)
|
|
348
|
+
rsize = rtype->size;
|
|
349
|
+
else
|
|
350
|
+
flags = ARM_TYPE_VOID;
|
|
217
351
|
}
|
|
218
|
-
else if (
|
|
219
|
-
ecif.rvalue = &temp;
|
|
220
|
-
else if (vfp_struct)
|
|
352
|
+
else if (flags == ARM_TYPE_VFP_N)
|
|
221
353
|
{
|
|
222
354
|
/* Largest case is double x 4. */
|
|
223
|
-
|
|
355
|
+
rsize = 32;
|
|
224
356
|
}
|
|
225
|
-
else
|
|
226
|
-
|
|
357
|
+
else if (flags == ARM_TYPE_INT && rtype->type == FFI_TYPE_STRUCT)
|
|
358
|
+
rsize = 4;
|
|
227
359
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
case FFI_SYSV:
|
|
231
|
-
ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
|
|
232
|
-
break;
|
|
360
|
+
/* Largest case. */
|
|
361
|
+
vfp_size = (cif->abi == FFI_VFP && cif->vfp_used ? 8*8: 0);
|
|
233
362
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
break;
|
|
363
|
+
bytes = cif->bytes;
|
|
364
|
+
stack = alloca (vfp_size + bytes + sizeof(struct call_frame) + rsize);
|
|
237
365
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
366
|
+
vfp_space = NULL;
|
|
367
|
+
if (vfp_size)
|
|
368
|
+
{
|
|
369
|
+
vfp_space = stack;
|
|
370
|
+
stack += vfp_size;
|
|
241
371
|
}
|
|
242
|
-
if (small_struct)
|
|
243
|
-
memcpy (rvalue, &temp, cif->rtype->size);
|
|
244
|
-
else if (vfp_struct)
|
|
245
|
-
memcpy (rvalue, ecif.rvalue, cif->rtype->size);
|
|
246
|
-
}
|
|
247
372
|
|
|
248
|
-
|
|
373
|
+
frame = (struct call_frame *)(stack + bytes);
|
|
249
374
|
|
|
250
|
-
|
|
251
|
-
|
|
375
|
+
new_rvalue = rvalue;
|
|
376
|
+
if (rsize)
|
|
377
|
+
new_rvalue = (void *)(frame + 1);
|
|
252
378
|
|
|
253
|
-
|
|
379
|
+
frame->rvalue = new_rvalue;
|
|
380
|
+
frame->flags = flags;
|
|
381
|
+
frame->closure = closure;
|
|
254
382
|
|
|
255
|
-
|
|
383
|
+
if (vfp_space)
|
|
384
|
+
{
|
|
385
|
+
ffi_prep_args_VFP (cif, flags, new_rvalue, avalue, stack, vfp_space);
|
|
386
|
+
ffi_call_VFP (vfp_space, frame, fn, cif->vfp_used);
|
|
387
|
+
}
|
|
388
|
+
else
|
|
389
|
+
{
|
|
390
|
+
ffi_prep_args_SYSV (cif, flags, new_rvalue, avalue, stack);
|
|
391
|
+
ffi_call_SYSV (stack, frame, fn);
|
|
392
|
+
}
|
|
256
393
|
|
|
257
|
-
|
|
394
|
+
if (rvalue && rvalue != new_rvalue)
|
|
395
|
+
memcpy (rvalue, new_rvalue, rtype->size);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
void
|
|
399
|
+
ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
|
|
400
|
+
{
|
|
401
|
+
ffi_call_int (cif, fn, rvalue, avalue, NULL);
|
|
402
|
+
}
|
|
258
403
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
void **respp;
|
|
263
|
-
void *args;
|
|
264
|
-
void *vfp_args;
|
|
404
|
+
void
|
|
405
|
+
ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,
|
|
406
|
+
void **avalue, void *closure)
|
|
265
407
|
{
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
void **arg_area;
|
|
408
|
+
ffi_call_int (cif, fn, rvalue, avalue, closure);
|
|
409
|
+
}
|
|
269
410
|
|
|
270
|
-
|
|
271
|
-
|
|
411
|
+
static void *
|
|
412
|
+
ffi_prep_incoming_args_SYSV (ffi_cif *cif, void *rvalue,
|
|
413
|
+
char *argp, void **avalue)
|
|
414
|
+
{
|
|
415
|
+
ffi_type **arg_types = cif->arg_types;
|
|
416
|
+
int i, n;
|
|
272
417
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
418
|
+
if (cif->flags == ARM_TYPE_STRUCT)
|
|
419
|
+
{
|
|
420
|
+
rvalue = *(void **) argp;
|
|
421
|
+
argp += 4;
|
|
422
|
+
}
|
|
423
|
+
else
|
|
424
|
+
{
|
|
425
|
+
if (cif->rtype->size && cif->rtype->size < 4)
|
|
426
|
+
*(uint32_t *) rvalue = 0;
|
|
427
|
+
}
|
|
278
428
|
|
|
279
|
-
|
|
429
|
+
for (i = 0, n = cif->nargs; i < n; i++)
|
|
430
|
+
{
|
|
431
|
+
ffi_type *ty = arg_types[i];
|
|
432
|
+
size_t z = ty->size;
|
|
280
433
|
|
|
281
|
-
|
|
434
|
+
argp = ffi_align (ty, argp);
|
|
435
|
+
avalue[i] = (void *) argp;
|
|
436
|
+
argp += z;
|
|
437
|
+
}
|
|
282
438
|
|
|
283
|
-
return
|
|
439
|
+
return rvalue;
|
|
284
440
|
}
|
|
285
441
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
void **avalue, ffi_cif *cif,
|
|
290
|
-
/* Used only under VFP hard-float ABI. */
|
|
291
|
-
float *vfp_stack)
|
|
292
|
-
/*@=exportheader@*/
|
|
442
|
+
static void *
|
|
443
|
+
ffi_prep_incoming_args_VFP (ffi_cif *cif, void *rvalue, char *stack,
|
|
444
|
+
char *vfp_space, void **avalue)
|
|
293
445
|
{
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
argp = stack;
|
|
446
|
+
ffi_type **arg_types = cif->arg_types;
|
|
447
|
+
int i, n, vi = 0;
|
|
448
|
+
char *argp, *regp, *eo_regp;
|
|
449
|
+
char done_with_regs = 0;
|
|
450
|
+
char stack_used = 0;
|
|
300
451
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
argp += 4;
|
|
304
|
-
}
|
|
452
|
+
regp = stack;
|
|
453
|
+
eo_regp = argp = regp + 16;
|
|
305
454
|
|
|
306
|
-
|
|
455
|
+
if (cif->flags == ARM_TYPE_STRUCT)
|
|
456
|
+
{
|
|
457
|
+
rvalue = *(void **) regp;
|
|
458
|
+
regp += 4;
|
|
459
|
+
}
|
|
307
460
|
|
|
308
|
-
for (i =
|
|
461
|
+
for (i = 0, n = cif->nargs; i < n; i++)
|
|
309
462
|
{
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
463
|
+
ffi_type *ty = arg_types[i];
|
|
464
|
+
int is_vfp_type = vfp_type_p (ty);
|
|
465
|
+
size_t z = ty->size;
|
|
466
|
+
|
|
467
|
+
if (vi < cif->vfp_nargs && is_vfp_type)
|
|
315
468
|
{
|
|
316
|
-
|
|
469
|
+
avalue[i] = vfp_space + cif->vfp_args[vi++] * 4;
|
|
317
470
|
continue;
|
|
318
471
|
}
|
|
472
|
+
else if (!done_with_regs && !is_vfp_type)
|
|
473
|
+
{
|
|
474
|
+
char *tregp = ffi_align (ty, regp);
|
|
319
475
|
|
|
320
|
-
|
|
321
|
-
if (alignment < 4)
|
|
322
|
-
alignment = 4;
|
|
323
|
-
/* Align if necessary */
|
|
324
|
-
if ((alignment - 1) & (unsigned) argp) {
|
|
325
|
-
argp = (char *) ALIGN(argp, alignment);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
z = (*p_arg)->size;
|
|
329
|
-
|
|
330
|
-
/* because we're little endian, this is what it turns into. */
|
|
476
|
+
z = (z < 4) ? 4 : z; // pad
|
|
331
477
|
|
|
332
|
-
|
|
478
|
+
/* If the arguments either fits into the registers or uses registers
|
|
479
|
+
and stack, while we haven't read other things from the stack */
|
|
480
|
+
if (tregp + z <= eo_regp || !stack_used)
|
|
481
|
+
{
|
|
482
|
+
/* Because we're little endian, this is what it turns into. */
|
|
483
|
+
avalue[i] = (void *) tregp;
|
|
484
|
+
regp = tregp + z;
|
|
485
|
+
|
|
486
|
+
/* If we read past the last core register, make sure we
|
|
487
|
+
have not read from the stack before and continue
|
|
488
|
+
reading after regp. */
|
|
489
|
+
if (regp > eo_regp)
|
|
490
|
+
{
|
|
491
|
+
FFI_ASSERT (!stack_used);
|
|
492
|
+
argp = regp;
|
|
493
|
+
}
|
|
494
|
+
if (regp >= eo_regp)
|
|
495
|
+
{
|
|
496
|
+
done_with_regs = 1;
|
|
497
|
+
stack_used = 1;
|
|
498
|
+
}
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
333
502
|
|
|
334
|
-
|
|
503
|
+
stack_used = 1;
|
|
504
|
+
argp = ffi_align (ty, argp);
|
|
505
|
+
avalue[i] = (void *) argp;
|
|
335
506
|
argp += z;
|
|
336
507
|
}
|
|
337
|
-
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
508
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
#if FFI_EXEC_TRAMPOLINE_TABLE
|
|
344
|
-
|
|
345
|
-
#include <mach/mach.h>
|
|
346
|
-
#include <pthread.h>
|
|
347
|
-
#include <stdio.h>
|
|
348
|
-
#include <stdlib.h>
|
|
349
|
-
|
|
350
|
-
extern void *ffi_closure_trampoline_table_page;
|
|
351
|
-
|
|
352
|
-
typedef struct ffi_trampoline_table ffi_trampoline_table;
|
|
353
|
-
typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry;
|
|
354
|
-
|
|
355
|
-
struct ffi_trampoline_table {
|
|
356
|
-
/* contigious writable and executable pages */
|
|
357
|
-
vm_address_t config_page;
|
|
358
|
-
vm_address_t trampoline_page;
|
|
359
|
-
|
|
360
|
-
/* free list tracking */
|
|
361
|
-
uint16_t free_count;
|
|
362
|
-
ffi_trampoline_table_entry *free_list;
|
|
363
|
-
ffi_trampoline_table_entry *free_list_pool;
|
|
364
|
-
|
|
365
|
-
ffi_trampoline_table *prev;
|
|
366
|
-
ffi_trampoline_table *next;
|
|
367
|
-
};
|
|
509
|
+
return rvalue;
|
|
510
|
+
}
|
|
368
511
|
|
|
369
|
-
struct
|
|
370
|
-
|
|
371
|
-
|
|
512
|
+
struct closure_frame
|
|
513
|
+
{
|
|
514
|
+
char vfp_space[8*8] __attribute__((aligned(8)));
|
|
515
|
+
char result[8*4];
|
|
516
|
+
char argp[];
|
|
372
517
|
};
|
|
373
518
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
/* The trampoline configuration is placed at 4080 bytes prior to the trampoline's entry point */
|
|
380
|
-
#define FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc) ((void **) (((uint8_t *) codeloc) - 4080));
|
|
381
|
-
|
|
382
|
-
/* The first 16 bytes of the config page are unused, as they are unaddressable from the trampoline page. */
|
|
383
|
-
#define FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET 16
|
|
384
|
-
|
|
385
|
-
/* Total number of trampolines that fit in one trampoline table */
|
|
386
|
-
#define FFI_TRAMPOLINE_COUNT ((PAGE_SIZE - FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET) / FFI_TRAMPOLINE_SIZE)
|
|
387
|
-
|
|
388
|
-
static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
389
|
-
static ffi_trampoline_table *ffi_trampoline_tables = NULL;
|
|
390
|
-
|
|
391
|
-
static ffi_trampoline_table *
|
|
392
|
-
ffi_trampoline_table_alloc ()
|
|
519
|
+
int FFI_HIDDEN
|
|
520
|
+
ffi_closure_inner_SYSV (ffi_cif *cif,
|
|
521
|
+
void (*fun) (ffi_cif *, void *, void **, void *),
|
|
522
|
+
void *user_data,
|
|
523
|
+
struct closure_frame *frame)
|
|
393
524
|
{
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
/* Try to allocate two pages */
|
|
402
|
-
kt = vm_allocate (mach_task_self (), &config_page, PAGE_SIZE*2, VM_FLAGS_ANYWHERE);
|
|
403
|
-
if (kt != KERN_SUCCESS) {
|
|
404
|
-
fprintf(stderr, "vm_allocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
|
|
405
|
-
break;
|
|
406
|
-
}
|
|
525
|
+
void **avalue = (void **) alloca (cif->nargs * sizeof (void *));
|
|
526
|
+
void *rvalue = ffi_prep_incoming_args_SYSV (cif, frame->result,
|
|
527
|
+
frame->argp, avalue);
|
|
528
|
+
fun (cif, rvalue, avalue, user_data);
|
|
529
|
+
return cif->flags;
|
|
530
|
+
}
|
|
407
531
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
532
|
+
int FFI_HIDDEN
|
|
533
|
+
ffi_closure_inner_VFP (ffi_cif *cif,
|
|
534
|
+
void (*fun) (ffi_cif *, void *, void **, void *),
|
|
535
|
+
void *user_data,
|
|
536
|
+
struct closure_frame *frame)
|
|
537
|
+
{
|
|
538
|
+
void **avalue = (void **) alloca (cif->nargs * sizeof (void *));
|
|
539
|
+
void *rvalue = ffi_prep_incoming_args_VFP (cif, frame->result, frame->argp,
|
|
540
|
+
frame->vfp_space, avalue);
|
|
541
|
+
fun (cif, rvalue, avalue, user_data);
|
|
542
|
+
return cif->flags;
|
|
543
|
+
}
|
|
415
544
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
545
|
+
void ffi_closure_SYSV (void) FFI_HIDDEN;
|
|
546
|
+
void ffi_closure_VFP (void) FFI_HIDDEN;
|
|
547
|
+
void ffi_go_closure_SYSV (void) FFI_HIDDEN;
|
|
548
|
+
void ffi_go_closure_VFP (void) FFI_HIDDEN;
|
|
419
549
|
|
|
420
|
-
|
|
550
|
+
/* the cif must already be prep'ed */
|
|
421
551
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
552
|
+
ffi_status
|
|
553
|
+
ffi_prep_closure_loc (ffi_closure * closure,
|
|
554
|
+
ffi_cif * cif,
|
|
555
|
+
void (*fun) (ffi_cif *, void *, void **, void *),
|
|
556
|
+
void *user_data, void *codeloc)
|
|
557
|
+
{
|
|
558
|
+
void (*closure_func) (void) = ffi_closure_SYSV;
|
|
428
559
|
|
|
429
|
-
|
|
430
|
-
|
|
560
|
+
if (cif->abi == FFI_VFP)
|
|
561
|
+
{
|
|
562
|
+
/* We only need take the vfp path if there are vfp arguments. */
|
|
563
|
+
if (cif->vfp_used)
|
|
564
|
+
closure_func = ffi_closure_VFP;
|
|
431
565
|
}
|
|
566
|
+
else if (cif->abi != FFI_SYSV)
|
|
567
|
+
return FFI_BAD_ABI;
|
|
432
568
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
entry->next = &table->free_list_pool[i+1];
|
|
449
|
-
}
|
|
569
|
+
#if FFI_EXEC_TRAMPOLINE_TABLE
|
|
570
|
+
void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);
|
|
571
|
+
config[0] = closure;
|
|
572
|
+
config[1] = closure_func;
|
|
573
|
+
#else
|
|
574
|
+
memcpy (closure->tramp, ffi_arm_trampoline, 8);
|
|
575
|
+
#if defined (__QNX__)
|
|
576
|
+
msync(closure->tramp, 8, 0x1000000); /* clear data map */
|
|
577
|
+
msync(codeloc, 8, 0x1000000); /* clear insn map */
|
|
578
|
+
#else
|
|
579
|
+
__clear_cache(closure->tramp, closure->tramp + 8); /* clear data map */
|
|
580
|
+
__clear_cache(codeloc, codeloc + 8); /* clear insn map */
|
|
581
|
+
#endif
|
|
582
|
+
*(void (**)(void))(closure->tramp + 8) = closure_func;
|
|
583
|
+
#endif
|
|
450
584
|
|
|
451
|
-
|
|
452
|
-
|
|
585
|
+
closure->cif = cif;
|
|
586
|
+
closure->fun = fun;
|
|
587
|
+
closure->user_data = user_data;
|
|
453
588
|
|
|
454
|
-
return
|
|
589
|
+
return FFI_OK;
|
|
455
590
|
}
|
|
456
591
|
|
|
457
|
-
|
|
458
|
-
|
|
592
|
+
ffi_status
|
|
593
|
+
ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
|
|
594
|
+
void (*fun) (ffi_cif *, void *, void **, void *))
|
|
459
595
|
{
|
|
460
|
-
|
|
461
|
-
ffi_closure *closure = malloc(size);
|
|
462
|
-
if (closure == NULL)
|
|
463
|
-
return NULL;
|
|
464
|
-
|
|
465
|
-
pthread_mutex_lock(&ffi_trampoline_lock);
|
|
466
|
-
|
|
467
|
-
/* Check for an active trampoline table with available entries. */
|
|
468
|
-
ffi_trampoline_table *table = ffi_trampoline_tables;
|
|
469
|
-
if (table == NULL || table->free_list == NULL) {
|
|
470
|
-
table = ffi_trampoline_table_alloc ();
|
|
471
|
-
if (table == NULL) {
|
|
472
|
-
free(closure);
|
|
473
|
-
return NULL;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
/* Insert the new table at the top of the list */
|
|
477
|
-
table->next = ffi_trampoline_tables;
|
|
478
|
-
if (table->next != NULL)
|
|
479
|
-
table->next->prev = table;
|
|
596
|
+
void (*closure_func) (void) = ffi_go_closure_SYSV;
|
|
480
597
|
|
|
481
|
-
|
|
482
|
-
|
|
598
|
+
if (cif->abi == FFI_VFP)
|
|
599
|
+
{
|
|
600
|
+
/* We only need take the vfp path if there are vfp arguments. */
|
|
601
|
+
if (cif->vfp_used)
|
|
602
|
+
closure_func = ffi_go_closure_VFP;
|
|
603
|
+
}
|
|
604
|
+
else if (cif->abi != FFI_SYSV)
|
|
605
|
+
return FFI_BAD_ABI;
|
|
483
606
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
ffi_trampoline_tables->free_count--;
|
|
488
|
-
entry->next = NULL;
|
|
607
|
+
closure->tramp = closure_func;
|
|
608
|
+
closure->cif = cif;
|
|
609
|
+
closure->fun = fun;
|
|
489
610
|
|
|
490
|
-
|
|
611
|
+
return FFI_OK;
|
|
612
|
+
}
|
|
491
613
|
|
|
492
|
-
|
|
493
|
-
*code = entry->trampoline;
|
|
494
|
-
closure->trampoline_table = table;
|
|
495
|
-
closure->trampoline_table_entry = entry;
|
|
614
|
+
/* Below are routines for VFP hard-float support. */
|
|
496
615
|
|
|
497
|
-
return
|
|
498
|
-
|
|
616
|
+
/* A subroutine of vfp_type_p. Given a structure type, return the type code
|
|
617
|
+
of the first non-structure element. Recurse for structure elements.
|
|
618
|
+
Return -1 if the structure is in fact empty, i.e. no nested elements. */
|
|
499
619
|
|
|
500
|
-
|
|
501
|
-
|
|
620
|
+
static int
|
|
621
|
+
is_hfa0 (const ffi_type *ty)
|
|
502
622
|
{
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
pthread_mutex_lock(&ffi_trampoline_lock);
|
|
506
|
-
|
|
507
|
-
/* Fetch the table and entry references */
|
|
508
|
-
ffi_trampoline_table *table = closure->trampoline_table;
|
|
509
|
-
ffi_trampoline_table_entry *entry = closure->trampoline_table_entry;
|
|
510
|
-
|
|
511
|
-
/* Return the entry to the free list */
|
|
512
|
-
entry->next = table->free_list;
|
|
513
|
-
table->free_list = entry;
|
|
514
|
-
table->free_count++;
|
|
515
|
-
|
|
516
|
-
/* If all trampolines within this table are free, and at least one other table exists, deallocate
|
|
517
|
-
* the table */
|
|
518
|
-
if (table->free_count == FFI_TRAMPOLINE_COUNT && ffi_trampoline_tables != table) {
|
|
519
|
-
/* Remove from the list */
|
|
520
|
-
if (table->prev != NULL)
|
|
521
|
-
table->prev->next = table->next;
|
|
522
|
-
|
|
523
|
-
if (table->next != NULL)
|
|
524
|
-
table->next->prev = table->prev;
|
|
525
|
-
|
|
526
|
-
/* Deallocate pages */
|
|
527
|
-
kern_return_t kt;
|
|
528
|
-
kt = vm_deallocate (mach_task_self (), table->config_page, PAGE_SIZE);
|
|
529
|
-
if (kt != KERN_SUCCESS)
|
|
530
|
-
fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
|
|
531
|
-
|
|
532
|
-
kt = vm_deallocate (mach_task_self (), table->trampoline_page, PAGE_SIZE);
|
|
533
|
-
if (kt != KERN_SUCCESS)
|
|
534
|
-
fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
|
|
535
|
-
|
|
536
|
-
/* Deallocate free list */
|
|
537
|
-
free (table->free_list_pool);
|
|
538
|
-
free (table);
|
|
539
|
-
} else if (ffi_trampoline_tables != table) {
|
|
540
|
-
/* Otherwise, bump this table to the top of the list */
|
|
541
|
-
table->prev = NULL;
|
|
542
|
-
table->next = ffi_trampoline_tables;
|
|
543
|
-
if (ffi_trampoline_tables != NULL)
|
|
544
|
-
ffi_trampoline_tables->prev = table;
|
|
545
|
-
|
|
546
|
-
ffi_trampoline_tables = table;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
pthread_mutex_unlock (&ffi_trampoline_lock);
|
|
550
|
-
|
|
551
|
-
/* Free the closure */
|
|
552
|
-
free (closure);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
#else
|
|
623
|
+
ffi_type **elements = ty->elements;
|
|
624
|
+
int i, ret = -1;
|
|
556
625
|
|
|
557
|
-
|
|
558
|
-
(
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
/* Clear instruction \
|
|
570
|
-
mapping. */ \
|
|
571
|
-
})
|
|
626
|
+
if (elements != NULL)
|
|
627
|
+
for (i = 0; elements[i]; ++i)
|
|
628
|
+
{
|
|
629
|
+
ret = elements[i]->type;
|
|
630
|
+
if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX)
|
|
631
|
+
{
|
|
632
|
+
ret = is_hfa0 (elements[i]);
|
|
633
|
+
if (ret < 0)
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
break;
|
|
637
|
+
}
|
|
572
638
|
|
|
573
|
-
|
|
639
|
+
return ret;
|
|
640
|
+
}
|
|
574
641
|
|
|
575
|
-
/*
|
|
642
|
+
/* A subroutine of vfp_type_p. Given a structure type, return true if all
|
|
643
|
+
of the non-structure elements are the same as CANDIDATE. */
|
|
576
644
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
ffi_cif* cif,
|
|
580
|
-
void (*fun)(ffi_cif*,void*,void**,void*),
|
|
581
|
-
void *user_data,
|
|
582
|
-
void *codeloc)
|
|
645
|
+
static int
|
|
646
|
+
is_hfa1 (const ffi_type *ty, int candidate)
|
|
583
647
|
{
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
if (cif->abi == FFI_SYSV)
|
|
587
|
-
closure_func = &ffi_closure_SYSV;
|
|
588
|
-
else if (cif->abi == FFI_VFP)
|
|
589
|
-
closure_func = &ffi_closure_VFP;
|
|
590
|
-
else
|
|
591
|
-
return FFI_BAD_ABI;
|
|
592
|
-
|
|
593
|
-
#if FFI_EXEC_TRAMPOLINE_TABLE
|
|
594
|
-
void **config = FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc);
|
|
595
|
-
config[0] = closure;
|
|
596
|
-
config[1] = closure_func;
|
|
597
|
-
#else
|
|
598
|
-
FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
|
|
599
|
-
closure_func, \
|
|
600
|
-
codeloc);
|
|
601
|
-
#endif
|
|
648
|
+
ffi_type **elements = ty->elements;
|
|
649
|
+
int i;
|
|
602
650
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
651
|
+
if (elements != NULL)
|
|
652
|
+
for (i = 0; elements[i]; ++i)
|
|
653
|
+
{
|
|
654
|
+
int t = elements[i]->type;
|
|
655
|
+
if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
|
|
656
|
+
{
|
|
657
|
+
if (!is_hfa1 (elements[i], candidate))
|
|
658
|
+
return 0;
|
|
659
|
+
}
|
|
660
|
+
else if (t != candidate)
|
|
661
|
+
return 0;
|
|
662
|
+
}
|
|
606
663
|
|
|
607
|
-
return
|
|
664
|
+
return 1;
|
|
608
665
|
}
|
|
609
666
|
|
|
610
|
-
/*
|
|
667
|
+
/* Determine if TY is an homogenous floating point aggregate (HFA).
|
|
668
|
+
That is, a structure consisting of 1 to 4 members of all the same type,
|
|
669
|
+
where that type is a floating point scalar.
|
|
611
670
|
|
|
612
|
-
|
|
671
|
+
Returns non-zero iff TY is an HFA. The result is an encoded value where
|
|
672
|
+
bits 0-7 contain the type code, and bits 8-10 contain the element count. */
|
|
673
|
+
|
|
674
|
+
static int
|
|
675
|
+
vfp_type_p (const ffi_type *ty)
|
|
613
676
|
{
|
|
614
|
-
|
|
677
|
+
ffi_type **elements;
|
|
678
|
+
int candidate, i;
|
|
679
|
+
size_t size, ele_count;
|
|
680
|
+
|
|
681
|
+
/* Quickest tests first. */
|
|
682
|
+
candidate = ty->type;
|
|
683
|
+
switch (ty->type)
|
|
615
684
|
{
|
|
685
|
+
default:
|
|
686
|
+
return 0;
|
|
616
687
|
case FFI_TYPE_FLOAT:
|
|
617
688
|
case FFI_TYPE_DOUBLE:
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
689
|
+
ele_count = 1;
|
|
690
|
+
goto done;
|
|
691
|
+
case FFI_TYPE_COMPLEX:
|
|
692
|
+
candidate = ty->elements[0]->type;
|
|
693
|
+
if (candidate != FFI_TYPE_FLOAT && candidate != FFI_TYPE_DOUBLE)
|
|
694
|
+
return 0;
|
|
695
|
+
ele_count = 2;
|
|
696
|
+
goto done;
|
|
697
|
+
case FFI_TYPE_STRUCT:
|
|
698
|
+
break;
|
|
699
|
+
}
|
|
621
700
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
701
|
+
/* No HFA types are smaller than 4 bytes, or larger than 32 bytes. */
|
|
702
|
+
size = ty->size;
|
|
703
|
+
if (size < 4 || size > 32)
|
|
704
|
+
return 0;
|
|
626
705
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
706
|
+
/* Find the type of the first non-structure member. */
|
|
707
|
+
elements = ty->elements;
|
|
708
|
+
candidate = elements[0]->type;
|
|
709
|
+
if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX)
|
|
710
|
+
{
|
|
711
|
+
for (i = 0; ; ++i)
|
|
712
|
+
{
|
|
713
|
+
candidate = is_hfa0 (elements[i]);
|
|
714
|
+
if (candidate >= 0)
|
|
715
|
+
break;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
631
718
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
*elt = base_elt;
|
|
649
|
-
return 1;
|
|
650
|
-
}
|
|
651
|
-
default: ;
|
|
719
|
+
/* If the first member is not a floating point type, it's not an HFA.
|
|
720
|
+
Also quickly re-check the size of the structure. */
|
|
721
|
+
switch (candidate)
|
|
722
|
+
{
|
|
723
|
+
case FFI_TYPE_FLOAT:
|
|
724
|
+
ele_count = size / sizeof(float);
|
|
725
|
+
if (size != ele_count * sizeof(float))
|
|
726
|
+
return 0;
|
|
727
|
+
break;
|
|
728
|
+
case FFI_TYPE_DOUBLE:
|
|
729
|
+
ele_count = size / sizeof(double);
|
|
730
|
+
if (size != ele_count * sizeof(double))
|
|
731
|
+
return 0;
|
|
732
|
+
break;
|
|
733
|
+
default:
|
|
734
|
+
return 0;
|
|
652
735
|
}
|
|
653
|
-
|
|
654
|
-
|
|
736
|
+
if (ele_count > 4)
|
|
737
|
+
return 0;
|
|
655
738
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
int elt, elnum;
|
|
659
|
-
if (rec_vfp_type_p (t, &elt, &elnum))
|
|
739
|
+
/* Finally, make sure that all scalar elements are the same type. */
|
|
740
|
+
for (i = 0; elements[i]; ++i)
|
|
660
741
|
{
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
return (int) t->type;
|
|
742
|
+
int t = elements[i]->type;
|
|
743
|
+
if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
|
|
744
|
+
{
|
|
745
|
+
if (!is_hfa1 (elements[i], candidate))
|
|
746
|
+
return 0;
|
|
747
|
+
}
|
|
748
|
+
else if (t != candidate)
|
|
749
|
+
return 0;
|
|
671
750
|
}
|
|
672
|
-
|
|
751
|
+
|
|
752
|
+
/* All tests succeeded. Encode the result. */
|
|
753
|
+
done:
|
|
754
|
+
return (ele_count << 8) | candidate;
|
|
673
755
|
}
|
|
674
756
|
|
|
675
|
-
static
|
|
757
|
+
static int
|
|
758
|
+
place_vfp_arg (ffi_cif *cif, int h)
|
|
676
759
|
{
|
|
677
|
-
|
|
678
|
-
int nregs =
|
|
679
|
-
|
|
680
|
-
|
|
760
|
+
unsigned short reg = cif->vfp_reg_free;
|
|
761
|
+
int align = 1, nregs = h >> 8;
|
|
762
|
+
|
|
763
|
+
if ((h & 0xff) == FFI_TYPE_DOUBLE)
|
|
764
|
+
align = 2, nregs *= 2;
|
|
765
|
+
|
|
681
766
|
/* Align register number. */
|
|
682
767
|
if ((reg & 1) && align == 2)
|
|
683
768
|
reg++;
|
|
769
|
+
|
|
684
770
|
while (reg + nregs <= 16)
|
|
685
771
|
{
|
|
686
772
|
int s, new_used = 0;
|
|
@@ -705,24 +791,29 @@ static void place_vfp_arg (ffi_cif *cif, ffi_type *t)
|
|
|
705
791
|
reg += 1;
|
|
706
792
|
cif->vfp_reg_free = reg;
|
|
707
793
|
}
|
|
708
|
-
return;
|
|
709
|
-
next_reg
|
|
794
|
+
return 0;
|
|
795
|
+
next_reg:;
|
|
710
796
|
}
|
|
797
|
+
// done, mark all regs as used
|
|
798
|
+
cif->vfp_reg_free = 16;
|
|
799
|
+
cif->vfp_used = 0xFFFF;
|
|
800
|
+
return 1;
|
|
711
801
|
}
|
|
712
802
|
|
|
713
|
-
static void
|
|
803
|
+
static void
|
|
804
|
+
layout_vfp_args (ffi_cif * cif)
|
|
714
805
|
{
|
|
715
806
|
int i;
|
|
716
807
|
/* Init VFP fields */
|
|
717
808
|
cif->vfp_used = 0;
|
|
718
809
|
cif->vfp_nargs = 0;
|
|
719
810
|
cif->vfp_reg_free = 0;
|
|
720
|
-
memset (cif->vfp_args, -1, 16);
|
|
811
|
+
memset (cif->vfp_args, -1, 16); /* Init to -1. */
|
|
721
812
|
|
|
722
813
|
for (i = 0; i < cif->nargs; i++)
|
|
723
814
|
{
|
|
724
|
-
|
|
725
|
-
if (
|
|
726
|
-
|
|
815
|
+
int h = vfp_type_p (cif->arg_types[i]);
|
|
816
|
+
if (h && place_vfp_arg (cif, h) == 1)
|
|
817
|
+
break;
|
|
727
818
|
}
|
|
728
819
|
}
|