ffi 1.0.0 → 1.17.1
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 +7 -0
- checksums.yaml.gz.sig +4 -0
- data/CHANGELOG.md +465 -0
- data/COPYING +49 -0
- data/Gemfile +21 -0
- data/LICENSE +21 -11
- data/LICENSE.SPECS +22 -0
- data/README.md +137 -0
- data/Rakefile +165 -148
- data/ext/ffi_c/AbstractMemory.c +716 -97
- data/ext/ffi_c/AbstractMemory.h +38 -17
- data/ext/ffi_c/ArrayType.c +102 -33
- data/ext/ffi_c/ArrayType.h +20 -18
- data/ext/ffi_c/Buffer.c +229 -54
- data/ext/ffi_c/Call.c +211 -100
- data/ext/ffi_c/Call.h +46 -28
- data/ext/ffi_c/ClosurePool.c +110 -81
- data/ext/ffi_c/ClosurePool.h +31 -1
- data/ext/ffi_c/DynamicLibrary.c +216 -54
- data/ext/ffi_c/DynamicLibrary.h +76 -0
- data/ext/ffi_c/Function.c +527 -164
- data/ext/ffi_c/Function.h +24 -20
- data/ext/ffi_c/FunctionInfo.c +151 -50
- data/ext/ffi_c/LastError.c +112 -28
- data/ext/ffi_c/LastError.h +29 -0
- data/ext/ffi_c/LongDouble.c +65 -0
- data/ext/ffi_c/LongDouble.h +47 -0
- data/ext/ffi_c/MappedType.c +107 -42
- data/ext/ffi_c/MappedType.h +20 -20
- data/ext/ffi_c/MemoryPointer.c +108 -46
- data/ext/ffi_c/MemoryPointer.h +33 -4
- data/ext/ffi_c/MethodHandle.c +71 -67
- data/ext/ffi_c/MethodHandle.h +26 -23
- data/ext/ffi_c/Platform.c +42 -25
- data/ext/ffi_c/Platform.h +32 -3
- data/ext/ffi_c/Pointer.c +324 -51
- data/ext/ffi_c/Pointer.h +29 -18
- data/ext/ffi_c/Struct.c +434 -161
- data/ext/ffi_c/Struct.h +47 -27
- data/ext/ffi_c/StructByValue.c +74 -37
- data/ext/ffi_c/StructByValue.h +20 -18
- data/ext/ffi_c/StructLayout.c +358 -87
- data/ext/ffi_c/Thread.c +129 -0
- data/ext/ffi_c/Thread.h +76 -0
- data/ext/ffi_c/Type.c +241 -76
- data/ext/ffi_c/Type.h +27 -11
- data/ext/ffi_c/Types.c +54 -34
- data/ext/ffi_c/Types.h +24 -24
- data/ext/ffi_c/Variadic.c +151 -55
- data/ext/ffi_c/compat.h +48 -38
- data/ext/ffi_c/extconf.rb +106 -34
- data/ext/ffi_c/ffi.c +35 -26
- data/ext/ffi_c/libffi/.allow-ai-service +0 -0
- data/ext/ffi_c/libffi/.appveyor/site.exp +16 -0
- data/ext/ffi_c/libffi/.appveyor/unix-noexec.exp +7 -0
- data/ext/ffi_c/libffi/.appveyor.yml +84 -0
- data/ext/ffi_c/libffi/.ci/ar-lib +270 -0
- data/ext/ffi_c/libffi/.ci/bfin-sim.exp +58 -0
- data/ext/ffi_c/libffi/.ci/build-cross-in-container.sh +18 -0
- data/ext/ffi_c/libffi/.ci/build-in-container.sh +10 -0
- data/ext/ffi_c/libffi/.ci/build.sh +124 -0
- data/ext/ffi_c/libffi/.ci/compile +351 -0
- data/ext/ffi_c/libffi/.ci/install.sh +78 -0
- data/ext/ffi_c/libffi/.ci/m32r-sim.exp +58 -0
- data/ext/ffi_c/libffi/.ci/moxie-sim.exp +60 -0
- data/ext/ffi_c/libffi/.ci/msvs-detect +1103 -0
- data/ext/ffi_c/libffi/.ci/or1k-sim.exp +58 -0
- data/ext/ffi_c/libffi/.ci/powerpc-eabisim.exp +58 -0
- data/ext/ffi_c/libffi/.ci/site.exp +29 -0
- data/ext/ffi_c/libffi/.ci/wine-sim.exp +55 -0
- data/ext/ffi_c/libffi/.circleci/config.yml +156 -0
- data/ext/ffi_c/libffi/.gitattributes +4 -0
- data/ext/ffi_c/libffi/.github/issue_template.md +10 -0
- data/ext/ffi_c/libffi/.github/workflows/build.yml +479 -0
- data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +172 -0
- data/ext/ffi_c/libffi/.gitignore +46 -0
- data/ext/ffi_c/libffi/{ChangeLog → ChangeLog.old} +6528 -3180
- data/ext/ffi_c/libffi/LICENSE +3 -3
- data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +353 -0
- data/ext/ffi_c/libffi/Makefile.am +132 -162
- data/ext/ffi_c/libffi/Makefile.in +1339 -1003
- data/ext/ffi_c/libffi/README.md +531 -0
- data/ext/ffi_c/libffi/acinclude.m4 +289 -4
- data/ext/ffi_c/libffi/autogen.sh +2 -0
- data/ext/ffi_c/libffi/compile +227 -21
- data/ext/ffi_c/libffi/config.guess +1034 -778
- data/ext/ffi_c/libffi/config.sub +1394 -1204
- data/ext/ffi_c/libffi/configure +14327 -8503
- data/ext/ffi_c/libffi/configure.ac +294 -247
- data/ext/ffi_c/libffi/configure.host +330 -4
- data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
- data/ext/ffi_c/libffi/doc/Makefile.in +818 -0
- data/ext/ffi_c/libffi/doc/libffi.texi +572 -67
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +53 -46
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +312 -0
- data/ext/ffi_c/libffi/include/Makefile.am +3 -3
- data/ext/ffi_c/libffi/include/Makefile.in +219 -79
- data/ext/ffi_c/libffi/include/ffi.h.in +230 -111
- data/ext/ffi_c/libffi/include/ffi_cfi.h +76 -0
- data/ext/ffi_c/libffi/include/ffi_common.h +78 -16
- data/ext/ffi_c/libffi/include/tramp.h +45 -0
- data/ext/ffi_c/libffi/install-sh +402 -184
- data/ext/ffi_c/libffi/libffi.map.in +81 -0
- data/ext/ffi_c/libffi/libffi.pc.in +3 -2
- data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +997 -0
- data/ext/ffi_c/libffi/libtool-ldflags +106 -0
- data/ext/ffi_c/libffi/libtool-version +2 -2
- data/ext/ffi_c/libffi/ltmain.sh +5752 -2722
- data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
- data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +50 -0
- data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +198 -0
- data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +158 -0
- data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +53 -0
- data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +119 -0
- data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +49 -0
- data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +302 -0
- data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +267 -0
- data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +89 -0
- data/ext/ffi_c/libffi/m4/ax_prepend_flag.m4 +51 -0
- data/ext/ffi_c/libffi/m4/ax_require_defined.m4 +37 -0
- data/ext/ffi_c/libffi/make_sunver.pl +333 -0
- data/ext/ffi_c/libffi/man/Makefile.am +2 -2
- data/ext/ffi_c/libffi/man/Makefile.in +174 -57
- 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 +155 -300
- data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.sln +33 -0
- data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj +130 -0
- data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters +57 -0
- data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.user +4 -0
- data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +511 -0
- data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/fficonfig.h +219 -0
- data/ext/ffi_c/libffi/msvcc.sh +353 -0
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +1142 -0
- data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +97 -0
- data/ext/ffi_c/libffi/src/aarch64/internal.h +100 -0
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +695 -0
- data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +506 -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 +162 -246
- data/ext/ffi_c/libffi/src/arc/arcompact.S +210 -0
- data/ext/ffi_c/libffi/src/arc/ffi.c +443 -0
- data/ext/ffi_c/libffi/src/arc/ffitarget.h +67 -0
- data/ext/ffi_c/libffi/src/arm/ffi.c +806 -194
- data/ext/ffi_c/libffi/src/arm/ffitarget.h +43 -3
- data/ext/ffi_c/libffi/src/arm/internal.h +17 -0
- data/ext/ffi_c/libffi/src/arm/sysv.S +381 -231
- data/ext/ffi_c/libffi/src/arm/sysv_msvc_arm32.S +311 -0
- data/ext/ffi_c/libffi/src/avr32/ffi.c +4 -2
- data/ext/ffi_c/libffi/src/avr32/ffitarget.h +8 -3
- 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 +574 -100
- data/ext/ffi_c/libffi/src/cris/ffi.c +11 -8
- data/ext/ffi_c/libffi/src/cris/ffitarget.h +8 -3
- data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
- data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
- data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
- data/ext/ffi_c/libffi/src/debug.c +8 -3
- data/ext/ffi_c/libffi/src/dlmalloc.c +89 -17
- data/ext/ffi_c/libffi/src/frv/ffi.c +2 -2
- data/ext/ffi_c/libffi/src/frv/ffitarget.h +8 -7
- data/ext/ffi_c/libffi/src/ia64/ffi.c +48 -12
- data/ext/ffi_c/libffi/src/ia64/ffitarget.h +10 -4
- data/ext/ffi_c/libffi/src/ia64/unix.S +28 -3
- data/ext/ffi_c/libffi/src/java_raw_api.c +24 -6
- data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
- data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
- data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
- data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
- data/ext/ffi_c/libffi/src/loongarch64/ffi.c +624 -0
- data/ext/ffi_c/libffi/src/loongarch64/ffitarget.h +82 -0
- data/ext/ffi_c/libffi/src/loongarch64/sysv.S +327 -0
- data/ext/ffi_c/libffi/src/m32r/ffi.c +32 -15
- data/ext/ffi_c/libffi/src/m32r/ffitarget.h +8 -3
- data/ext/ffi_c/libffi/src/m68k/ffi.c +97 -13
- data/ext/ffi_c/libffi/src/m68k/ffitarget.h +8 -3
- data/ext/ffi_c/libffi/src/m68k/sysv.S +148 -25
- 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/src/metag/ffitarget.h +53 -0
- 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 +392 -104
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +40 -24
- data/ext/ffi_c/libffi/src/mips/n32.S +325 -93
- data/ext/ffi_c/libffi/src/mips/o32.S +211 -31
- data/ext/ffi_c/libffi/src/moxie/eabi.S +101 -0
- data/ext/ffi_c/libffi/src/moxie/ffi.c +310 -0
- 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 +341 -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/ffi.c +68 -111
- data/ext/ffi_c/libffi/src/pa/ffi64.c +614 -0
- data/ext/ffi_c/libffi/src/pa/ffitarget.h +34 -17
- data/ext/ffi_c/libffi/src/pa/hpux32.S +87 -38
- data/ext/ffi_c/libffi/src/pa/hpux64.S +681 -0
- data/ext/ffi_c/libffi/src/pa/linux.S +109 -39
- data/ext/ffi_c/libffi/src/powerpc/aix.S +250 -8
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +255 -4
- data/ext/ffi_c/libffi/src/powerpc/asm.h +3 -3
- data/ext/ffi_c/libffi/src/powerpc/darwin.S +211 -78
- data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +356 -102
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +108 -1375
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +746 -210
- data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +1153 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +105 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +126 -48
- data/ext/ffi_c/libffi/src/powerpc/linux64.S +191 -85
- data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +438 -108
- data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +138 -68
- data/ext/ffi_c/libffi/src/powerpc/sysv.S +73 -119
- data/ext/ffi_c/libffi/src/powerpc/t-aix +5 -0
- data/ext/ffi_c/libffi/src/prep_cif.c +141 -32
- data/ext/ffi_c/libffi/src/raw_api.c +18 -5
- data/ext/ffi_c/libffi/src/riscv/ffi.c +514 -0
- data/ext/ffi_c/libffi/src/riscv/ffitarget.h +69 -0
- data/ext/ffi_c/libffi/src/riscv/sysv.S +293 -0
- data/ext/ffi_c/libffi/src/s390/ffi.c +294 -318
- data/ext/ffi_c/libffi/src/s390/ffitarget.h +13 -3
- 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 +8 -3
- data/ext/ffi_c/libffi/src/sh64/ffi.c +3 -2
- data/ext/ffi_c/libffi/src/sh64/ffitarget.h +8 -3
- data/ext/ffi_c/libffi/src/sparc/ffi.c +334 -491
- data/ext/ffi_c/libffi/src/sparc/ffi64.c +630 -0
- data/ext/ffi_c/libffi/src/sparc/ffitarget.h +20 -5
- 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/tramp.c +716 -0
- data/ext/ffi_c/libffi/src/types.c +48 -19
- 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/wasm32/ffi.c +947 -0
- data/ext/ffi_c/libffi/src/wasm32/ffitarget.h +62 -0
- data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
- data/ext/ffi_c/libffi/src/x86/ffi.c +690 -540
- data/ext/ffi_c/libffi/src/x86/ffi64.c +450 -126
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +86 -42
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +361 -0
- data/ext/ffi_c/libffi/src/x86/internal.h +43 -0
- data/ext/ffi_c/libffi/src/x86/internal64.h +36 -0
- data/ext/ffi_c/libffi/src/x86/sysv.S +1199 -381
- data/ext/ffi_c/libffi/src/x86/sysv_intel.S +998 -0
- data/ext/ffi_c/libffi/src/x86/unix64.S +587 -298
- data/ext/ffi_c/libffi/src/x86/win64.S +251 -457
- data/ext/ffi_c/libffi/src/x86/win64_intel.S +238 -0
- data/ext/ffi_c/libffi/src/xtensa/ffi.c +306 -0
- data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +57 -0
- data/ext/ffi_c/libffi/src/xtensa/sysv.S +268 -0
- data/ext/ffi_c/libffi/stamp-h.in +1 -0
- data/ext/ffi_c/libffi/testsuite/Makefile.am +80 -73
- data/ext/ffi_c/libffi/testsuite/Makefile.in +251 -117
- data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +54 -0
- data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +63 -0
- data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +86 -0
- data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +48 -0
- data/ext/ffi_c/libffi/testsuite/emscripten/test.html +7 -0
- data/ext/ffi_c/libffi/testsuite/emscripten/test_libffi.py +51 -0
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +682 -0
- data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +22 -2
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/Makefile +28 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/README +78 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/alignof.h +50 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +63 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +1746 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2885 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +747 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/align_stdcall.c +46 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/bpo_38748.c +41 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +28 -10
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback2.c +108 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback3.c +114 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback4.c +119 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +4 -3
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +88 -42
- data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +3 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +15 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +4 -2
- data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +110 -0
- 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/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_ll1.c +6 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +4 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +4 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/s55.c +60 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +9 -10
- 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/struct10.c +57 -0
- 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/struct_by_value_2.c +63 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3.c +65 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3f.c +65 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4.c +67 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4f.c +67 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_big.c +93 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_small.c +61 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_2H.c +63 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_8H.c +90 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +78 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_2.c +220 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_3.c +154 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +134 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +134 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +140 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure.exp +67 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn0.c +3 -2
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn1.c +2 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn2.c +2 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn3.c +21 -1
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn4.c +2 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn5.c +2 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn6.c +2 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_loc_fn0.c +7 -6
- data/ext/ffi_c/libffi/testsuite/{libffi.call/closure_stdcall.c → libffi.closures/closure_simple.c} +13 -16
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_12byte.c +22 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_16byte.c +26 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_18byte.c +28 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_19byte.c +33 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_1_1byte.c +8 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_20byte.c +23 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_20byte1.c +25 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_24byte.c +40 -8
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_2byte.c +17 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3_1byte.c +23 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3byte1.c +17 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3byte2.c +17 -4
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3float.c +113 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_4_1byte.c +26 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_4byte.c +17 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_5_1_byte.c +33 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_5byte.c +23 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_64byte.c +29 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_6_1_byte.c +32 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_6byte.c +28 -6
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_7_1_byte.c +43 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_7byte.c +29 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_8byte.c +18 -4
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_9byte1.c +18 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_9byte2.c +18 -6
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_double.c +23 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_float.c +23 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble.c +24 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble_split.c +44 -31
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble_split2.c +44 -9
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_pointer.c +23 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint16.c +22 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint32.c +22 -7
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint64.c +23 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint16.c +22 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint32.c +23 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint64.c +24 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_dbls_struct.c +7 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_double_va.c +21 -9
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_float.c +4 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_longdouble.c +13 -3
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_longdouble_va.c +34 -11
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_args.c +70 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_float_double.c +55 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_schar.c +5 -1
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_sshort.c +6 -1
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_sshortchar.c +9 -1
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_uchar.c +9 -1
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_ushort.c +6 -2
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_ushortchar.c +9 -1
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_pointer.c +7 -2
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_pointer_stack.c +22 -10
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_schar.c +3 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_sint.c +2 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_sshort.c +3 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_struct_va1.c +125 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uchar.c +3 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uint.c +4 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint_va.c +49 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulong_va.c +49 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ulonglong.c +8 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ushort.c +3 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/err_bad_abi.c +2 -3
- data/ext/ffi_c/libffi/testsuite/libffi.closures/ffitest.h +1 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/huge_struct.c +57 -56
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct.c +38 -15
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct1.c +9 -9
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct10.c +19 -6
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct11.c +137 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct12.c +86 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct13.c +115 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct2.c +15 -6
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct3.c +15 -6
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct4.c +14 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct5.c +14 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct6.c +17 -6
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct7.c +14 -5
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct8.c +17 -6
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct9.c +17 -6
- data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs1.c +86 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs2.c +102 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs3.c +101 -0
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_large.c +7 -7
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_large2.c +7 -7
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_medium.c +6 -6
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_medium2.c +7 -6
- data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/testclosure.c +8 -3
- data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.closures}/unwindtest.cc +4 -10
- data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.closures}/unwindtest_ffi_call.cc +4 -2
- 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 -10
- 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 +14 -8
- data/ext/ffi_c/libffi.darwin.mk +56 -26
- data/ext/ffi_c/libffi.gnu.mk +9 -6
- data/ext/ffi_c/libffi.mk +13 -8
- data/ext/ffi_c/libffi.vc.mk +26 -0
- data/ext/ffi_c/libffi.vc64.mk +26 -0
- data/ext/ffi_c/rbffi.h +34 -6
- data/ext/ffi_c/{endian.h → rbffi_endian.h} +21 -2
- data/ffi.gemspec +42 -0
- data/lib/ffi/abstract_memory.rb +44 -0
- data/lib/ffi/autopointer.rb +111 -52
- data/lib/ffi/compat.rb +43 -0
- data/lib/ffi/data_converter.rb +67 -0
- data/lib/ffi/dynamic_library.rb +118 -0
- data/lib/ffi/enum.rb +203 -22
- data/lib/ffi/errno.rb +27 -12
- data/lib/ffi/ffi.rb +88 -11
- data/lib/ffi/function.rb +71 -0
- data/lib/ffi/io.rb +35 -14
- data/lib/ffi/library.rb +382 -96
- data/lib/ffi/library_path.rb +109 -0
- data/lib/ffi/managedstruct.rb +64 -35
- data/lib/ffi/memorypointer.rb +1 -33
- data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
- data/lib/ffi/platform/aarch64-freebsd/types.conf +128 -0
- data/lib/ffi/platform/aarch64-freebsd12/types.conf +181 -0
- data/lib/ffi/platform/aarch64-linux/types.conf +175 -0
- data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
- data/lib/ffi/platform/aarch64-windows/types.conf +52 -0
- data/lib/ffi/platform/arm-freebsd/types.conf +152 -0
- data/lib/ffi/platform/arm-freebsd12/types.conf +152 -0
- data/lib/ffi/platform/arm-linux/types.conf +132 -0
- data/lib/ffi/platform/hppa1.1-linux/types.conf +178 -0
- data/lib/ffi/platform/hppa2.0-linux/types.conf +178 -0
- data/lib/ffi/platform/i386-cygwin/types.conf +3 -0
- data/lib/ffi/platform/i386-darwin/types.conf +100 -0
- data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
- data/lib/ffi/platform/i386-freebsd12/types.conf +152 -0
- data/lib/ffi/platform/i386-gnu/types.conf +107 -0
- data/lib/ffi/platform/i386-linux/types.conf +103 -0
- data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
- data/lib/ffi/platform/i386-openbsd/types.conf +128 -0
- data/lib/ffi/platform/i386-solaris/types.conf +122 -0
- data/lib/ffi/platform/i386-windows/types.conf +52 -0
- data/lib/ffi/platform/ia64-linux/types.conf +104 -0
- data/lib/ffi/platform/loongarch64-linux/types.conf +141 -0
- data/lib/ffi/platform/mips-linux/types.conf +102 -0
- data/lib/ffi/platform/mips64-linux/types.conf +104 -0
- data/lib/ffi/platform/mips64el-linux/types.conf +104 -0
- data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
- data/lib/ffi/platform/mipsisa32r6-linux/types.conf +102 -0
- data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +102 -0
- data/lib/ffi/platform/mipsisa64r6-linux/types.conf +104 -0
- data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +104 -0
- data/lib/ffi/platform/powerpc-aix/types.conf +180 -0
- data/lib/ffi/platform/powerpc-darwin/types.conf +100 -0
- data/lib/ffi/platform/powerpc-linux/types.conf +130 -0
- data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
- data/lib/ffi/platform/powerpc64-linux/types.conf +104 -0
- data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
- data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
- data/lib/ffi/platform/s390-linux/types.conf +102 -0
- data/lib/ffi/platform/s390x-linux/types.conf +102 -0
- data/lib/ffi/platform/sparc-linux/types.conf +102 -0
- data/lib/ffi/platform/sparc-solaris/types.conf +128 -0
- data/lib/ffi/platform/sparcv9-linux/types.conf +102 -0
- data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
- data/lib/ffi/platform/sparcv9-solaris/types.conf +128 -0
- data/lib/ffi/platform/sw_64-linux/types.conf +141 -0
- data/lib/ffi/platform/x86_64-cygwin/types.conf +3 -0
- data/lib/ffi/platform/x86_64-darwin/types.conf +130 -0
- data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +130 -0
- data/lib/ffi/platform/x86_64-freebsd/types.conf +128 -0
- data/lib/ffi/platform/x86_64-freebsd12/types.conf +158 -0
- data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
- data/lib/ffi/platform/x86_64-linux/types.conf +132 -0
- data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
- data/lib/ffi/platform/x86_64-netbsd/types.conf +128 -0
- data/lib/ffi/platform/x86_64-openbsd/types.conf +134 -0
- data/lib/ffi/platform/x86_64-solaris/types.conf +122 -0
- data/lib/ffi/platform/x86_64-windows/types.conf +52 -0
- data/lib/ffi/platform.rb +110 -34
- data/lib/ffi/pointer.rb +117 -90
- data/lib/ffi/struct.rb +101 -70
- data/lib/ffi/struct_by_reference.rb +72 -0
- data/lib/ffi/struct_layout.rb +96 -0
- data/lib/ffi/struct_layout_builder.rb +90 -21
- data/lib/ffi/tools/const_generator.rb +86 -31
- data/lib/ffi/tools/generator.rb +49 -2
- data/lib/ffi/tools/generator_task.rb +13 -16
- data/lib/ffi/tools/struct_generator.rb +6 -5
- data/lib/ffi/tools/types_generator.rb +25 -11
- data/lib/ffi/types.rb +105 -36
- data/lib/ffi/union.rb +23 -12
- data/lib/ffi/variadic.rb +44 -29
- data/lib/ffi/version.rb +3 -0
- data/lib/ffi.rb +25 -9
- data/rakelib/ffi_gem_helper.rb +65 -0
- data/samples/getlogin.rb +8 -0
- data/samples/getpid.rb +8 -0
- data/samples/gettimeofday.rb +18 -0
- data/samples/hello.rb +8 -0
- data/samples/hello_ractor.rb +11 -0
- data/samples/inotify.rb +60 -0
- data/samples/pty.rb +75 -0
- data/samples/qsort.rb +20 -0
- data/samples/qsort_ractor.rb +28 -0
- data/sig/ffi/abstract_memory.rbs +165 -0
- data/sig/ffi/auto_pointer.rbs +26 -0
- data/sig/ffi/buffer.rbs +18 -0
- data/sig/ffi/data_converter.rbs +10 -0
- data/sig/ffi/dynamic_library.rbs +9 -0
- data/sig/ffi/enum.rbs +38 -0
- data/sig/ffi/function.rbs +39 -0
- data/sig/ffi/library.rbs +42 -0
- data/sig/ffi/native_type.rbs +86 -0
- data/sig/ffi/pointer.rbs +42 -0
- data/sig/ffi/struct.rbs +76 -0
- data/sig/ffi/struct_by_reference.rbs +11 -0
- data/sig/ffi/struct_by_value.rbs +7 -0
- data/sig/ffi/struct_layout.rbs +9 -0
- data/sig/ffi/struct_layout_builder.rbs +5 -0
- data/sig/ffi/type.rbs +39 -0
- data/sig/ffi.rbs +26 -0
- data.tar.gz.sig +0 -0
- metadata +547 -248
- metadata.gz.sig +0 -0
- data/History.txt +0 -109
- data/README.rdoc +0 -70
- data/ext/ffi_c/DataConverter.c +0 -62
- data/ext/ffi_c/StructByReference.c +0 -150
- data/ext/ffi_c/StructByReference.h +0 -50
- data/ext/ffi_c/libffi/ChangeLog.libffi +0 -658
- data/ext/ffi_c/libffi/ChangeLog.libgcj +0 -40
- data/ext/ffi_c/libffi/ChangeLog.v1 +0 -764
- data/ext/ffi_c/libffi/README +0 -306
- data/ext/ffi_c/libffi/aclocal.m4 +0 -8998
- data/ext/ffi_c/libffi/depcomp +0 -584
- data/ext/ffi_c/libffi/doc/libffi.info +0 -533
- data/ext/ffi_c/libffi/doc/stamp-vti +0 -4
- data/ext/ffi_c/libffi/m4/libtool.m4 +0 -7360
- data/ext/ffi_c/libffi/m4/ltoptions.m4 +0 -368
- 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 -92
- data/ext/ffi_c/libffi/mdate-sh +0 -201
- 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 -877
- 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 -14
- data/spec/ffi/async_callback_spec.rb +0 -23
- data/spec/ffi/bool_spec.rb +0 -24
- data/spec/ffi/buffer_spec.rb +0 -202
- data/spec/ffi/callback_spec.rb +0 -653
- data/spec/ffi/custom_param_type.rb +0 -31
- data/spec/ffi/custom_type_spec.rb +0 -73
- data/spec/ffi/enum_spec.rb +0 -183
- data/spec/ffi/errno_spec.rb +0 -13
- data/spec/ffi/ffi_spec.rb +0 -24
- data/spec/ffi/function_spec.rb +0 -73
- data/spec/ffi/library_spec.rb +0 -174
- data/spec/ffi/managed_struct_spec.rb +0 -56
- data/spec/ffi/number_spec.rb +0 -231
- data/spec/ffi/pointer_spec.rb +0 -210
- data/spec/ffi/rbx/attach_function_spec.rb +0 -28
- data/spec/ffi/rbx/memory_pointer_spec.rb +0 -109
- data/spec/ffi/rbx/spec_helper.rb +0 -1
- data/spec/ffi/rbx/struct_spec.rb +0 -13
- data/spec/ffi/spec_helper.rb +0 -21
- data/spec/ffi/string_spec.rb +0 -103
- data/spec/ffi/strptr_spec.rb +0 -36
- data/spec/ffi/struct_callback_spec.rb +0 -64
- data/spec/ffi/struct_initialize_spec.rb +0 -30
- data/spec/ffi/struct_packed_spec.rb +0 -46
- data/spec/ffi/struct_spec.rb +0 -638
- data/spec/ffi/typedef_spec.rb +0 -62
- data/spec/ffi/union_spec.rb +0 -60
- data/spec/ffi/variadic_spec.rb +0 -84
- data/spec/spec.opts +0 -4
- data/tasks/ann.rake +0 -80
- data/tasks/extension.rake +0 -25
- data/tasks/gem.rake +0 -200
- data/tasks/git.rake +0 -41
- data/tasks/notes.rake +0 -27
- data/tasks/post_load.rake +0 -34
- data/tasks/rdoc.rake +0 -50
- data/tasks/rubyforge.rake +0 -55
- data/tasks/setup.rb +0 -301
- data/tasks/spec.rake +0 -54
- data/tasks/svn.rake +0 -47
- data/tasks/test.rake +0 -40
- /data/ext/ffi_c/libffi/testsuite/libffi.call/{pyobjc-tc.c → pyobjc_tc.c} +0 -0
- /data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_double.c +0 -0
- /data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/problem1.c +0 -0
data/ext/ffi_c/Function.c
CHANGED
@@ -1,40 +1,56 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c) 2009
|
3
|
-
|
4
|
-
* All rights reserved.
|
2
|
+
* Copyright (c) 2009-2011 Wayne Meissner
|
5
3
|
*
|
6
|
-
*
|
7
|
-
*
|
8
|
-
* This code is free software: you can redistribute it and/or modify it under
|
9
|
-
* the terms of the GNU Lesser General Public License version 3 only, as
|
10
|
-
* published by the Free Software Foundation.
|
4
|
+
* Copyright (c) 2008-2013, Ruby FFI project contributors
|
5
|
+
* All rights reserved.
|
11
6
|
*
|
12
|
-
*
|
13
|
-
*
|
14
|
-
*
|
15
|
-
*
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
8
|
+
* modification, are permitted provided that the following conditions are met:
|
9
|
+
* * Redistributions of source code must retain the above copyright
|
10
|
+
* notice, this list of conditions and the following disclaimer.
|
11
|
+
* * Redistributions in binary form must reproduce the above copyright
|
12
|
+
* notice, this list of conditions and the following disclaimer in the
|
13
|
+
* documentation and/or other materials provided with the distribution.
|
14
|
+
* * Neither the name of the Ruby FFI project nor the
|
15
|
+
* names of its contributors may be used to endorse or promote products
|
16
|
+
* derived from this software without specific prior written permission.
|
16
17
|
*
|
17
|
-
*
|
18
|
-
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
19
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
22
|
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
24
|
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
25
|
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
26
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
27
|
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
19
28
|
*/
|
20
29
|
|
21
|
-
#
|
22
|
-
|
23
|
-
|
30
|
+
#ifndef _MSC_VER
|
24
31
|
#include <sys/param.h>
|
32
|
+
#endif
|
25
33
|
#include <sys/types.h>
|
26
34
|
#ifndef _WIN32
|
27
35
|
# include <sys/mman.h>
|
36
|
+
# include <unistd.h>
|
28
37
|
#endif
|
38
|
+
|
29
39
|
#include <stdio.h>
|
30
40
|
#include <stdint.h>
|
31
41
|
#include <stdbool.h>
|
32
42
|
#include <ruby.h>
|
43
|
+
#include <ruby/thread.h>
|
44
|
+
|
45
|
+
#if HAVE_RB_EXT_RACTOR_SAFE
|
46
|
+
#include <ruby/ractor.h>
|
47
|
+
#endif
|
33
48
|
|
34
49
|
#include <ffi.h>
|
35
50
|
#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32)
|
36
51
|
#include <pthread.h>
|
37
52
|
#endif
|
53
|
+
#include <fcntl.h>
|
38
54
|
|
39
55
|
#include "rbffi.h"
|
40
56
|
#include "compat.h"
|
@@ -47,106 +63,245 @@
|
|
47
63
|
#include "LastError.h"
|
48
64
|
#include "Call.h"
|
49
65
|
#include "ClosurePool.h"
|
50
|
-
#include "Function.h"
|
51
66
|
#include "MappedType.h"
|
67
|
+
#include "Thread.h"
|
68
|
+
#include "LongDouble.h"
|
69
|
+
#include "MethodHandle.h"
|
70
|
+
#include "Function.h"
|
71
|
+
|
72
|
+
#define DEFER_ASYNC_CALLBACK 1
|
52
73
|
|
74
|
+
struct async_cb_dispatcher;
|
53
75
|
typedef struct Function_ {
|
54
|
-
|
76
|
+
Pointer base;
|
55
77
|
FunctionType* info;
|
56
78
|
MethodHandle* methodHandle;
|
57
79
|
bool autorelease;
|
58
80
|
Closure* closure;
|
59
81
|
VALUE rbProc;
|
60
82
|
VALUE rbFunctionInfo;
|
83
|
+
#if defined(DEFER_ASYNC_CALLBACK)
|
84
|
+
struct async_cb_dispatcher *dispatcher;
|
85
|
+
#endif
|
61
86
|
} Function;
|
62
87
|
|
63
|
-
static void function_mark(
|
64
|
-
static void
|
88
|
+
static void function_mark(void *data);
|
89
|
+
static void function_compact(void *data);
|
90
|
+
static void function_free(void *data);
|
91
|
+
static size_t function_memsize(const void *data);
|
65
92
|
static VALUE function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc);
|
66
93
|
static void callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data);
|
67
94
|
static bool callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize);
|
68
95
|
static void* callback_with_gvl(void* data);
|
69
|
-
|
70
|
-
|
71
|
-
# define DEFER_ASYNC_CALLBACK 1
|
72
|
-
#endif
|
96
|
+
static VALUE invoke_callback(VALUE data);
|
97
|
+
static VALUE save_callback_exception(VALUE data, VALUE exc);
|
73
98
|
|
74
99
|
#if defined(DEFER_ASYNC_CALLBACK)
|
75
|
-
static VALUE async_cb_event(void);
|
100
|
+
static VALUE async_cb_event(void *);
|
76
101
|
static VALUE async_cb_call(void *);
|
77
102
|
#endif
|
78
103
|
|
79
|
-
#if defined(HAVE_NATIVETHREAD) && defined (HAVE_RB_THREAD_BLOCKING_REGION)
|
80
|
-
# define DEFER_ASYNC_CALLBACK
|
81
|
-
#endif
|
82
|
-
|
83
|
-
#ifdef HAVE_RUBY_THREAD_HAS_GVL_P
|
84
104
|
extern int ruby_thread_has_gvl_p(void);
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
105
|
+
extern int ruby_native_thread_p(void);
|
106
|
+
|
107
|
+
static const rb_data_type_t function_data_type = {
|
108
|
+
.wrap_struct_name = "FFI::Function",
|
109
|
+
.function = {
|
110
|
+
.dmark = function_mark,
|
111
|
+
.dfree = function_free,
|
112
|
+
.dsize = function_memsize,
|
113
|
+
ffi_compact_callback( function_compact )
|
114
|
+
},
|
115
|
+
.parent = &rbffi_pointer_data_type,
|
116
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
117
|
+
// macro to update VALUE references, as to trigger write barriers.
|
118
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
|
119
|
+
};
|
90
120
|
|
91
121
|
VALUE rbffi_FunctionClass = Qnil;
|
92
122
|
|
93
|
-
#if defined(DEFER_ASYNC_CALLBACK)
|
94
|
-
static VALUE async_cb_thread = Qnil;
|
95
|
-
#endif
|
96
|
-
|
97
123
|
static ID id_call = 0, id_to_native = 0, id_from_native = 0, id_cbtable = 0, id_cb_ref = 0;
|
98
124
|
|
99
125
|
struct gvl_callback {
|
100
126
|
Closure* closure;
|
101
127
|
void* retval;
|
102
128
|
void** parameters;
|
103
|
-
|
129
|
+
bool done;
|
130
|
+
rbffi_frame_t *frame;
|
104
131
|
#if defined(DEFER_ASYNC_CALLBACK)
|
132
|
+
struct async_cb_dispatcher *dispatcher;
|
105
133
|
struct gvl_callback* next;
|
134
|
+
|
135
|
+
/* Signal when the callback has finished and retval is set */
|
106
136
|
# ifndef _WIN32
|
107
137
|
pthread_cond_t async_cond;
|
108
138
|
pthread_mutex_t async_mutex;
|
139
|
+
# else
|
140
|
+
HANDLE async_event;
|
109
141
|
# endif
|
110
142
|
#endif
|
111
143
|
};
|
112
144
|
|
113
145
|
|
114
146
|
#if defined(DEFER_ASYNC_CALLBACK)
|
115
|
-
|
147
|
+
struct async_cb_dispatcher {
|
148
|
+
/* the Ractor-local dispatcher thread */
|
149
|
+
VALUE thread;
|
150
|
+
|
151
|
+
/* single linked list of pending callbacks */
|
152
|
+
struct gvl_callback* async_cb_list;
|
153
|
+
|
154
|
+
/* Signal new entries in async_cb_list */
|
116
155
|
# ifndef _WIN32
|
117
|
-
|
118
|
-
|
156
|
+
pthread_mutex_t async_cb_mutex;
|
157
|
+
pthread_cond_t async_cb_cond;
|
158
|
+
# else
|
159
|
+
HANDLE async_cb_cond;
|
160
|
+
CRITICAL_SECTION async_cb_lock;
|
119
161
|
# endif
|
162
|
+
};
|
163
|
+
|
164
|
+
#if HAVE_RB_EXT_RACTOR_SAFE
|
165
|
+
static void
|
166
|
+
async_cb_dispatcher_mark(void *ptr)
|
167
|
+
{
|
168
|
+
struct async_cb_dispatcher *ctx = (struct async_cb_dispatcher *)ptr;
|
169
|
+
if (ctx) {
|
170
|
+
rb_gc_mark(ctx->thread);
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
static void
|
175
|
+
async_cb_dispatcher_free(void *ptr)
|
176
|
+
{
|
177
|
+
struct async_cb_dispatcher *ctx = (struct async_cb_dispatcher *)ptr;
|
178
|
+
if (ctx) {
|
179
|
+
xfree(ctx);
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
struct rb_ractor_local_storage_type async_cb_dispatcher_key_type = {
|
184
|
+
async_cb_dispatcher_mark,
|
185
|
+
async_cb_dispatcher_free,
|
186
|
+
};
|
187
|
+
|
188
|
+
static rb_ractor_local_key_t async_cb_dispatcher_key;
|
189
|
+
|
190
|
+
static struct async_cb_dispatcher *
|
191
|
+
async_cb_dispatcher_get(void)
|
192
|
+
{
|
193
|
+
struct async_cb_dispatcher *ctx = (struct async_cb_dispatcher *)rb_ractor_local_storage_ptr(async_cb_dispatcher_key);
|
194
|
+
return ctx;
|
195
|
+
}
|
196
|
+
|
197
|
+
static void
|
198
|
+
async_cb_dispatcher_set(struct async_cb_dispatcher *ctx)
|
199
|
+
{
|
200
|
+
rb_ractor_local_storage_ptr_set(async_cb_dispatcher_key, ctx);
|
201
|
+
}
|
202
|
+
#else
|
203
|
+
// for ruby 2.x
|
204
|
+
static struct async_cb_dispatcher *async_cb_dispatcher = NULL;
|
205
|
+
|
206
|
+
static struct async_cb_dispatcher *
|
207
|
+
async_cb_dispatcher_get(void)
|
208
|
+
{
|
209
|
+
return async_cb_dispatcher;
|
210
|
+
}
|
211
|
+
|
212
|
+
static void
|
213
|
+
async_cb_dispatcher_set(struct async_cb_dispatcher *ctx)
|
214
|
+
{
|
215
|
+
async_cb_dispatcher = ctx;
|
216
|
+
}
|
217
|
+
#endif
|
218
|
+
|
219
|
+
static void
|
220
|
+
async_cb_dispatcher_initialize(struct async_cb_dispatcher *ctx)
|
221
|
+
{
|
222
|
+
ctx->async_cb_list = NULL;
|
223
|
+
|
224
|
+
#if !defined(_WIN32)
|
225
|
+
/* n.b. we _used_ to try and destroy the mutex/cond before initializing here,
|
226
|
+
* but it's undefined what happens if you try and destory an unitialized cond.
|
227
|
+
* glibc in particular seems to wait for any concurrent waiters to finish before
|
228
|
+
* destroying a condvar, trying to destroy a condvar after fork that someone was
|
229
|
+
* waiting on pre-fork won't work. Just re-init he memory directly. */
|
230
|
+
pthread_mutex_init(&ctx->async_cb_mutex, NULL);
|
231
|
+
pthread_cond_init(&ctx->async_cb_cond, NULL);
|
232
|
+
#else
|
233
|
+
InitializeCriticalSection(&ctx->async_cb_lock);
|
234
|
+
ctx->async_cb_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
|
120
235
|
#endif
|
236
|
+
ctx->thread = rb_thread_create(async_cb_event, ctx);
|
237
|
+
|
238
|
+
/* Name thread, for better debugging */
|
239
|
+
rb_funcall(ctx->thread, rb_intern("name="), 1, rb_str_new2("FFI Callback Dispatcher"));
|
240
|
+
}
|
241
|
+
|
242
|
+
static struct async_cb_dispatcher *
|
243
|
+
async_cb_dispatcher_ensure_created(void)
|
244
|
+
{
|
245
|
+
struct async_cb_dispatcher *ctx = async_cb_dispatcher_get();
|
246
|
+
if (ctx == NULL) {
|
247
|
+
ctx = (struct async_cb_dispatcher*)ALLOC(struct async_cb_dispatcher);
|
248
|
+
async_cb_dispatcher_initialize(ctx);
|
249
|
+
async_cb_dispatcher_set(ctx);
|
250
|
+
}
|
251
|
+
return ctx;
|
252
|
+
}
|
121
253
|
|
122
254
|
|
255
|
+
static VALUE
|
256
|
+
async_cb_dispatcher_atfork_child(VALUE self)
|
257
|
+
{
|
258
|
+
struct async_cb_dispatcher *ctx = async_cb_dispatcher_get();
|
259
|
+
if (ctx) {
|
260
|
+
async_cb_dispatcher_initialize(ctx);
|
261
|
+
}
|
262
|
+
return Qnil;
|
263
|
+
}
|
264
|
+
#endif
|
265
|
+
|
123
266
|
static VALUE
|
124
267
|
function_allocate(VALUE klass)
|
125
268
|
{
|
126
269
|
Function *fn;
|
127
270
|
VALUE obj;
|
128
271
|
|
129
|
-
obj =
|
272
|
+
obj = TypedData_Make_Struct(klass, Function, &function_data_type, fn);
|
130
273
|
|
131
|
-
fn->memory.flags = MEM_RD;
|
132
|
-
|
133
|
-
fn->rbProc
|
134
|
-
fn->rbFunctionInfo
|
274
|
+
fn->base.memory.flags = MEM_RD;
|
275
|
+
RB_OBJ_WRITE(obj, &fn->base.rbParent, Qnil);
|
276
|
+
RB_OBJ_WRITE(obj, &fn->rbProc, Qnil);
|
277
|
+
RB_OBJ_WRITE(obj, &fn->rbFunctionInfo, Qnil);
|
135
278
|
fn->autorelease = true;
|
136
279
|
|
137
280
|
return obj;
|
138
281
|
}
|
139
282
|
|
140
283
|
static void
|
141
|
-
function_mark(
|
284
|
+
function_mark(void *data)
|
285
|
+
{
|
286
|
+
Function *fn = (Function *)data;
|
287
|
+
rb_gc_mark_movable(fn->base.rbParent);
|
288
|
+
rb_gc_mark_movable(fn->rbProc);
|
289
|
+
rb_gc_mark_movable(fn->rbFunctionInfo);
|
290
|
+
}
|
291
|
+
|
292
|
+
static void
|
293
|
+
function_compact(void *data)
|
142
294
|
{
|
143
|
-
|
144
|
-
|
295
|
+
Function *fn = (Function *)data;
|
296
|
+
ffi_gc_location(fn->base.rbParent);
|
297
|
+
ffi_gc_location(fn->rbProc);
|
298
|
+
ffi_gc_location(fn->rbFunctionInfo);
|
145
299
|
}
|
146
300
|
|
147
301
|
static void
|
148
|
-
function_free(
|
302
|
+
function_free(void *data)
|
149
303
|
{
|
304
|
+
Function *fn = (Function *)data;
|
150
305
|
if (fn->methodHandle != NULL) {
|
151
306
|
rbffi_MethodHandle_Free(fn->methodHandle);
|
152
307
|
}
|
@@ -158,10 +313,38 @@ function_free(Function *fn)
|
|
158
313
|
xfree(fn);
|
159
314
|
}
|
160
315
|
|
316
|
+
static size_t
|
317
|
+
function_memsize(const void *data)
|
318
|
+
{
|
319
|
+
const Function *fn = (const Function *)data;
|
320
|
+
size_t memsize = sizeof(Function);
|
321
|
+
|
322
|
+
// Would be nice to better account for MethodHandle and Closure too.
|
323
|
+
if (fn->closure) {
|
324
|
+
memsize += sizeof(Closure);
|
325
|
+
}
|
326
|
+
|
327
|
+
return memsize;
|
328
|
+
}
|
329
|
+
|
330
|
+
/*
|
331
|
+
* @param [Type, Symbol] return_type return type for the function
|
332
|
+
* @param [Array<Type, Symbol>] param_types array of parameters types
|
333
|
+
* @param [Hash] options see {FFI::FunctionType} for available options
|
334
|
+
* @return [self]
|
335
|
+
* A new Function instance.
|
336
|
+
*
|
337
|
+
* Define a function from a Proc or a block.
|
338
|
+
*
|
339
|
+
* @overload initialize(return_type, param_types, options = {}) { |i| ... }
|
340
|
+
* @yieldparam i parameters for the function
|
341
|
+
* @overload initialize(return_type, param_types, proc, options = {})
|
342
|
+
* @param [Proc] proc
|
343
|
+
*/
|
161
344
|
static VALUE
|
162
345
|
function_initialize(int argc, VALUE* argv, VALUE self)
|
163
346
|
{
|
164
|
-
|
347
|
+
|
165
348
|
VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbProc = Qnil, rbOptions = Qnil;
|
166
349
|
VALUE rbFunctionInfo = Qnil;
|
167
350
|
VALUE infoArgv[3];
|
@@ -169,11 +352,11 @@ function_initialize(int argc, VALUE* argv, VALUE self)
|
|
169
352
|
|
170
353
|
nargs = rb_scan_args(argc, argv, "22", &rbReturnType, &rbParamTypes, &rbProc, &rbOptions);
|
171
354
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
355
|
+
/*
|
356
|
+
* Callback with block,
|
357
|
+
* e.g. Function.new(:int, [ :int ]) { |i| blah }
|
358
|
+
* or Function.new(:int, [ :int ], { :convention => :stdcall }) { |i| blah }
|
359
|
+
*/
|
177
360
|
if (rb_block_given_p()) {
|
178
361
|
if (nargs > 3) {
|
179
362
|
rb_raise(rb_eArgError, "cannot create function with both proc/address and block");
|
@@ -181,23 +364,36 @@ function_initialize(int argc, VALUE* argv, VALUE self)
|
|
181
364
|
rbOptions = rbProc;
|
182
365
|
rbProc = rb_block_proc();
|
183
366
|
} else {
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
367
|
+
/* Callback with proc, or Function with address
|
368
|
+
* e.g. Function.new(:int, [ :int ], Proc.new { |i| })
|
369
|
+
* Function.new(:int, [ :int ], Proc.new { |i| }, { :convention => :stdcall })
|
370
|
+
* Function.new(:int, [ :int ], addr)
|
371
|
+
* Function.new(:int, [ :int ], addr, { :convention => :stdcall })
|
372
|
+
*/
|
189
373
|
}
|
190
|
-
|
374
|
+
|
191
375
|
infoArgv[0] = rbReturnType;
|
192
376
|
infoArgv[1] = rbParamTypes;
|
193
377
|
infoArgv[2] = rbOptions;
|
194
378
|
rbFunctionInfo = rb_class_new_instance(rbOptions != Qnil ? 3 : 2, infoArgv, rbffi_FunctionTypeClass);
|
195
379
|
|
196
380
|
function_init(self, rbFunctionInfo, rbProc);
|
197
|
-
|
381
|
+
|
198
382
|
return self;
|
199
383
|
}
|
200
384
|
|
385
|
+
/*
|
386
|
+
* call-seq: initialize_copy(other)
|
387
|
+
* @return [nil]
|
388
|
+
* DO NOT CALL THIS METHOD
|
389
|
+
*/
|
390
|
+
static VALUE
|
391
|
+
function_initialize_copy(VALUE self, VALUE other)
|
392
|
+
{
|
393
|
+
rb_raise(rb_eRuntimeError, "cannot duplicate function instances");
|
394
|
+
return Qnil;
|
395
|
+
}
|
396
|
+
|
201
397
|
VALUE
|
202
398
|
rbffi_Function_NewInstance(VALUE rbFunctionInfo, VALUE rbProc)
|
203
399
|
{
|
@@ -208,22 +404,22 @@ VALUE
|
|
208
404
|
rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
|
209
405
|
{
|
210
406
|
VALUE callback, cbref, cbTable;
|
211
|
-
Function* fp;
|
212
407
|
|
213
408
|
cbref = RTEST(rb_ivar_defined(proc, id_cb_ref)) ? rb_ivar_get(proc, id_cb_ref) : Qnil;
|
214
409
|
/* If the first callback reference has the same function function signature, use it */
|
215
410
|
if (cbref != Qnil && CLASS_OF(cbref) == rbffi_FunctionClass) {
|
216
|
-
|
411
|
+
Function* fp;
|
412
|
+
TypedData_Get_Struct(cbref, Function, &function_data_type, fp);
|
217
413
|
if (fp->rbFunctionInfo == rbFunctionInfo) {
|
218
414
|
return cbref;
|
219
415
|
}
|
220
416
|
}
|
221
|
-
|
417
|
+
|
222
418
|
cbTable = RTEST(rb_ivar_defined(proc, id_cbtable)) ? rb_ivar_get(proc, id_cbtable) : Qnil;
|
223
419
|
if (cbTable != Qnil && (callback = rb_hash_aref(cbTable, rbFunctionInfo)) != Qnil) {
|
224
420
|
return callback;
|
225
421
|
}
|
226
|
-
|
422
|
+
|
227
423
|
/* No existing function for the proc with that signature, create a new one and cache it */
|
228
424
|
callback = rbffi_Function_NewInstance(rbFunctionInfo, proc);
|
229
425
|
if (cbref == Qnil) {
|
@@ -231,8 +427,10 @@ rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
|
|
231
427
|
rb_ivar_set(proc, id_cb_ref, callback);
|
232
428
|
} else {
|
233
429
|
/* The proc instance has been used as more than one type of callback, store extras in a hash */
|
234
|
-
cbTable
|
235
|
-
|
430
|
+
if(cbTable == Qnil) {
|
431
|
+
cbTable = rb_hash_new();
|
432
|
+
rb_ivar_set(proc, id_cbtable, cbTable);
|
433
|
+
}
|
236
434
|
rb_hash_aset(cbTable, rbFunctionInfo, callback);
|
237
435
|
}
|
238
436
|
|
@@ -243,17 +441,18 @@ static VALUE
|
|
243
441
|
function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
|
244
442
|
{
|
245
443
|
Function* fn = NULL;
|
246
|
-
|
247
|
-
Data_Get_Struct(self, Function, fn);
|
248
444
|
|
249
|
-
|
445
|
+
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
446
|
+
|
447
|
+
RB_OBJ_WRITE(self, &fn->rbFunctionInfo, rbFunctionInfo);
|
250
448
|
|
251
|
-
|
449
|
+
TypedData_Get_Struct(fn->rbFunctionInfo, FunctionType, &rbffi_fntype_data_type, fn->info);
|
252
450
|
|
253
451
|
if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) {
|
254
|
-
|
255
|
-
|
256
|
-
fn->memory =
|
452
|
+
Pointer* orig;
|
453
|
+
TypedData_Get_Struct(rbProc, Pointer, &rbffi_pointer_data_type, orig);
|
454
|
+
fn->base.memory = orig->memory;
|
455
|
+
RB_OBJ_WRITE(self, &fn->base.rbParent, rbProc);
|
257
456
|
|
258
457
|
} else if (rb_obj_is_kind_of(rbProc, rb_cProc) || rb_respond_to(rbProc, id_call)) {
|
259
458
|
if (fn->info->closurePool == NULL) {
|
@@ -264,44 +463,55 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
|
|
264
463
|
}
|
265
464
|
|
266
465
|
#if defined(DEFER_ASYNC_CALLBACK)
|
267
|
-
|
268
|
-
async_cb_thread = rb_thread_create(async_cb_event, NULL);
|
269
|
-
}
|
466
|
+
fn->dispatcher = async_cb_dispatcher_ensure_created();
|
270
467
|
#endif
|
271
468
|
|
272
469
|
fn->closure = rbffi_Closure_Alloc(fn->info->closurePool);
|
273
470
|
fn->closure->info = fn;
|
274
|
-
fn->memory.address = fn->closure->code;
|
275
|
-
fn->memory.size = sizeof(*fn->closure);
|
471
|
+
fn->base.memory.address = fn->closure->code;
|
472
|
+
fn->base.memory.size = sizeof(*fn->closure);
|
276
473
|
fn->autorelease = true;
|
277
474
|
|
278
475
|
} else {
|
279
476
|
rb_raise(rb_eTypeError, "wrong argument type %s, expected pointer or proc",
|
280
477
|
rb_obj_classname(rbProc));
|
281
478
|
}
|
282
|
-
|
283
|
-
fn->rbProc
|
479
|
+
|
480
|
+
RB_OBJ_WRITE(self, &fn->rbProc, rbProc);
|
284
481
|
|
285
482
|
return self;
|
286
483
|
}
|
287
484
|
|
485
|
+
/*
|
486
|
+
* call-seq: call(*args)
|
487
|
+
* @param [Array] args function arguments
|
488
|
+
* @return [FFI::Type]
|
489
|
+
* Call the function
|
490
|
+
*/
|
288
491
|
static VALUE
|
289
492
|
function_call(int argc, VALUE* argv, VALUE self)
|
290
493
|
{
|
291
494
|
Function* fn;
|
292
495
|
|
293
|
-
|
496
|
+
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
294
497
|
|
295
|
-
return (*fn->info->invoke)(argc, argv, fn->memory.address, fn->info);
|
498
|
+
return (*fn->info->invoke)(argc, argv, fn->base.memory.address, fn->info);
|
296
499
|
}
|
297
500
|
|
501
|
+
/*
|
502
|
+
* call-seq: attach(m, name)
|
503
|
+
* @param [Module] m
|
504
|
+
* @param [String] name
|
505
|
+
* @return [self]
|
506
|
+
* Attach a Function to the Module +m+ as +name+.
|
507
|
+
*/
|
298
508
|
static VALUE
|
299
509
|
function_attach(VALUE self, VALUE module, VALUE name)
|
300
510
|
{
|
301
511
|
Function* fn;
|
302
|
-
char var[1024];
|
303
512
|
|
304
|
-
|
513
|
+
StringValue(name);
|
514
|
+
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
305
515
|
|
306
516
|
if (fn->info->parameterCount == -1) {
|
307
517
|
rb_raise(rb_eRuntimeError, "cannot attach variadic functions");
|
@@ -314,31 +524,32 @@ function_attach(VALUE self, VALUE module, VALUE name)
|
|
314
524
|
}
|
315
525
|
|
316
526
|
if (fn->methodHandle == NULL) {
|
317
|
-
fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->memory.address);
|
527
|
+
fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->base.memory.address);
|
318
528
|
}
|
319
529
|
|
320
|
-
//
|
321
|
-
// Stash the Function in a module variable so it does not get garbage collected
|
322
|
-
//
|
323
|
-
snprintf(var, sizeof(var), "@@%s", StringValueCStr(name));
|
324
|
-
rb_cv_set(module, var, self);
|
325
|
-
|
326
530
|
rb_define_singleton_method(module, StringValueCStr(name),
|
327
531
|
rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
|
328
532
|
|
329
|
-
|
533
|
+
|
330
534
|
rb_define_method(module, StringValueCStr(name),
|
331
535
|
rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
|
332
536
|
|
333
537
|
return self;
|
334
538
|
}
|
335
539
|
|
540
|
+
/*
|
541
|
+
* call-seq: autorelease = autorelease
|
542
|
+
* @param [Boolean] autorelease
|
543
|
+
* @return [self]
|
544
|
+
* Set +autorelease+ attribute (See {Pointer}).
|
545
|
+
*/
|
336
546
|
static VALUE
|
337
547
|
function_set_autorelease(VALUE self, VALUE autorelease)
|
338
548
|
{
|
339
549
|
Function* fn;
|
340
550
|
|
341
|
-
|
551
|
+
rb_check_frozen(self);
|
552
|
+
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
342
553
|
|
343
554
|
fn->autorelease = RTEST(autorelease);
|
344
555
|
|
@@ -350,147 +561,251 @@ function_autorelease_p(VALUE self)
|
|
350
561
|
{
|
351
562
|
Function* fn;
|
352
563
|
|
353
|
-
|
564
|
+
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
354
565
|
|
355
566
|
return fn->autorelease ? Qtrue : Qfalse;
|
356
567
|
}
|
357
568
|
|
569
|
+
static VALUE
|
570
|
+
function_type(VALUE self)
|
571
|
+
{
|
572
|
+
Function* fn;
|
573
|
+
|
574
|
+
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
575
|
+
|
576
|
+
return fn->rbFunctionInfo;
|
577
|
+
}
|
578
|
+
|
579
|
+
/*
|
580
|
+
* call-seq: free
|
581
|
+
* @return [self]
|
582
|
+
* Free memory allocated by Function.
|
583
|
+
*/
|
358
584
|
static VALUE
|
359
585
|
function_release(VALUE self)
|
360
586
|
{
|
361
587
|
Function* fn;
|
362
588
|
|
363
|
-
|
589
|
+
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
364
590
|
|
365
591
|
if (fn->closure == NULL) {
|
366
592
|
rb_raise(rb_eRuntimeError, "cannot free function which was not allocated");
|
367
593
|
}
|
368
|
-
|
594
|
+
|
369
595
|
rbffi_Closure_Free(fn->closure);
|
370
596
|
fn->closure = NULL;
|
371
|
-
|
597
|
+
|
372
598
|
return self;
|
373
599
|
}
|
374
600
|
|
375
601
|
static void
|
376
602
|
callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
377
603
|
{
|
378
|
-
|
604
|
+
Function* fn;
|
605
|
+
struct gvl_callback cb = { 0 };
|
606
|
+
|
379
607
|
cb.closure = (Closure *) user_data;
|
380
608
|
cb.retval = retval;
|
381
609
|
cb.parameters = parameters;
|
610
|
+
cb.done = false;
|
611
|
+
cb.frame = rbffi_frame_current();
|
612
|
+
fn = (Function *) cb.closure->info;
|
382
613
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
#endif
|
614
|
+
if (cb.frame != NULL) cb.frame->exc = Qnil;
|
615
|
+
|
616
|
+
if (ruby_native_thread_p()) {
|
617
|
+
if(ruby_thread_has_gvl_p()) {
|
388
618
|
callback_with_gvl(&cb);
|
389
|
-
|
390
|
-
#if defined(HAVE_RUBY_NATIVE_THREAD_P) && defined (HAVE_RB_THREAD_CALL_WITH_GVL)
|
391
|
-
} else if (ruby_native_thread_p()) {
|
619
|
+
} else {
|
392
620
|
rb_thread_call_with_gvl(callback_with_gvl, &cb);
|
393
|
-
|
621
|
+
}
|
394
622
|
#if defined(DEFER_ASYNC_CALLBACK) && !defined(_WIN32)
|
395
623
|
} else {
|
624
|
+
bool empty = false;
|
625
|
+
struct async_cb_dispatcher *ctx = fn->dispatcher;
|
626
|
+
|
396
627
|
pthread_mutex_init(&cb.async_mutex, NULL);
|
397
628
|
pthread_cond_init(&cb.async_cond, NULL);
|
398
629
|
|
630
|
+
/* Now signal the async callback dispatcher thread */
|
631
|
+
pthread_mutex_lock(&ctx->async_cb_mutex);
|
632
|
+
empty = ctx->async_cb_list == NULL;
|
633
|
+
cb.next = ctx->async_cb_list;
|
634
|
+
ctx->async_cb_list = &cb;
|
635
|
+
|
636
|
+
pthread_cond_signal(&ctx->async_cb_cond);
|
637
|
+
pthread_mutex_unlock(&ctx->async_cb_mutex);
|
638
|
+
|
639
|
+
/* Wait for the thread executing the ruby callback to signal it is done */
|
399
640
|
pthread_mutex_lock(&cb.async_mutex);
|
641
|
+
while (!cb.done) {
|
642
|
+
pthread_cond_wait(&cb.async_cond, &cb.async_mutex);
|
643
|
+
}
|
644
|
+
pthread_mutex_unlock(&cb.async_mutex);
|
645
|
+
pthread_cond_destroy(&cb.async_cond);
|
646
|
+
pthread_mutex_destroy(&cb.async_mutex);
|
647
|
+
|
648
|
+
#elif defined(DEFER_ASYNC_CALLBACK) && defined(_WIN32)
|
649
|
+
} else {
|
650
|
+
bool empty = false;
|
651
|
+
struct async_cb_dispatcher *ctx = fn->dispatcher;
|
400
652
|
|
401
|
-
|
402
|
-
pthread_mutex_lock(&async_cb_mutex);
|
403
|
-
cb.next = async_cb_list;
|
404
|
-
async_cb_list = &cb;
|
405
|
-
pthread_cond_signal(&async_cb_cond);
|
406
|
-
pthread_mutex_unlock(&async_cb_mutex);
|
653
|
+
cb.async_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
407
654
|
|
408
|
-
|
409
|
-
|
655
|
+
/* Now signal the async callback dispatcher thread */
|
656
|
+
EnterCriticalSection(&ctx->async_cb_lock);
|
657
|
+
empty = ctx->async_cb_list == NULL;
|
658
|
+
cb.next = ctx->async_cb_list;
|
659
|
+
ctx->async_cb_list = &cb;
|
660
|
+
LeaveCriticalSection(&ctx->async_cb_lock);
|
661
|
+
|
662
|
+
SetEvent(ctx->async_cb_cond);
|
663
|
+
|
664
|
+
/* Wait for the thread executing the ruby callback to signal it is done */
|
665
|
+
WaitForSingleObject(cb.async_event, INFINITE);
|
666
|
+
CloseHandle(cb.async_event);
|
410
667
|
#endif
|
411
668
|
}
|
412
669
|
}
|
413
670
|
|
414
671
|
#if defined(DEFER_ASYNC_CALLBACK)
|
415
672
|
struct async_wait {
|
673
|
+
struct async_cb_dispatcher *dispatcher;
|
416
674
|
void* cb;
|
417
675
|
bool stop;
|
418
676
|
};
|
419
677
|
|
420
|
-
static
|
678
|
+
static void * async_cb_wait(void *);
|
421
679
|
static void async_cb_stop(void *);
|
422
680
|
|
423
681
|
static VALUE
|
424
|
-
async_cb_event(void)
|
682
|
+
async_cb_event(void* ptr)
|
425
683
|
{
|
426
|
-
struct
|
684
|
+
struct async_cb_dispatcher *ctx = (struct async_cb_dispatcher *)ptr;
|
685
|
+
struct async_wait w = { ctx };
|
427
686
|
|
428
687
|
w.stop = false;
|
429
688
|
while (!w.stop) {
|
430
|
-
|
689
|
+
rb_thread_call_without_gvl(async_cb_wait, &w, async_cb_stop, &w);
|
431
690
|
if (w.cb != NULL) {
|
432
|
-
|
433
|
-
rb_thread_create(async_cb_call, w.cb);
|
691
|
+
/* Start up a new ruby thread to run the ruby callback */
|
692
|
+
VALUE new_thread = rb_thread_create(async_cb_call, w.cb);
|
693
|
+
/* Name thread, for better debugging */
|
694
|
+
rb_funcall(new_thread, rb_intern("name="), 1, rb_str_new2("FFI Callback Runner"));
|
434
695
|
}
|
435
696
|
}
|
436
|
-
|
697
|
+
|
437
698
|
return Qnil;
|
438
699
|
}
|
439
700
|
|
440
|
-
|
701
|
+
#ifdef _WIN32
|
702
|
+
static void *
|
441
703
|
async_cb_wait(void *data)
|
442
704
|
{
|
443
705
|
struct async_wait* w = (struct async_wait *) data;
|
706
|
+
struct async_cb_dispatcher *ctx = w->dispatcher;
|
444
707
|
|
445
708
|
w->cb = NULL;
|
446
709
|
|
447
|
-
|
710
|
+
EnterCriticalSection(&ctx->async_cb_lock);
|
448
711
|
|
449
|
-
while (!w->stop && async_cb_list == NULL) {
|
450
|
-
|
712
|
+
while (!w->stop && ctx->async_cb_list == NULL) {
|
713
|
+
LeaveCriticalSection(&ctx->async_cb_lock);
|
714
|
+
WaitForSingleObject(ctx->async_cb_cond, INFINITE);
|
715
|
+
EnterCriticalSection(&ctx->async_cb_lock);
|
451
716
|
}
|
452
|
-
|
453
|
-
if (async_cb_list != NULL) {
|
454
|
-
w->cb = async_cb_list;
|
455
|
-
async_cb_list = async_cb_list->next;
|
717
|
+
|
718
|
+
if (ctx->async_cb_list != NULL) {
|
719
|
+
w->cb = ctx->async_cb_list;
|
720
|
+
ctx->async_cb_list = ctx->async_cb_list->next;
|
456
721
|
}
|
457
722
|
|
458
|
-
|
459
|
-
|
460
|
-
return
|
723
|
+
LeaveCriticalSection(&ctx->async_cb_lock);
|
724
|
+
|
725
|
+
return NULL;
|
461
726
|
}
|
462
727
|
|
463
728
|
static void
|
464
729
|
async_cb_stop(void *data)
|
465
730
|
{
|
466
731
|
struct async_wait* w = (struct async_wait *) data;
|
732
|
+
struct async_cb_dispatcher *ctx = w->dispatcher;
|
467
733
|
|
468
|
-
|
734
|
+
EnterCriticalSection(&ctx->async_cb_lock);
|
469
735
|
w->stop = true;
|
470
|
-
|
471
|
-
|
736
|
+
LeaveCriticalSection(&ctx->async_cb_lock);
|
737
|
+
SetEvent(ctx->async_cb_cond);
|
472
738
|
}
|
473
739
|
|
740
|
+
#else
|
741
|
+
static void *
|
742
|
+
async_cb_wait(void *data)
|
743
|
+
{
|
744
|
+
struct async_wait* w = (struct async_wait *) data;
|
745
|
+
struct async_cb_dispatcher *ctx = w->dispatcher;
|
746
|
+
|
747
|
+
w->cb = NULL;
|
748
|
+
|
749
|
+
pthread_mutex_lock(&ctx->async_cb_mutex);
|
750
|
+
|
751
|
+
while (!w->stop && ctx->async_cb_list == NULL) {
|
752
|
+
pthread_cond_wait(&ctx->async_cb_cond, &ctx->async_cb_mutex);
|
753
|
+
}
|
754
|
+
|
755
|
+
if (ctx->async_cb_list != NULL) {
|
756
|
+
w->cb = ctx->async_cb_list;
|
757
|
+
ctx->async_cb_list = ctx->async_cb_list->next;
|
758
|
+
}
|
759
|
+
|
760
|
+
pthread_mutex_unlock(&ctx->async_cb_mutex);
|
761
|
+
|
762
|
+
return NULL;
|
763
|
+
}
|
764
|
+
|
765
|
+
static void
|
766
|
+
async_cb_stop(void *data)
|
767
|
+
{
|
768
|
+
struct async_wait* w = (struct async_wait *) data;
|
769
|
+
struct async_cb_dispatcher *ctx = w->dispatcher;
|
770
|
+
|
771
|
+
pthread_mutex_lock(&ctx->async_cb_mutex);
|
772
|
+
w->stop = true;
|
773
|
+
pthread_cond_signal(&ctx->async_cb_cond);
|
774
|
+
pthread_mutex_unlock(&ctx->async_cb_mutex);
|
775
|
+
}
|
776
|
+
#endif
|
777
|
+
|
474
778
|
static VALUE
|
475
779
|
async_cb_call(void *data)
|
476
780
|
{
|
477
781
|
struct gvl_callback* cb = (struct gvl_callback *) data;
|
478
782
|
|
479
|
-
callback_with_gvl(
|
783
|
+
callback_with_gvl(data);
|
480
784
|
|
481
|
-
|
785
|
+
/* Signal the original native thread that the ruby code has completed */
|
786
|
+
#ifdef _WIN32
|
787
|
+
SetEvent(cb->async_event);
|
788
|
+
#else
|
482
789
|
pthread_mutex_lock(&cb->async_mutex);
|
790
|
+
cb->done = true;
|
483
791
|
pthread_cond_signal(&cb->async_cond);
|
484
792
|
pthread_mutex_unlock(&cb->async_mutex);
|
793
|
+
#endif
|
485
794
|
|
486
795
|
return Qnil;
|
487
796
|
}
|
488
797
|
|
489
798
|
#endif
|
490
799
|
|
491
|
-
|
492
|
-
static void*
|
800
|
+
static void *
|
493
801
|
callback_with_gvl(void* data)
|
802
|
+
{
|
803
|
+
rb_rescue2(invoke_callback, (VALUE) data, save_callback_exception, (VALUE) data, rb_eException, (VALUE) 0);
|
804
|
+
return NULL;
|
805
|
+
}
|
806
|
+
|
807
|
+
static VALUE
|
808
|
+
invoke_callback(VALUE data)
|
494
809
|
{
|
495
810
|
struct gvl_callback* cb = (struct gvl_callback *) data;
|
496
811
|
|
@@ -511,8 +826,8 @@ callback_with_gvl(void* data)
|
|
511
826
|
VALUE rbParamType = rb_ary_entry(cbInfo->rbParameterTypes, i);
|
512
827
|
|
513
828
|
if (unlikely(paramType->nativeType == NATIVE_MAPPED)) {
|
514
|
-
paramType = ((MappedType *) paramType)->type;
|
515
829
|
rbParamType = ((MappedType *) paramType)->rbType;
|
830
|
+
paramType = ((MappedType *) paramType)->type;
|
516
831
|
}
|
517
832
|
|
518
833
|
switch (paramType->nativeType) {
|
@@ -552,8 +867,11 @@ callback_with_gvl(void* data)
|
|
552
867
|
case NATIVE_FLOAT64:
|
553
868
|
param = rb_float_new(*(double *) parameters[i]);
|
554
869
|
break;
|
870
|
+
case NATIVE_LONGDOUBLE:
|
871
|
+
param = rbffi_longdouble_new(*(long double *) parameters[i]);
|
872
|
+
break;
|
555
873
|
case NATIVE_STRING:
|
556
|
-
param = (*(void **) parameters[i] != NULL) ?
|
874
|
+
param = (*(void **) parameters[i] != NULL) ? rb_str_new2(*(char **) parameters[i]) : Qnil;
|
557
875
|
break;
|
558
876
|
case NATIVE_POINTER:
|
559
877
|
param = rbffi_Pointer_NewInstance(*(void **) parameters[i]);
|
@@ -563,9 +881,8 @@ callback_with_gvl(void* data)
|
|
563
881
|
break;
|
564
882
|
|
565
883
|
case NATIVE_FUNCTION:
|
566
|
-
case NATIVE_CALLBACK:
|
567
884
|
case NATIVE_STRUCT:
|
568
|
-
param = rbffi_NativeValue_ToRuby(paramType, rbParamType, parameters[i]
|
885
|
+
param = rbffi_NativeValue_ToRuby(paramType, rbParamType, parameters[i]);
|
569
886
|
break;
|
570
887
|
|
571
888
|
default:
|
@@ -573,7 +890,7 @@ callback_with_gvl(void* data)
|
|
573
890
|
break;
|
574
891
|
}
|
575
892
|
|
576
|
-
|
893
|
+
/* Convert the native value into a custom ruby value */
|
577
894
|
if (unlikely(cbInfo->parameterTypes[i]->nativeType == NATIVE_MAPPED)) {
|
578
895
|
VALUE values[] = { param, Qnil };
|
579
896
|
param = rb_funcall2(((MappedType *) cbInfo->parameterTypes[i])->rbConverter, id_from_native, 2, values);
|
@@ -583,7 +900,7 @@ callback_with_gvl(void* data)
|
|
583
900
|
}
|
584
901
|
|
585
902
|
rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams);
|
586
|
-
|
903
|
+
|
587
904
|
if (unlikely(returnType->nativeType == NATIVE_MAPPED)) {
|
588
905
|
VALUE values[] = { rbReturnValue, Qnil };
|
589
906
|
rbReturnValue = rb_funcall2(((MappedType *) returnType)->rbConverter, id_to_native, 2, values);
|
@@ -622,11 +939,16 @@ callback_with_gvl(void* data)
|
|
622
939
|
case NATIVE_FLOAT64:
|
623
940
|
*((double *) retval) = NUM2DBL(rbReturnValue);
|
624
941
|
break;
|
942
|
+
case NATIVE_LONGDOUBLE:
|
943
|
+
*((long double *) retval) = rbffi_num2longdouble(rbReturnValue);
|
944
|
+
break;
|
625
945
|
case NATIVE_POINTER:
|
626
946
|
if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
|
627
|
-
|
947
|
+
AbstractMemory* memory;
|
948
|
+
TypedData_Get_Struct(rbReturnValue, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
|
949
|
+
*((void **) retval) = memory->address;
|
628
950
|
} else {
|
629
|
-
|
951
|
+
/* Default to returning NULL if not a value pointer object. handles nil case as well */
|
630
952
|
*((void **) retval) = NULL;
|
631
953
|
}
|
632
954
|
break;
|
@@ -636,17 +958,21 @@ callback_with_gvl(void* data)
|
|
636
958
|
break;
|
637
959
|
|
638
960
|
case NATIVE_FUNCTION:
|
639
|
-
case NATIVE_CALLBACK:
|
640
961
|
if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
|
962
|
+
AbstractMemory* memory;
|
963
|
+
TypedData_Get_Struct(rbReturnValue, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
|
641
964
|
|
642
|
-
*((void **) retval) =
|
965
|
+
*((void **) retval) = memory->address;
|
643
966
|
|
644
967
|
} else if (rb_obj_is_kind_of(rbReturnValue, rb_cProc) || rb_respond_to(rbReturnValue, id_call)) {
|
645
968
|
VALUE function;
|
969
|
+
AbstractMemory* memory;
|
646
970
|
|
647
971
|
function = rbffi_Function_ForProc(rbReturnType, rbReturnValue);
|
648
972
|
|
649
|
-
|
973
|
+
TypedData_Get_Struct(function, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
|
974
|
+
|
975
|
+
*((void **) retval) = memory->address;
|
650
976
|
} else {
|
651
977
|
*((void **) retval) = NULL;
|
652
978
|
}
|
@@ -654,7 +980,11 @@ callback_with_gvl(void* data)
|
|
654
980
|
|
655
981
|
case NATIVE_STRUCT:
|
656
982
|
if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_StructClass)) {
|
657
|
-
|
983
|
+
Struct* s;
|
984
|
+
AbstractMemory* memory;
|
985
|
+
|
986
|
+
TypedData_Get_Struct(rbReturnValue, Struct, &rbffi_struct_data_type, s);
|
987
|
+
memory = s->pointer;
|
658
988
|
|
659
989
|
if (memory->address != NULL) {
|
660
990
|
memcpy(retval, memory->address, returnType->ffiType->size);
|
@@ -662,7 +992,7 @@ callback_with_gvl(void* data)
|
|
662
992
|
} else {
|
663
993
|
memset(retval, 0, returnType->ffiType->size);
|
664
994
|
}
|
665
|
-
|
995
|
+
|
666
996
|
} else {
|
667
997
|
memset(retval, 0, returnType->ffiType->size);
|
668
998
|
}
|
@@ -673,9 +1003,19 @@ callback_with_gvl(void* data)
|
|
673
1003
|
break;
|
674
1004
|
}
|
675
1005
|
|
676
|
-
return
|
1006
|
+
return Qnil;
|
677
1007
|
}
|
678
1008
|
|
1009
|
+
static VALUE
|
1010
|
+
save_callback_exception(VALUE data, VALUE exc)
|
1011
|
+
{
|
1012
|
+
struct gvl_callback* cb = (struct gvl_callback *) data;
|
1013
|
+
|
1014
|
+
memset(cb->retval, 0, ((Function *) cb->closure->info)->info->returnType->ffiType->size);
|
1015
|
+
if (cb->frame != NULL) cb->frame->exc = exc;
|
1016
|
+
|
1017
|
+
return Qnil;
|
1018
|
+
}
|
679
1019
|
|
680
1020
|
static bool
|
681
1021
|
callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
|
@@ -683,9 +1023,9 @@ callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errm
|
|
683
1023
|
FunctionType* fnInfo = (FunctionType *) ctx;
|
684
1024
|
ffi_status ffiStatus;
|
685
1025
|
|
686
|
-
ffiStatus =
|
1026
|
+
ffiStatus = ffi_prep_closure_loc(closure->pcl, &fnInfo->ffi_cif, callback_invoke, closure, code);
|
687
1027
|
if (ffiStatus != FFI_OK) {
|
688
|
-
snprintf(errmsg, errmsgsize, "
|
1028
|
+
snprintf(errmsg, errmsgsize, "ffi_prep_closure_loc failed. status=%#x", ffiStatus);
|
689
1029
|
return false;
|
690
1030
|
}
|
691
1031
|
|
@@ -696,17 +1036,33 @@ void
|
|
696
1036
|
rbffi_Function_Init(VALUE moduleFFI)
|
697
1037
|
{
|
698
1038
|
rbffi_FunctionInfo_Init(moduleFFI);
|
1039
|
+
/*
|
1040
|
+
* Document-class: FFI::Function < FFI::Pointer
|
1041
|
+
*/
|
699
1042
|
rbffi_FunctionClass = rb_define_class_under(moduleFFI, "Function", rbffi_PointerClass);
|
700
|
-
|
1043
|
+
|
701
1044
|
rb_global_variable(&rbffi_FunctionClass);
|
702
1045
|
rb_define_alloc_func(rbffi_FunctionClass, function_allocate);
|
703
1046
|
|
704
1047
|
rb_define_method(rbffi_FunctionClass, "initialize", function_initialize, -1);
|
1048
|
+
rb_define_method(rbffi_FunctionClass, "initialize_copy", function_initialize_copy, 1);
|
705
1049
|
rb_define_method(rbffi_FunctionClass, "call", function_call, -1);
|
706
1050
|
rb_define_method(rbffi_FunctionClass, "attach", function_attach, 2);
|
707
1051
|
rb_define_method(rbffi_FunctionClass, "free", function_release, 0);
|
708
1052
|
rb_define_method(rbffi_FunctionClass, "autorelease=", function_set_autorelease, 1);
|
1053
|
+
rb_define_private_method(rbffi_FunctionClass, "type", function_type, 0);
|
1054
|
+
/*
|
1055
|
+
* call-seq: autorelease
|
1056
|
+
* @return [Boolean]
|
1057
|
+
* Get +autorelease+ attribute.
|
1058
|
+
* Synonymous for {#autorelease?}.
|
1059
|
+
*/
|
709
1060
|
rb_define_method(rbffi_FunctionClass, "autorelease", function_autorelease_p, 0);
|
1061
|
+
/*
|
1062
|
+
* call-seq: autorelease?
|
1063
|
+
* @return [Boolean] +autorelease+ attribute
|
1064
|
+
* Get +autorelease+ attribute.
|
1065
|
+
*/
|
710
1066
|
rb_define_method(rbffi_FunctionClass, "autorelease?", function_autorelease_p, 0);
|
711
1067
|
|
712
1068
|
id_call = rb_intern("call");
|
@@ -714,5 +1070,12 @@ rbffi_Function_Init(VALUE moduleFFI)
|
|
714
1070
|
id_cb_ref = rb_intern("@__ffi_callback__");
|
715
1071
|
id_to_native = rb_intern("to_native");
|
716
1072
|
id_from_native = rb_intern("from_native");
|
1073
|
+
#if defined(DEFER_ASYNC_CALLBACK) && defined(HAVE_RB_EXT_RACTOR_SAFE)
|
1074
|
+
async_cb_dispatcher_key = rb_ractor_local_storage_ptr_newkey(&async_cb_dispatcher_key_type);
|
1075
|
+
#endif
|
1076
|
+
#ifdef DEFER_ASYNC_CALLBACK
|
1077
|
+
/* Ruby code will call this method in a Process._fork patch */
|
1078
|
+
rb_define_singleton_method(moduleFFI, "_async_cb_dispatcher_atfork_child",
|
1079
|
+
async_cb_dispatcher_atfork_child, 0);
|
1080
|
+
#endif
|
717
1081
|
}
|
718
|
-
|