ffi 1.16.3 → 1.17.0-java
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +42 -0
- data/Gemfile +9 -2
- data/README.md +1 -1
- data/Rakefile +17 -5
- data/lib/ffi/autopointer.rb +1 -9
- data/lib/ffi/dynamic_library.rb +34 -5
- data/lib/ffi/enum.rb +0 -1
- data/lib/ffi/function.rb +1 -1
- data/lib/ffi/io.rb +2 -2
- data/lib/ffi/library.rb +23 -23
- data/lib/ffi/platform/aarch64-linux/types.conf +74 -3
- data/lib/ffi/pointer.rb +6 -6
- data/lib/ffi/struct.rb +4 -4
- data/lib/ffi/struct_layout.rb +2 -2
- data/lib/ffi/struct_layout_builder.rb +8 -8
- data/lib/ffi/types.rb +51 -49
- data/lib/ffi/version.rb +1 -1
- data/sig/ffi/abstract_memory.rbs +165 -0
- data/sig/ffi/auto_pointer.rbs +27 -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 +34 -532
- metadata.gz.sig +0 -0
- data/ext/ffi_c/AbstractMemory.c +0 -1128
- data/ext/ffi_c/AbstractMemory.h +0 -176
- data/ext/ffi_c/ArrayType.c +0 -198
- data/ext/ffi_c/ArrayType.h +0 -60
- data/ext/ffi_c/Buffer.c +0 -417
- data/ext/ffi_c/Call.c +0 -498
- data/ext/ffi_c/Call.h +0 -107
- data/ext/ffi_c/ClosurePool.c +0 -333
- data/ext/ffi_c/ClosurePool.h +0 -59
- data/ext/ffi_c/DynamicLibrary.c +0 -397
- data/ext/ffi_c/DynamicLibrary.h +0 -98
- data/ext/ffi_c/Function.c +0 -1063
- data/ext/ffi_c/Function.h +0 -84
- data/ext/ffi_c/FunctionInfo.c +0 -322
- data/ext/ffi_c/LastError.c +0 -243
- data/ext/ffi_c/LastError.h +0 -47
- data/ext/ffi_c/LongDouble.c +0 -65
- data/ext/ffi_c/LongDouble.h +0 -47
- data/ext/ffi_c/MappedType.c +0 -211
- data/ext/ffi_c/MappedType.h +0 -57
- data/ext/ffi_c/MemoryPointer.c +0 -219
- data/ext/ffi_c/MemoryPointer.h +0 -49
- data/ext/ffi_c/MethodHandle.c +0 -350
- data/ext/ffi_c/MethodHandle.h +0 -56
- data/ext/ffi_c/Platform.c +0 -78
- data/ext/ffi_c/Platform.h +0 -45
- data/ext/ffi_c/Pointer.c +0 -546
- data/ext/ffi_c/Pointer.h +0 -60
- data/ext/ffi_c/Struct.c +0 -897
- data/ext/ffi_c/Struct.h +0 -115
- data/ext/ffi_c/StructByValue.c +0 -177
- data/ext/ffi_c/StructByValue.h +0 -55
- data/ext/ffi_c/StructLayout.c +0 -769
- data/ext/ffi_c/Thread.c +0 -129
- data/ext/ffi_c/Thread.h +0 -76
- data/ext/ffi_c/Type.c +0 -447
- data/ext/ffi_c/Type.h +0 -63
- data/ext/ffi_c/Types.c +0 -138
- data/ext/ffi_c/Types.h +0 -88
- data/ext/ffi_c/Variadic.c +0 -345
- data/ext/ffi_c/compat.h +0 -82
- data/ext/ffi_c/extconf.rb +0 -115
- data/ext/ffi_c/ffi.c +0 -97
- data/ext/ffi_c/libffi/.appveyor/site.exp +0 -16
- data/ext/ffi_c/libffi/.appveyor/unix-noexec.exp +0 -7
- data/ext/ffi_c/libffi/.appveyor.yml +0 -84
- data/ext/ffi_c/libffi/.ci/ar-lib +0 -270
- data/ext/ffi_c/libffi/.ci/bfin-sim.exp +0 -58
- data/ext/ffi_c/libffi/.ci/build-cross-in-container.sh +0 -18
- data/ext/ffi_c/libffi/.ci/build-in-container.sh +0 -10
- data/ext/ffi_c/libffi/.ci/build.sh +0 -124
- data/ext/ffi_c/libffi/.ci/compile +0 -351
- data/ext/ffi_c/libffi/.ci/install.sh +0 -78
- data/ext/ffi_c/libffi/.ci/m32r-sim.exp +0 -58
- data/ext/ffi_c/libffi/.ci/moxie-sim.exp +0 -60
- data/ext/ffi_c/libffi/.ci/msvs-detect +0 -1103
- data/ext/ffi_c/libffi/.ci/or1k-sim.exp +0 -58
- data/ext/ffi_c/libffi/.ci/powerpc-eabisim.exp +0 -58
- data/ext/ffi_c/libffi/.ci/site.exp +0 -29
- data/ext/ffi_c/libffi/.ci/wine-sim.exp +0 -55
- data/ext/ffi_c/libffi/.circleci/config.yml +0 -156
- data/ext/ffi_c/libffi/.gitattributes +0 -4
- data/ext/ffi_c/libffi/.github/issue_template.md +0 -10
- data/ext/ffi_c/libffi/.github/workflows/build.yml +0 -460
- data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +0 -171
- data/ext/ffi_c/libffi/.gitignore +0 -46
- data/ext/ffi_c/libffi/ChangeLog.old +0 -7407
- data/ext/ffi_c/libffi/LICENSE +0 -21
- data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +0 -353
- data/ext/ffi_c/libffi/Makefile.am +0 -157
- data/ext/ffi_c/libffi/Makefile.in +0 -2127
- data/ext/ffi_c/libffi/README.md +0 -526
- data/ext/ffi_c/libffi/acinclude.m4 +0 -377
- data/ext/ffi_c/libffi/autogen.sh +0 -2
- data/ext/ffi_c/libffi/compile +0 -348
- data/ext/ffi_c/libffi/config.guess +0 -1754
- data/ext/ffi_c/libffi/config.sub +0 -1892
- data/ext/ffi_c/libffi/configure +0 -22791
- data/ext/ffi_c/libffi/configure.ac +0 -451
- data/ext/ffi_c/libffi/configure.host +0 -337
- data/ext/ffi_c/libffi/doc/Makefile.am +0 -3
- data/ext/ffi_c/libffi/doc/Makefile.in +0 -818
- data/ext/ffi_c/libffi/doc/libffi.texi +0 -1046
- data/ext/ffi_c/libffi/doc/version.texi +0 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +0 -188
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +0 -312
- data/ext/ffi_c/libffi/include/Makefile.am +0 -9
- data/ext/ffi_c/libffi/include/Makefile.in +0 -609
- data/ext/ffi_c/libffi/include/ffi.h.in +0 -527
- data/ext/ffi_c/libffi/include/ffi_cfi.h +0 -76
- data/ext/ffi_c/libffi/include/ffi_common.h +0 -182
- data/ext/ffi_c/libffi/include/tramp.h +0 -45
- data/ext/ffi_c/libffi/install-sh +0 -541
- data/ext/ffi_c/libffi/libffi.map.in +0 -76
- data/ext/ffi_c/libffi/libffi.pc.in +0 -11
- data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +0 -997
- data/ext/ffi_c/libffi/libtool-ldflags +0 -106
- data/ext/ffi_c/libffi/libtool-version +0 -29
- data/ext/ffi_c/libffi/ltmain.sh +0 -11448
- data/ext/ffi_c/libffi/m4/asmcfi.m4 +0 -13
- data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +0 -50
- data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +0 -198
- data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +0 -158
- data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +0 -53
- data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +0 -119
- data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +0 -49
- data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +0 -302
- data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +0 -267
- data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +0 -89
- data/ext/ffi_c/libffi/m4/ax_prepend_flag.m4 +0 -51
- data/ext/ffi_c/libffi/m4/ax_require_defined.m4 +0 -37
- data/ext/ffi_c/libffi/make_sunver.pl +0 -333
- data/ext/ffi_c/libffi/man/Makefile.am +0 -8
- data/ext/ffi_c/libffi/man/Makefile.in +0 -565
- data/ext/ffi_c/libffi/man/ffi.3 +0 -41
- data/ext/ffi_c/libffi/man/ffi_call.3 +0 -103
- data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +0 -68
- data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +0 -73
- data/ext/ffi_c/libffi/missing +0 -215
- data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.sln +0 -33
- data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj +0 -130
- data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters +0 -57
- data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.user +0 -4
- data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +0 -511
- data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/fficonfig.h +0 -219
- data/ext/ffi_c/libffi/msvcc.sh +0 -353
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +0 -1129
- data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +0 -97
- data/ext/ffi_c/libffi/src/aarch64/internal.h +0 -100
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +0 -543
- data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +0 -506
- data/ext/ffi_c/libffi/src/alpha/ffi.c +0 -521
- data/ext/ffi_c/libffi/src/alpha/ffitarget.h +0 -57
- data/ext/ffi_c/libffi/src/alpha/internal.h +0 -23
- data/ext/ffi_c/libffi/src/alpha/osf.S +0 -282
- data/ext/ffi_c/libffi/src/arc/arcompact.S +0 -210
- data/ext/ffi_c/libffi/src/arc/ffi.c +0 -443
- data/ext/ffi_c/libffi/src/arc/ffitarget.h +0 -67
- data/ext/ffi_c/libffi/src/arm/ffi.c +0 -921
- data/ext/ffi_c/libffi/src/arm/ffitarget.h +0 -89
- data/ext/ffi_c/libffi/src/arm/internal.h +0 -17
- data/ext/ffi_c/libffi/src/arm/sysv.S +0 -456
- data/ext/ffi_c/libffi/src/arm/sysv_msvc_arm32.S +0 -311
- data/ext/ffi_c/libffi/src/avr32/ffi.c +0 -423
- data/ext/ffi_c/libffi/src/avr32/ffitarget.h +0 -55
- data/ext/ffi_c/libffi/src/avr32/sysv.S +0 -208
- data/ext/ffi_c/libffi/src/bfin/ffi.c +0 -196
- data/ext/ffi_c/libffi/src/bfin/ffitarget.h +0 -43
- data/ext/ffi_c/libffi/src/bfin/sysv.S +0 -179
- data/ext/ffi_c/libffi/src/closures.c +0 -1107
- data/ext/ffi_c/libffi/src/cris/ffi.c +0 -386
- data/ext/ffi_c/libffi/src/cris/ffitarget.h +0 -56
- data/ext/ffi_c/libffi/src/cris/sysv.S +0 -215
- data/ext/ffi_c/libffi/src/csky/ffi.c +0 -395
- data/ext/ffi_c/libffi/src/csky/ffitarget.h +0 -63
- data/ext/ffi_c/libffi/src/csky/sysv.S +0 -371
- data/ext/ffi_c/libffi/src/debug.c +0 -64
- data/ext/ffi_c/libffi/src/dlmalloc.c +0 -5171
- data/ext/ffi_c/libffi/src/frv/eabi.S +0 -128
- data/ext/ffi_c/libffi/src/frv/ffi.c +0 -292
- data/ext/ffi_c/libffi/src/frv/ffitarget.h +0 -62
- data/ext/ffi_c/libffi/src/ia64/ffi.c +0 -616
- data/ext/ffi_c/libffi/src/ia64/ffitarget.h +0 -56
- data/ext/ffi_c/libffi/src/ia64/ia64_flags.h +0 -40
- data/ext/ffi_c/libffi/src/ia64/unix.S +0 -585
- data/ext/ffi_c/libffi/src/java_raw_api.c +0 -374
- data/ext/ffi_c/libffi/src/kvx/asm.h +0 -5
- data/ext/ffi_c/libffi/src/kvx/ffi.c +0 -273
- data/ext/ffi_c/libffi/src/kvx/ffitarget.h +0 -75
- data/ext/ffi_c/libffi/src/kvx/sysv.S +0 -127
- data/ext/ffi_c/libffi/src/loongarch64/ffi.c +0 -621
- data/ext/ffi_c/libffi/src/loongarch64/ffitarget.h +0 -82
- data/ext/ffi_c/libffi/src/loongarch64/sysv.S +0 -327
- data/ext/ffi_c/libffi/src/m32r/ffi.c +0 -249
- data/ext/ffi_c/libffi/src/m32r/ffitarget.h +0 -53
- data/ext/ffi_c/libffi/src/m32r/sysv.S +0 -121
- data/ext/ffi_c/libffi/src/m68k/ffi.c +0 -362
- data/ext/ffi_c/libffi/src/m68k/ffitarget.h +0 -54
- data/ext/ffi_c/libffi/src/m68k/sysv.S +0 -357
- data/ext/ffi_c/libffi/src/m88k/ffi.c +0 -400
- data/ext/ffi_c/libffi/src/m88k/ffitarget.h +0 -49
- data/ext/ffi_c/libffi/src/m88k/obsd.S +0 -209
- data/ext/ffi_c/libffi/src/metag/ffi.c +0 -330
- data/ext/ffi_c/libffi/src/metag/ffitarget.h +0 -53
- data/ext/ffi_c/libffi/src/metag/sysv.S +0 -311
- data/ext/ffi_c/libffi/src/microblaze/ffi.c +0 -321
- data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +0 -53
- data/ext/ffi_c/libffi/src/microblaze/sysv.S +0 -302
- data/ext/ffi_c/libffi/src/mips/ffi.c +0 -1309
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +0 -251
- data/ext/ffi_c/libffi/src/mips/n32.S +0 -772
- data/ext/ffi_c/libffi/src/mips/o32.S +0 -561
- data/ext/ffi_c/libffi/src/moxie/eabi.S +0 -101
- data/ext/ffi_c/libffi/src/moxie/ffi.c +0 -310
- data/ext/ffi_c/libffi/src/moxie/ffitarget.h +0 -52
- data/ext/ffi_c/libffi/src/nios2/ffi.c +0 -304
- data/ext/ffi_c/libffi/src/nios2/ffitarget.h +0 -52
- data/ext/ffi_c/libffi/src/nios2/sysv.S +0 -136
- data/ext/ffi_c/libffi/src/or1k/ffi.c +0 -341
- data/ext/ffi_c/libffi/src/or1k/ffitarget.h +0 -58
- data/ext/ffi_c/libffi/src/or1k/sysv.S +0 -107
- data/ext/ffi_c/libffi/src/pa/ffi.c +0 -673
- data/ext/ffi_c/libffi/src/pa/ffi64.c +0 -614
- data/ext/ffi_c/libffi/src/pa/ffitarget.h +0 -94
- data/ext/ffi_c/libffi/src/pa/hpux32.S +0 -417
- data/ext/ffi_c/libffi/src/pa/hpux64.S +0 -681
- data/ext/ffi_c/libffi/src/pa/linux.S +0 -427
- data/ext/ffi_c/libffi/src/powerpc/aix.S +0 -566
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +0 -694
- data/ext/ffi_c/libffi/src/powerpc/asm.h +0 -125
- data/ext/ffi_c/libffi/src/powerpc/darwin.S +0 -378
- data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +0 -571
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +0 -175
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +0 -1452
- data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +0 -1153
- data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +0 -105
- data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +0 -923
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +0 -204
- data/ext/ffi_c/libffi/src/powerpc/linux64.S +0 -293
- data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +0 -566
- data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +0 -397
- data/ext/ffi_c/libffi/src/powerpc/sysv.S +0 -173
- data/ext/ffi_c/libffi/src/powerpc/t-aix +0 -5
- data/ext/ffi_c/libffi/src/prep_cif.c +0 -283
- data/ext/ffi_c/libffi/src/raw_api.c +0 -267
- data/ext/ffi_c/libffi/src/riscv/ffi.c +0 -514
- data/ext/ffi_c/libffi/src/riscv/ffitarget.h +0 -69
- data/ext/ffi_c/libffi/src/riscv/sysv.S +0 -293
- data/ext/ffi_c/libffi/src/s390/ffi.c +0 -756
- data/ext/ffi_c/libffi/src/s390/ffitarget.h +0 -70
- data/ext/ffi_c/libffi/src/s390/internal.h +0 -11
- data/ext/ffi_c/libffi/src/s390/sysv.S +0 -325
- data/ext/ffi_c/libffi/src/sh/ffi.c +0 -717
- data/ext/ffi_c/libffi/src/sh/ffitarget.h +0 -54
- data/ext/ffi_c/libffi/src/sh/sysv.S +0 -850
- data/ext/ffi_c/libffi/src/sh64/ffi.c +0 -469
- data/ext/ffi_c/libffi/src/sh64/ffitarget.h +0 -58
- data/ext/ffi_c/libffi/src/sh64/sysv.S +0 -539
- data/ext/ffi_c/libffi/src/sparc/ffi.c +0 -468
- data/ext/ffi_c/libffi/src/sparc/ffi64.c +0 -624
- data/ext/ffi_c/libffi/src/sparc/ffitarget.h +0 -81
- data/ext/ffi_c/libffi/src/sparc/internal.h +0 -26
- data/ext/ffi_c/libffi/src/sparc/v8.S +0 -443
- data/ext/ffi_c/libffi/src/sparc/v9.S +0 -440
- data/ext/ffi_c/libffi/src/tile/ffi.c +0 -355
- data/ext/ffi_c/libffi/src/tile/ffitarget.h +0 -65
- data/ext/ffi_c/libffi/src/tile/tile.S +0 -360
- data/ext/ffi_c/libffi/src/tramp.c +0 -716
- data/ext/ffi_c/libffi/src/types.c +0 -108
- data/ext/ffi_c/libffi/src/vax/elfbsd.S +0 -195
- data/ext/ffi_c/libffi/src/vax/ffi.c +0 -276
- data/ext/ffi_c/libffi/src/vax/ffitarget.h +0 -49
- data/ext/ffi_c/libffi/src/wasm32/ffi.c +0 -934
- data/ext/ffi_c/libffi/src/wasm32/ffitarget.h +0 -62
- data/ext/ffi_c/libffi/src/x86/asmnames.h +0 -30
- data/ext/ffi_c/libffi/src/x86/ffi.c +0 -832
- data/ext/ffi_c/libffi/src/x86/ffi64.c +0 -950
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +0 -164
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +0 -361
- data/ext/ffi_c/libffi/src/x86/internal.h +0 -43
- data/ext/ffi_c/libffi/src/x86/internal64.h +0 -36
- data/ext/ffi_c/libffi/src/x86/sysv.S +0 -1272
- data/ext/ffi_c/libffi/src/x86/sysv_intel.S +0 -998
- data/ext/ffi_c/libffi/src/x86/unix64.S +0 -711
- data/ext/ffi_c/libffi/src/x86/win64.S +0 -254
- data/ext/ffi_c/libffi/src/x86/win64_intel.S +0 -238
- data/ext/ffi_c/libffi/src/xtensa/ffi.c +0 -306
- data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +0 -57
- data/ext/ffi_c/libffi/src/xtensa/sysv.S +0 -268
- data/ext/ffi_c/libffi/stamp-h.in +0 -1
- data/ext/ffi_c/libffi/testsuite/Makefile.am +0 -135
- data/ext/ffi_c/libffi/testsuite/Makefile.in +0 -664
- data/ext/ffi_c/libffi/testsuite/config/default.exp +0 -1
- data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +0 -54
- data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +0 -63
- data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +0 -80
- data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +0 -48
- data/ext/ffi_c/libffi/testsuite/emscripten/test.html +0 -7
- data/ext/ffi_c/libffi/testsuite/emscripten/test_libffi.py +0 -51
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +0 -682
- data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +0 -283
- data/ext/ffi_c/libffi/testsuite/lib/wrapper.exp +0 -45
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/Makefile +0 -28
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/README +0 -78
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/alignof.h +0 -50
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +0 -63
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +0 -1746
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +0 -2885
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +0 -747
- data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +0 -46
- data/ext/ffi_c/libffi/testsuite/libffi.call/align_stdcall.c +0 -46
- data/ext/ffi_c/libffi/testsuite/libffi.call/bpo_38748.c +0 -41
- data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +0 -54
- data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +0 -26
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +0 -163
- data/ext/ffi_c/libffi/testsuite/libffi.call/float.c +0 -59
- data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +0 -60
- data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +0 -61
- data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +0 -74
- data/ext/ffi_c/libffi/testsuite/libffi.call/float4.c +0 -62
- data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +0 -110
- data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +0 -59
- data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +0 -57
- data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +0 -70
- data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +0 -78
- data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +0 -52
- data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +0 -46
- data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +0 -127
- data/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c +0 -59
- data/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc_tc.c +0 -114
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +0 -36
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c +0 -43
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c +0 -42
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c +0 -35
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c +0 -36
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c +0 -49
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c +0 -42
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +0 -34
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c +0 -41
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +0 -48
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +0 -36
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +0 -42
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +0 -38
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +0 -42
- data/ext/ffi_c/libffi/testsuite/libffi.call/s55.c +0 -60
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +0 -43
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +0 -49
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +0 -49
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +0 -55
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +0 -67
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +0 -57
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +0 -67
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +0 -60
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +0 -64
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +0 -66
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +0 -64
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +0 -74
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +0 -81
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +0 -68
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_2.c +0 -63
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3.c +0 -65
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3f.c +0 -65
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4.c +0 -67
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4f.c +0 -67
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_big.c +0 -93
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_small.c +0 -61
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_2H.c +0 -63
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_8H.c +0 -90
- data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +0 -61
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +0 -78
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_2.c +0 -220
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_3.c +0 -154
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +0 -134
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +0 -134
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +0 -140
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure.exp +0 -67
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn0.c +0 -90
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn1.c +0 -83
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn2.c +0 -83
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn3.c +0 -102
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn4.c +0 -91
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn5.c +0 -94
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn6.c +0 -92
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_loc_fn0.c +0 -96
- data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_simple.c +0 -61
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_12byte.c +0 -112
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_16byte.c +0 -117
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_18byte.c +0 -120
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_19byte.c +0 -131
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_1_1byte.c +0 -93
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_20byte.c +0 -109
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_20byte1.c +0 -113
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_24byte.c +0 -145
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_2byte.c +0 -103
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3_1byte.c +0 -114
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3byte1.c +0 -103
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3byte2.c +0 -103
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3float.c +0 -113
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_4_1byte.c +0 -120
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_4byte.c +0 -103
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_5_1_byte.c +0 -137
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_5byte.c +0 -116
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_64byte.c +0 -148
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_6_1_byte.c +0 -140
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_6byte.c +0 -121
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_7_1_byte.c +0 -155
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_7byte.c +0 -121
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_8byte.c +0 -102
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_9byte1.c +0 -103
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_9byte2.c +0 -103
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_double.c +0 -111
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_float.c +0 -109
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble.c +0 -111
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble_split.c +0 -147
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble_split2.c +0 -152
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_pointer.c +0 -113
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint16.c +0 -108
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint32.c +0 -106
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint64.c +0 -109
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint16.c +0 -108
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint32.c +0 -109
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint64.c +0 -111
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_dbls_struct.c +0 -68
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_double.c +0 -43
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_double_va.c +0 -69
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_float.c +0 -46
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_longdouble.c +0 -115
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_longdouble_va.c +0 -80
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_args.c +0 -70
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_float_double.c +0 -55
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_schar.c +0 -78
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshort.c +0 -79
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c +0 -94
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_uchar.c +0 -99
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushort.c +0 -78
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c +0 -94
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_pointer.c +0 -79
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_pointer_stack.c +0 -152
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_schar.c +0 -47
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_sint.c +0 -44
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_sshort.c +0 -45
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_struct_va1.c +0 -125
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uchar.c +0 -45
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint.c +0 -47
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint_va.c +0 -49
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulong_va.c +0 -49
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulonglong.c +0 -49
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ushort.c +0 -46
- data/ext/ffi_c/libffi/testsuite/libffi.closures/err_bad_abi.c +0 -36
- data/ext/ffi_c/libffi/testsuite/libffi.closures/ffitest.h +0 -1
- data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +0 -343
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct.c +0 -175
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct1.c +0 -161
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct10.c +0 -146
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct11.c +0 -137
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct12.c +0 -86
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct13.c +0 -115
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct2.c +0 -119
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct3.c +0 -120
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct4.c +0 -120
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct5.c +0 -121
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct6.c +0 -142
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct7.c +0 -120
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct8.c +0 -142
- data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct9.c +0 -142
- data/ext/ffi_c/libffi/testsuite/libffi.closures/problem1.c +0 -90
- data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs1.c +0 -86
- data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs2.c +0 -102
- data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs3.c +0 -101
- data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_large.c +0 -145
- data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_large2.c +0 -148
- data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_medium.c +0 -124
- data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_medium2.c +0 -125
- data/ext/ffi_c/libffi/testsuite/libffi.closures/testclosure.c +0 -75
- data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest.cc +0 -118
- data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc +0 -55
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +0 -91
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +0 -42
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +0 -71
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +0 -80
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +0 -16
- data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.exp +0 -36
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +0 -51
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +0 -7
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +0 -7
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +0 -7
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +0 -86
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +0 -1
- data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +0 -78
- data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +0 -37
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +0 -41
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +0 -44
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +0 -10
- data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +0 -34
- data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +0 -28
- data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +0 -1
- data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +0 -36
- data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +0 -19
- data/ext/ffi_c/libffi.bsd.mk +0 -40
- data/ext/ffi_c/libffi.darwin.mk +0 -105
- data/ext/ffi_c/libffi.gnu.mk +0 -32
- data/ext/ffi_c/libffi.mk +0 -18
- data/ext/ffi_c/libffi.vc.mk +0 -26
- data/ext/ffi_c/libffi.vc64.mk +0 -26
- data/ext/ffi_c/rbffi.h +0 -55
- data/ext/ffi_c/rbffi_endian.h +0 -59
data/ext/ffi_c/Function.c
DELETED
|
@@ -1,1063 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2009-2011 Wayne Meissner
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) 2008-2013, Ruby FFI project contributors
|
|
5
|
-
* All rights reserved.
|
|
6
|
-
*
|
|
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.
|
|
17
|
-
*
|
|
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.
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
#ifndef _MSC_VER
|
|
31
|
-
#include <sys/param.h>
|
|
32
|
-
#endif
|
|
33
|
-
#include <sys/types.h>
|
|
34
|
-
#ifndef _WIN32
|
|
35
|
-
# include <sys/mman.h>
|
|
36
|
-
# include <unistd.h>
|
|
37
|
-
#endif
|
|
38
|
-
|
|
39
|
-
#include <stdio.h>
|
|
40
|
-
#include <stdint.h>
|
|
41
|
-
#include <stdbool.h>
|
|
42
|
-
#include <ruby.h>
|
|
43
|
-
#include <ruby/thread.h>
|
|
44
|
-
|
|
45
|
-
#if HAVE_RB_EXT_RACTOR_SAFE
|
|
46
|
-
#include <ruby/ractor.h>
|
|
47
|
-
#endif
|
|
48
|
-
|
|
49
|
-
#include <ffi.h>
|
|
50
|
-
#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32)
|
|
51
|
-
#include <pthread.h>
|
|
52
|
-
#endif
|
|
53
|
-
#include <fcntl.h>
|
|
54
|
-
|
|
55
|
-
#include "rbffi.h"
|
|
56
|
-
#include "compat.h"
|
|
57
|
-
|
|
58
|
-
#include "AbstractMemory.h"
|
|
59
|
-
#include "Pointer.h"
|
|
60
|
-
#include "Struct.h"
|
|
61
|
-
#include "Platform.h"
|
|
62
|
-
#include "Type.h"
|
|
63
|
-
#include "LastError.h"
|
|
64
|
-
#include "Call.h"
|
|
65
|
-
#include "ClosurePool.h"
|
|
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
|
|
73
|
-
|
|
74
|
-
struct async_cb_dispatcher;
|
|
75
|
-
typedef struct Function_ {
|
|
76
|
-
Pointer base;
|
|
77
|
-
FunctionType* info;
|
|
78
|
-
MethodHandle* methodHandle;
|
|
79
|
-
bool autorelease;
|
|
80
|
-
Closure* closure;
|
|
81
|
-
VALUE rbProc;
|
|
82
|
-
VALUE rbFunctionInfo;
|
|
83
|
-
#if defined(DEFER_ASYNC_CALLBACK)
|
|
84
|
-
struct async_cb_dispatcher *dispatcher;
|
|
85
|
-
#endif
|
|
86
|
-
} Function;
|
|
87
|
-
|
|
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);
|
|
92
|
-
static VALUE function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc);
|
|
93
|
-
static void callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data);
|
|
94
|
-
static bool callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize);
|
|
95
|
-
static void* callback_with_gvl(void* data);
|
|
96
|
-
static VALUE invoke_callback(VALUE data);
|
|
97
|
-
static VALUE save_callback_exception(VALUE data, VALUE exc);
|
|
98
|
-
|
|
99
|
-
#if defined(DEFER_ASYNC_CALLBACK)
|
|
100
|
-
static VALUE async_cb_event(void *);
|
|
101
|
-
static VALUE async_cb_call(void *);
|
|
102
|
-
#endif
|
|
103
|
-
|
|
104
|
-
extern int ruby_thread_has_gvl_p(void);
|
|
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
|
-
};
|
|
120
|
-
|
|
121
|
-
VALUE rbffi_FunctionClass = Qnil;
|
|
122
|
-
|
|
123
|
-
static ID id_call = 0, id_to_native = 0, id_from_native = 0, id_cbtable = 0, id_cb_ref = 0;
|
|
124
|
-
|
|
125
|
-
struct gvl_callback {
|
|
126
|
-
Closure* closure;
|
|
127
|
-
void* retval;
|
|
128
|
-
void** parameters;
|
|
129
|
-
bool done;
|
|
130
|
-
rbffi_frame_t *frame;
|
|
131
|
-
#if defined(DEFER_ASYNC_CALLBACK)
|
|
132
|
-
struct async_cb_dispatcher *dispatcher;
|
|
133
|
-
struct gvl_callback* next;
|
|
134
|
-
|
|
135
|
-
/* Signal when the callback has finished and retval is set */
|
|
136
|
-
# ifndef _WIN32
|
|
137
|
-
pthread_cond_t async_cond;
|
|
138
|
-
pthread_mutex_t async_mutex;
|
|
139
|
-
# else
|
|
140
|
-
HANDLE async_event;
|
|
141
|
-
# endif
|
|
142
|
-
#endif
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
#if defined(DEFER_ASYNC_CALLBACK)
|
|
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 */
|
|
155
|
-
# ifndef _WIN32
|
|
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;
|
|
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
|
-
#endif
|
|
219
|
-
|
|
220
|
-
static VALUE
|
|
221
|
-
function_allocate(VALUE klass)
|
|
222
|
-
{
|
|
223
|
-
Function *fn;
|
|
224
|
-
VALUE obj;
|
|
225
|
-
|
|
226
|
-
obj = TypedData_Make_Struct(klass, Function, &function_data_type, fn);
|
|
227
|
-
|
|
228
|
-
fn->base.memory.flags = MEM_RD;
|
|
229
|
-
RB_OBJ_WRITE(obj, &fn->base.rbParent, Qnil);
|
|
230
|
-
RB_OBJ_WRITE(obj, &fn->rbProc, Qnil);
|
|
231
|
-
RB_OBJ_WRITE(obj, &fn->rbFunctionInfo, Qnil);
|
|
232
|
-
fn->autorelease = true;
|
|
233
|
-
|
|
234
|
-
return obj;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
static void
|
|
238
|
-
function_mark(void *data)
|
|
239
|
-
{
|
|
240
|
-
Function *fn = (Function *)data;
|
|
241
|
-
rb_gc_mark_movable(fn->base.rbParent);
|
|
242
|
-
rb_gc_mark_movable(fn->rbProc);
|
|
243
|
-
rb_gc_mark_movable(fn->rbFunctionInfo);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
static void
|
|
247
|
-
function_compact(void *data)
|
|
248
|
-
{
|
|
249
|
-
Function *fn = (Function *)data;
|
|
250
|
-
ffi_gc_location(fn->base.rbParent);
|
|
251
|
-
ffi_gc_location(fn->rbProc);
|
|
252
|
-
ffi_gc_location(fn->rbFunctionInfo);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
static void
|
|
256
|
-
function_free(void *data)
|
|
257
|
-
{
|
|
258
|
-
Function *fn = (Function *)data;
|
|
259
|
-
if (fn->methodHandle != NULL) {
|
|
260
|
-
rbffi_MethodHandle_Free(fn->methodHandle);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (fn->closure != NULL && fn->autorelease) {
|
|
264
|
-
rbffi_Closure_Free(fn->closure);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
xfree(fn);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
static size_t
|
|
271
|
-
function_memsize(const void *data)
|
|
272
|
-
{
|
|
273
|
-
const Function *fn = (const Function *)data;
|
|
274
|
-
size_t memsize = sizeof(Function);
|
|
275
|
-
|
|
276
|
-
// Would be nice to better account for MethodHandle and Closure too.
|
|
277
|
-
if (fn->closure) {
|
|
278
|
-
memsize += sizeof(Closure);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return memsize;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/*
|
|
285
|
-
* @param [Type, Symbol] return_type return type for the function
|
|
286
|
-
* @param [Array<Type, Symbol>] param_types array of parameters types
|
|
287
|
-
* @param [Hash] options see {FFI::FunctionType} for available options
|
|
288
|
-
* @return [self]
|
|
289
|
-
* A new Function instance.
|
|
290
|
-
*
|
|
291
|
-
* Define a function from a Proc or a block.
|
|
292
|
-
*
|
|
293
|
-
* @overload initialize(return_type, param_types, options = {}) { |i| ... }
|
|
294
|
-
* @yieldparam i parameters for the function
|
|
295
|
-
* @overload initialize(return_type, param_types, proc, options = {})
|
|
296
|
-
* @param [Proc] proc
|
|
297
|
-
*/
|
|
298
|
-
static VALUE
|
|
299
|
-
function_initialize(int argc, VALUE* argv, VALUE self)
|
|
300
|
-
{
|
|
301
|
-
|
|
302
|
-
VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbProc = Qnil, rbOptions = Qnil;
|
|
303
|
-
VALUE rbFunctionInfo = Qnil;
|
|
304
|
-
VALUE infoArgv[3];
|
|
305
|
-
int nargs;
|
|
306
|
-
|
|
307
|
-
nargs = rb_scan_args(argc, argv, "22", &rbReturnType, &rbParamTypes, &rbProc, &rbOptions);
|
|
308
|
-
|
|
309
|
-
/*
|
|
310
|
-
* Callback with block,
|
|
311
|
-
* e.g. Function.new(:int, [ :int ]) { |i| blah }
|
|
312
|
-
* or Function.new(:int, [ :int ], { :convention => :stdcall }) { |i| blah }
|
|
313
|
-
*/
|
|
314
|
-
if (rb_block_given_p()) {
|
|
315
|
-
if (nargs > 3) {
|
|
316
|
-
rb_raise(rb_eArgError, "cannot create function with both proc/address and block");
|
|
317
|
-
}
|
|
318
|
-
rbOptions = rbProc;
|
|
319
|
-
rbProc = rb_block_proc();
|
|
320
|
-
} else {
|
|
321
|
-
/* Callback with proc, or Function with address
|
|
322
|
-
* e.g. Function.new(:int, [ :int ], Proc.new { |i| })
|
|
323
|
-
* Function.new(:int, [ :int ], Proc.new { |i| }, { :convention => :stdcall })
|
|
324
|
-
* Function.new(:int, [ :int ], addr)
|
|
325
|
-
* Function.new(:int, [ :int ], addr, { :convention => :stdcall })
|
|
326
|
-
*/
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
infoArgv[0] = rbReturnType;
|
|
330
|
-
infoArgv[1] = rbParamTypes;
|
|
331
|
-
infoArgv[2] = rbOptions;
|
|
332
|
-
rbFunctionInfo = rb_class_new_instance(rbOptions != Qnil ? 3 : 2, infoArgv, rbffi_FunctionTypeClass);
|
|
333
|
-
|
|
334
|
-
function_init(self, rbFunctionInfo, rbProc);
|
|
335
|
-
|
|
336
|
-
return self;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/*
|
|
340
|
-
* call-seq: initialize_copy(other)
|
|
341
|
-
* @return [nil]
|
|
342
|
-
* DO NOT CALL THIS METHOD
|
|
343
|
-
*/
|
|
344
|
-
static VALUE
|
|
345
|
-
function_initialize_copy(VALUE self, VALUE other)
|
|
346
|
-
{
|
|
347
|
-
rb_raise(rb_eRuntimeError, "cannot duplicate function instances");
|
|
348
|
-
return Qnil;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
VALUE
|
|
352
|
-
rbffi_Function_NewInstance(VALUE rbFunctionInfo, VALUE rbProc)
|
|
353
|
-
{
|
|
354
|
-
return function_init(function_allocate(rbffi_FunctionClass), rbFunctionInfo, rbProc);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
VALUE
|
|
358
|
-
rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
|
|
359
|
-
{
|
|
360
|
-
VALUE callback, cbref, cbTable;
|
|
361
|
-
|
|
362
|
-
cbref = RTEST(rb_ivar_defined(proc, id_cb_ref)) ? rb_ivar_get(proc, id_cb_ref) : Qnil;
|
|
363
|
-
/* If the first callback reference has the same function function signature, use it */
|
|
364
|
-
if (cbref != Qnil && CLASS_OF(cbref) == rbffi_FunctionClass) {
|
|
365
|
-
Function* fp;
|
|
366
|
-
TypedData_Get_Struct(cbref, Function, &function_data_type, fp);
|
|
367
|
-
if (fp->rbFunctionInfo == rbFunctionInfo) {
|
|
368
|
-
return cbref;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
cbTable = RTEST(rb_ivar_defined(proc, id_cbtable)) ? rb_ivar_get(proc, id_cbtable) : Qnil;
|
|
373
|
-
if (cbTable != Qnil && (callback = rb_hash_aref(cbTable, rbFunctionInfo)) != Qnil) {
|
|
374
|
-
return callback;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/* No existing function for the proc with that signature, create a new one and cache it */
|
|
378
|
-
callback = rbffi_Function_NewInstance(rbFunctionInfo, proc);
|
|
379
|
-
if (cbref == Qnil) {
|
|
380
|
-
/* If there is no other cb already cached for this proc, we can use the ivar slot */
|
|
381
|
-
rb_ivar_set(proc, id_cb_ref, callback);
|
|
382
|
-
} else {
|
|
383
|
-
/* The proc instance has been used as more than one type of callback, store extras in a hash */
|
|
384
|
-
if(cbTable == Qnil) {
|
|
385
|
-
cbTable = rb_hash_new();
|
|
386
|
-
rb_ivar_set(proc, id_cbtable, cbTable);
|
|
387
|
-
}
|
|
388
|
-
rb_hash_aset(cbTable, rbFunctionInfo, callback);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
return callback;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
#if !defined(_WIN32) && defined(DEFER_ASYNC_CALLBACK)
|
|
395
|
-
static void
|
|
396
|
-
after_fork_callback(void)
|
|
397
|
-
{
|
|
398
|
-
/* Ensure that a new dispatcher thread is started in a forked process */
|
|
399
|
-
async_cb_dispatcher_set(NULL);
|
|
400
|
-
}
|
|
401
|
-
#endif
|
|
402
|
-
|
|
403
|
-
static VALUE
|
|
404
|
-
function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
|
|
405
|
-
{
|
|
406
|
-
Function* fn = NULL;
|
|
407
|
-
|
|
408
|
-
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
|
409
|
-
|
|
410
|
-
RB_OBJ_WRITE(self, &fn->rbFunctionInfo, rbFunctionInfo);
|
|
411
|
-
|
|
412
|
-
TypedData_Get_Struct(fn->rbFunctionInfo, FunctionType, &rbffi_fntype_data_type, fn->info);
|
|
413
|
-
|
|
414
|
-
if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) {
|
|
415
|
-
Pointer* orig;
|
|
416
|
-
TypedData_Get_Struct(rbProc, Pointer, &rbffi_pointer_data_type, orig);
|
|
417
|
-
fn->base.memory = orig->memory;
|
|
418
|
-
RB_OBJ_WRITE(self, &fn->base.rbParent, rbProc);
|
|
419
|
-
|
|
420
|
-
} else if (rb_obj_is_kind_of(rbProc, rb_cProc) || rb_respond_to(rbProc, id_call)) {
|
|
421
|
-
if (fn->info->closurePool == NULL) {
|
|
422
|
-
fn->info->closurePool = rbffi_ClosurePool_New(sizeof(ffi_closure), callback_prep, fn->info);
|
|
423
|
-
if (fn->info->closurePool == NULL) {
|
|
424
|
-
rb_raise(rb_eNoMemError, "failed to create closure pool");
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
#if defined(DEFER_ASYNC_CALLBACK)
|
|
429
|
-
{
|
|
430
|
-
struct async_cb_dispatcher *ctx = async_cb_dispatcher_get();
|
|
431
|
-
if (ctx == NULL) {
|
|
432
|
-
ctx = (struct async_cb_dispatcher*)ALLOC(struct async_cb_dispatcher);
|
|
433
|
-
ctx->async_cb_list = NULL;
|
|
434
|
-
|
|
435
|
-
#if !defined(_WIN32)
|
|
436
|
-
pthread_mutex_init(&ctx->async_cb_mutex, NULL);
|
|
437
|
-
pthread_cond_init(&ctx->async_cb_cond, NULL);
|
|
438
|
-
if( pthread_atfork(NULL, NULL, after_fork_callback) ){
|
|
439
|
-
rb_warn("FFI: unable to register fork callback");
|
|
440
|
-
}
|
|
441
|
-
#else
|
|
442
|
-
InitializeCriticalSection(&ctx->async_cb_lock);
|
|
443
|
-
ctx->async_cb_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
444
|
-
#endif
|
|
445
|
-
ctx->thread = rb_thread_create(async_cb_event, ctx);
|
|
446
|
-
|
|
447
|
-
/* Name thread, for better debugging */
|
|
448
|
-
rb_funcall(ctx->thread, rb_intern("name="), 1, rb_str_new2("FFI Callback Dispatcher"));
|
|
449
|
-
|
|
450
|
-
async_cb_dispatcher_set(ctx);
|
|
451
|
-
}
|
|
452
|
-
fn->dispatcher = ctx;
|
|
453
|
-
}
|
|
454
|
-
#endif
|
|
455
|
-
|
|
456
|
-
fn->closure = rbffi_Closure_Alloc(fn->info->closurePool);
|
|
457
|
-
fn->closure->info = fn;
|
|
458
|
-
fn->base.memory.address = fn->closure->code;
|
|
459
|
-
fn->base.memory.size = sizeof(*fn->closure);
|
|
460
|
-
fn->autorelease = true;
|
|
461
|
-
|
|
462
|
-
} else {
|
|
463
|
-
rb_raise(rb_eTypeError, "wrong argument type %s, expected pointer or proc",
|
|
464
|
-
rb_obj_classname(rbProc));
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
RB_OBJ_WRITE(self, &fn->rbProc, rbProc);
|
|
468
|
-
|
|
469
|
-
return self;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
/*
|
|
473
|
-
* call-seq: call(*args)
|
|
474
|
-
* @param [Array] args function arguments
|
|
475
|
-
* @return [FFI::Type]
|
|
476
|
-
* Call the function
|
|
477
|
-
*/
|
|
478
|
-
static VALUE
|
|
479
|
-
function_call(int argc, VALUE* argv, VALUE self)
|
|
480
|
-
{
|
|
481
|
-
Function* fn;
|
|
482
|
-
|
|
483
|
-
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
|
484
|
-
|
|
485
|
-
return (*fn->info->invoke)(argc, argv, fn->base.memory.address, fn->info);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
/*
|
|
489
|
-
* call-seq: attach(m, name)
|
|
490
|
-
* @param [Module] m
|
|
491
|
-
* @param [String] name
|
|
492
|
-
* @return [self]
|
|
493
|
-
* Attach a Function to the Module +m+ as +name+.
|
|
494
|
-
*/
|
|
495
|
-
static VALUE
|
|
496
|
-
function_attach(VALUE self, VALUE module, VALUE name)
|
|
497
|
-
{
|
|
498
|
-
Function* fn;
|
|
499
|
-
|
|
500
|
-
StringValue(name);
|
|
501
|
-
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
|
502
|
-
|
|
503
|
-
if (fn->info->parameterCount == -1) {
|
|
504
|
-
rb_raise(rb_eRuntimeError, "cannot attach variadic functions");
|
|
505
|
-
return Qnil;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
if (!rb_obj_is_kind_of(module, rb_cModule)) {
|
|
509
|
-
rb_raise(rb_eRuntimeError, "trying to attach function to non-module");
|
|
510
|
-
return Qnil;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
if (fn->methodHandle == NULL) {
|
|
514
|
-
fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->base.memory.address);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
rb_define_singleton_method(module, StringValueCStr(name),
|
|
518
|
-
rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
rb_define_method(module, StringValueCStr(name),
|
|
522
|
-
rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
|
|
523
|
-
|
|
524
|
-
return self;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
/*
|
|
528
|
-
* call-seq: autorelease = autorelease
|
|
529
|
-
* @param [Boolean] autorelease
|
|
530
|
-
* @return [self]
|
|
531
|
-
* Set +autorelease+ attribute (See {Pointer}).
|
|
532
|
-
*/
|
|
533
|
-
static VALUE
|
|
534
|
-
function_set_autorelease(VALUE self, VALUE autorelease)
|
|
535
|
-
{
|
|
536
|
-
Function* fn;
|
|
537
|
-
|
|
538
|
-
rb_check_frozen(self);
|
|
539
|
-
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
|
540
|
-
|
|
541
|
-
fn->autorelease = RTEST(autorelease);
|
|
542
|
-
|
|
543
|
-
return self;
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
static VALUE
|
|
547
|
-
function_autorelease_p(VALUE self)
|
|
548
|
-
{
|
|
549
|
-
Function* fn;
|
|
550
|
-
|
|
551
|
-
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
|
552
|
-
|
|
553
|
-
return fn->autorelease ? Qtrue : Qfalse;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
static VALUE
|
|
557
|
-
function_type(VALUE self)
|
|
558
|
-
{
|
|
559
|
-
Function* fn;
|
|
560
|
-
|
|
561
|
-
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
|
562
|
-
|
|
563
|
-
return fn->rbFunctionInfo;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
/*
|
|
567
|
-
* call-seq: free
|
|
568
|
-
* @return [self]
|
|
569
|
-
* Free memory allocated by Function.
|
|
570
|
-
*/
|
|
571
|
-
static VALUE
|
|
572
|
-
function_release(VALUE self)
|
|
573
|
-
{
|
|
574
|
-
Function* fn;
|
|
575
|
-
|
|
576
|
-
TypedData_Get_Struct(self, Function, &function_data_type, fn);
|
|
577
|
-
|
|
578
|
-
if (fn->closure == NULL) {
|
|
579
|
-
rb_raise(rb_eRuntimeError, "cannot free function which was not allocated");
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
rbffi_Closure_Free(fn->closure);
|
|
583
|
-
fn->closure = NULL;
|
|
584
|
-
|
|
585
|
-
return self;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
static void
|
|
589
|
-
callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
|
590
|
-
{
|
|
591
|
-
Function* fn;
|
|
592
|
-
struct gvl_callback cb = { 0 };
|
|
593
|
-
|
|
594
|
-
cb.closure = (Closure *) user_data;
|
|
595
|
-
cb.retval = retval;
|
|
596
|
-
cb.parameters = parameters;
|
|
597
|
-
cb.done = false;
|
|
598
|
-
cb.frame = rbffi_frame_current();
|
|
599
|
-
fn = (Function *) cb.closure->info;
|
|
600
|
-
|
|
601
|
-
if (cb.frame != NULL) cb.frame->exc = Qnil;
|
|
602
|
-
|
|
603
|
-
if (ruby_native_thread_p()) {
|
|
604
|
-
if(ruby_thread_has_gvl_p()) {
|
|
605
|
-
callback_with_gvl(&cb);
|
|
606
|
-
} else {
|
|
607
|
-
rb_thread_call_with_gvl(callback_with_gvl, &cb);
|
|
608
|
-
}
|
|
609
|
-
#if defined(DEFER_ASYNC_CALLBACK) && !defined(_WIN32)
|
|
610
|
-
} else {
|
|
611
|
-
bool empty = false;
|
|
612
|
-
struct async_cb_dispatcher *ctx = fn->dispatcher;
|
|
613
|
-
|
|
614
|
-
pthread_mutex_init(&cb.async_mutex, NULL);
|
|
615
|
-
pthread_cond_init(&cb.async_cond, NULL);
|
|
616
|
-
|
|
617
|
-
/* Now signal the async callback dispatcher thread */
|
|
618
|
-
pthread_mutex_lock(&ctx->async_cb_mutex);
|
|
619
|
-
empty = ctx->async_cb_list == NULL;
|
|
620
|
-
cb.next = ctx->async_cb_list;
|
|
621
|
-
ctx->async_cb_list = &cb;
|
|
622
|
-
|
|
623
|
-
pthread_cond_signal(&ctx->async_cb_cond);
|
|
624
|
-
pthread_mutex_unlock(&ctx->async_cb_mutex);
|
|
625
|
-
|
|
626
|
-
/* Wait for the thread executing the ruby callback to signal it is done */
|
|
627
|
-
pthread_mutex_lock(&cb.async_mutex);
|
|
628
|
-
while (!cb.done) {
|
|
629
|
-
pthread_cond_wait(&cb.async_cond, &cb.async_mutex);
|
|
630
|
-
}
|
|
631
|
-
pthread_mutex_unlock(&cb.async_mutex);
|
|
632
|
-
pthread_cond_destroy(&cb.async_cond);
|
|
633
|
-
pthread_mutex_destroy(&cb.async_mutex);
|
|
634
|
-
|
|
635
|
-
#elif defined(DEFER_ASYNC_CALLBACK) && defined(_WIN32)
|
|
636
|
-
} else {
|
|
637
|
-
bool empty = false;
|
|
638
|
-
struct async_cb_dispatcher *ctx = fn->dispatcher;
|
|
639
|
-
|
|
640
|
-
cb.async_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
641
|
-
|
|
642
|
-
/* Now signal the async callback dispatcher thread */
|
|
643
|
-
EnterCriticalSection(&ctx->async_cb_lock);
|
|
644
|
-
empty = ctx->async_cb_list == NULL;
|
|
645
|
-
cb.next = ctx->async_cb_list;
|
|
646
|
-
ctx->async_cb_list = &cb;
|
|
647
|
-
LeaveCriticalSection(&ctx->async_cb_lock);
|
|
648
|
-
|
|
649
|
-
SetEvent(ctx->async_cb_cond);
|
|
650
|
-
|
|
651
|
-
/* Wait for the thread executing the ruby callback to signal it is done */
|
|
652
|
-
WaitForSingleObject(cb.async_event, INFINITE);
|
|
653
|
-
CloseHandle(cb.async_event);
|
|
654
|
-
#endif
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
#if defined(DEFER_ASYNC_CALLBACK)
|
|
659
|
-
struct async_wait {
|
|
660
|
-
struct async_cb_dispatcher *dispatcher;
|
|
661
|
-
void* cb;
|
|
662
|
-
bool stop;
|
|
663
|
-
};
|
|
664
|
-
|
|
665
|
-
static void * async_cb_wait(void *);
|
|
666
|
-
static void async_cb_stop(void *);
|
|
667
|
-
|
|
668
|
-
static VALUE
|
|
669
|
-
async_cb_event(void* ptr)
|
|
670
|
-
{
|
|
671
|
-
struct async_cb_dispatcher *ctx = (struct async_cb_dispatcher *)ptr;
|
|
672
|
-
struct async_wait w = { ctx };
|
|
673
|
-
|
|
674
|
-
w.stop = false;
|
|
675
|
-
while (!w.stop) {
|
|
676
|
-
rb_thread_call_without_gvl(async_cb_wait, &w, async_cb_stop, &w);
|
|
677
|
-
if (w.cb != NULL) {
|
|
678
|
-
/* Start up a new ruby thread to run the ruby callback */
|
|
679
|
-
VALUE new_thread = rb_thread_create(async_cb_call, w.cb);
|
|
680
|
-
/* Name thread, for better debugging */
|
|
681
|
-
rb_funcall(new_thread, rb_intern("name="), 1, rb_str_new2("FFI Callback Runner"));
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
return Qnil;
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
#ifdef _WIN32
|
|
689
|
-
static void *
|
|
690
|
-
async_cb_wait(void *data)
|
|
691
|
-
{
|
|
692
|
-
struct async_wait* w = (struct async_wait *) data;
|
|
693
|
-
struct async_cb_dispatcher *ctx = w->dispatcher;
|
|
694
|
-
|
|
695
|
-
w->cb = NULL;
|
|
696
|
-
|
|
697
|
-
EnterCriticalSection(&ctx->async_cb_lock);
|
|
698
|
-
|
|
699
|
-
while (!w->stop && ctx->async_cb_list == NULL) {
|
|
700
|
-
LeaveCriticalSection(&ctx->async_cb_lock);
|
|
701
|
-
WaitForSingleObject(ctx->async_cb_cond, INFINITE);
|
|
702
|
-
EnterCriticalSection(&ctx->async_cb_lock);
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
if (ctx->async_cb_list != NULL) {
|
|
706
|
-
w->cb = ctx->async_cb_list;
|
|
707
|
-
ctx->async_cb_list = ctx->async_cb_list->next;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
LeaveCriticalSection(&ctx->async_cb_lock);
|
|
711
|
-
|
|
712
|
-
return NULL;
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
static void
|
|
716
|
-
async_cb_stop(void *data)
|
|
717
|
-
{
|
|
718
|
-
struct async_wait* w = (struct async_wait *) data;
|
|
719
|
-
struct async_cb_dispatcher *ctx = w->dispatcher;
|
|
720
|
-
|
|
721
|
-
EnterCriticalSection(&ctx->async_cb_lock);
|
|
722
|
-
w->stop = true;
|
|
723
|
-
LeaveCriticalSection(&ctx->async_cb_lock);
|
|
724
|
-
SetEvent(ctx->async_cb_cond);
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
#else
|
|
728
|
-
static void *
|
|
729
|
-
async_cb_wait(void *data)
|
|
730
|
-
{
|
|
731
|
-
struct async_wait* w = (struct async_wait *) data;
|
|
732
|
-
struct async_cb_dispatcher *ctx = w->dispatcher;
|
|
733
|
-
|
|
734
|
-
w->cb = NULL;
|
|
735
|
-
|
|
736
|
-
pthread_mutex_lock(&ctx->async_cb_mutex);
|
|
737
|
-
|
|
738
|
-
while (!w->stop && ctx->async_cb_list == NULL) {
|
|
739
|
-
pthread_cond_wait(&ctx->async_cb_cond, &ctx->async_cb_mutex);
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
if (ctx->async_cb_list != NULL) {
|
|
743
|
-
w->cb = ctx->async_cb_list;
|
|
744
|
-
ctx->async_cb_list = ctx->async_cb_list->next;
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
pthread_mutex_unlock(&ctx->async_cb_mutex);
|
|
748
|
-
|
|
749
|
-
return NULL;
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
static void
|
|
753
|
-
async_cb_stop(void *data)
|
|
754
|
-
{
|
|
755
|
-
struct async_wait* w = (struct async_wait *) data;
|
|
756
|
-
struct async_cb_dispatcher *ctx = w->dispatcher;
|
|
757
|
-
|
|
758
|
-
pthread_mutex_lock(&ctx->async_cb_mutex);
|
|
759
|
-
w->stop = true;
|
|
760
|
-
pthread_cond_signal(&ctx->async_cb_cond);
|
|
761
|
-
pthread_mutex_unlock(&ctx->async_cb_mutex);
|
|
762
|
-
}
|
|
763
|
-
#endif
|
|
764
|
-
|
|
765
|
-
static VALUE
|
|
766
|
-
async_cb_call(void *data)
|
|
767
|
-
{
|
|
768
|
-
struct gvl_callback* cb = (struct gvl_callback *) data;
|
|
769
|
-
|
|
770
|
-
callback_with_gvl(data);
|
|
771
|
-
|
|
772
|
-
/* Signal the original native thread that the ruby code has completed */
|
|
773
|
-
#ifdef _WIN32
|
|
774
|
-
SetEvent(cb->async_event);
|
|
775
|
-
#else
|
|
776
|
-
pthread_mutex_lock(&cb->async_mutex);
|
|
777
|
-
cb->done = true;
|
|
778
|
-
pthread_cond_signal(&cb->async_cond);
|
|
779
|
-
pthread_mutex_unlock(&cb->async_mutex);
|
|
780
|
-
#endif
|
|
781
|
-
|
|
782
|
-
return Qnil;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
#endif
|
|
786
|
-
|
|
787
|
-
static void *
|
|
788
|
-
callback_with_gvl(void* data)
|
|
789
|
-
{
|
|
790
|
-
rb_rescue2(invoke_callback, (VALUE) data, save_callback_exception, (VALUE) data, rb_eException, (VALUE) 0);
|
|
791
|
-
return NULL;
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
static VALUE
|
|
795
|
-
invoke_callback(VALUE data)
|
|
796
|
-
{
|
|
797
|
-
struct gvl_callback* cb = (struct gvl_callback *) data;
|
|
798
|
-
|
|
799
|
-
Function* fn = (Function *) cb->closure->info;
|
|
800
|
-
FunctionType *cbInfo = fn->info;
|
|
801
|
-
Type* returnType = cbInfo->returnType;
|
|
802
|
-
void* retval = cb->retval;
|
|
803
|
-
void** parameters = cb->parameters;
|
|
804
|
-
VALUE* rbParams;
|
|
805
|
-
VALUE rbReturnType = cbInfo->rbReturnType;
|
|
806
|
-
VALUE rbReturnValue;
|
|
807
|
-
int i;
|
|
808
|
-
|
|
809
|
-
rbParams = ALLOCA_N(VALUE, cbInfo->parameterCount);
|
|
810
|
-
for (i = 0; i < cbInfo->parameterCount; ++i) {
|
|
811
|
-
VALUE param;
|
|
812
|
-
Type* paramType = cbInfo->parameterTypes[i];
|
|
813
|
-
VALUE rbParamType = rb_ary_entry(cbInfo->rbParameterTypes, i);
|
|
814
|
-
|
|
815
|
-
if (unlikely(paramType->nativeType == NATIVE_MAPPED)) {
|
|
816
|
-
rbParamType = ((MappedType *) paramType)->rbType;
|
|
817
|
-
paramType = ((MappedType *) paramType)->type;
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
switch (paramType->nativeType) {
|
|
821
|
-
case NATIVE_INT8:
|
|
822
|
-
param = INT2NUM(*(int8_t *) parameters[i]);
|
|
823
|
-
break;
|
|
824
|
-
case NATIVE_UINT8:
|
|
825
|
-
param = UINT2NUM(*(uint8_t *) parameters[i]);
|
|
826
|
-
break;
|
|
827
|
-
case NATIVE_INT16:
|
|
828
|
-
param = INT2NUM(*(int16_t *) parameters[i]);
|
|
829
|
-
break;
|
|
830
|
-
case NATIVE_UINT16:
|
|
831
|
-
param = UINT2NUM(*(uint16_t *) parameters[i]);
|
|
832
|
-
break;
|
|
833
|
-
case NATIVE_INT32:
|
|
834
|
-
param = INT2NUM(*(int32_t *) parameters[i]);
|
|
835
|
-
break;
|
|
836
|
-
case NATIVE_UINT32:
|
|
837
|
-
param = UINT2NUM(*(uint32_t *) parameters[i]);
|
|
838
|
-
break;
|
|
839
|
-
case NATIVE_INT64:
|
|
840
|
-
param = LL2NUM(*(int64_t *) parameters[i]);
|
|
841
|
-
break;
|
|
842
|
-
case NATIVE_UINT64:
|
|
843
|
-
param = ULL2NUM(*(uint64_t *) parameters[i]);
|
|
844
|
-
break;
|
|
845
|
-
case NATIVE_LONG:
|
|
846
|
-
param = LONG2NUM(*(long *) parameters[i]);
|
|
847
|
-
break;
|
|
848
|
-
case NATIVE_ULONG:
|
|
849
|
-
param = ULONG2NUM(*(unsigned long *) parameters[i]);
|
|
850
|
-
break;
|
|
851
|
-
case NATIVE_FLOAT32:
|
|
852
|
-
param = rb_float_new(*(float *) parameters[i]);
|
|
853
|
-
break;
|
|
854
|
-
case NATIVE_FLOAT64:
|
|
855
|
-
param = rb_float_new(*(double *) parameters[i]);
|
|
856
|
-
break;
|
|
857
|
-
case NATIVE_LONGDOUBLE:
|
|
858
|
-
param = rbffi_longdouble_new(*(long double *) parameters[i]);
|
|
859
|
-
break;
|
|
860
|
-
case NATIVE_STRING:
|
|
861
|
-
param = (*(void **) parameters[i] != NULL) ? rb_str_new2(*(char **) parameters[i]) : Qnil;
|
|
862
|
-
break;
|
|
863
|
-
case NATIVE_POINTER:
|
|
864
|
-
param = rbffi_Pointer_NewInstance(*(void **) parameters[i]);
|
|
865
|
-
break;
|
|
866
|
-
case NATIVE_BOOL:
|
|
867
|
-
param = (*(uint8_t *) parameters[i]) ? Qtrue : Qfalse;
|
|
868
|
-
break;
|
|
869
|
-
|
|
870
|
-
case NATIVE_FUNCTION:
|
|
871
|
-
case NATIVE_STRUCT:
|
|
872
|
-
param = rbffi_NativeValue_ToRuby(paramType, rbParamType, parameters[i]);
|
|
873
|
-
break;
|
|
874
|
-
|
|
875
|
-
default:
|
|
876
|
-
param = Qnil;
|
|
877
|
-
break;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
/* Convert the native value into a custom ruby value */
|
|
881
|
-
if (unlikely(cbInfo->parameterTypes[i]->nativeType == NATIVE_MAPPED)) {
|
|
882
|
-
VALUE values[] = { param, Qnil };
|
|
883
|
-
param = rb_funcall2(((MappedType *) cbInfo->parameterTypes[i])->rbConverter, id_from_native, 2, values);
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
rbParams[i] = param;
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams);
|
|
890
|
-
|
|
891
|
-
if (unlikely(returnType->nativeType == NATIVE_MAPPED)) {
|
|
892
|
-
VALUE values[] = { rbReturnValue, Qnil };
|
|
893
|
-
rbReturnValue = rb_funcall2(((MappedType *) returnType)->rbConverter, id_to_native, 2, values);
|
|
894
|
-
rbReturnType = ((MappedType *) returnType)->rbType;
|
|
895
|
-
returnType = ((MappedType* ) returnType)->type;
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
if (rbReturnValue == Qnil || TYPE(rbReturnValue) == T_NIL) {
|
|
899
|
-
memset(retval, 0, returnType->ffiType->size);
|
|
900
|
-
} else switch (returnType->nativeType) {
|
|
901
|
-
case NATIVE_INT8:
|
|
902
|
-
case NATIVE_INT16:
|
|
903
|
-
case NATIVE_INT32:
|
|
904
|
-
*((ffi_sarg *) retval) = NUM2INT(rbReturnValue);
|
|
905
|
-
break;
|
|
906
|
-
case NATIVE_UINT8:
|
|
907
|
-
case NATIVE_UINT16:
|
|
908
|
-
case NATIVE_UINT32:
|
|
909
|
-
*((ffi_arg *) retval) = NUM2UINT(rbReturnValue);
|
|
910
|
-
break;
|
|
911
|
-
case NATIVE_INT64:
|
|
912
|
-
*((int64_t *) retval) = NUM2LL(rbReturnValue);
|
|
913
|
-
break;
|
|
914
|
-
case NATIVE_UINT64:
|
|
915
|
-
*((uint64_t *) retval) = NUM2ULL(rbReturnValue);
|
|
916
|
-
break;
|
|
917
|
-
case NATIVE_LONG:
|
|
918
|
-
*((ffi_sarg *) retval) = NUM2LONG(rbReturnValue);
|
|
919
|
-
break;
|
|
920
|
-
case NATIVE_ULONG:
|
|
921
|
-
*((ffi_arg *) retval) = NUM2ULONG(rbReturnValue);
|
|
922
|
-
break;
|
|
923
|
-
case NATIVE_FLOAT32:
|
|
924
|
-
*((float *) retval) = (float) NUM2DBL(rbReturnValue);
|
|
925
|
-
break;
|
|
926
|
-
case NATIVE_FLOAT64:
|
|
927
|
-
*((double *) retval) = NUM2DBL(rbReturnValue);
|
|
928
|
-
break;
|
|
929
|
-
case NATIVE_LONGDOUBLE:
|
|
930
|
-
*((long double *) retval) = rbffi_num2longdouble(rbReturnValue);
|
|
931
|
-
break;
|
|
932
|
-
case NATIVE_POINTER:
|
|
933
|
-
if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
|
|
934
|
-
AbstractMemory* memory;
|
|
935
|
-
TypedData_Get_Struct(rbReturnValue, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
|
|
936
|
-
*((void **) retval) = memory->address;
|
|
937
|
-
} else {
|
|
938
|
-
/* Default to returning NULL if not a value pointer object. handles nil case as well */
|
|
939
|
-
*((void **) retval) = NULL;
|
|
940
|
-
}
|
|
941
|
-
break;
|
|
942
|
-
|
|
943
|
-
case NATIVE_BOOL:
|
|
944
|
-
*((ffi_arg *) retval) = rbReturnValue == Qtrue;
|
|
945
|
-
break;
|
|
946
|
-
|
|
947
|
-
case NATIVE_FUNCTION:
|
|
948
|
-
if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
|
|
949
|
-
AbstractMemory* memory;
|
|
950
|
-
TypedData_Get_Struct(rbReturnValue, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
|
|
951
|
-
|
|
952
|
-
*((void **) retval) = memory->address;
|
|
953
|
-
|
|
954
|
-
} else if (rb_obj_is_kind_of(rbReturnValue, rb_cProc) || rb_respond_to(rbReturnValue, id_call)) {
|
|
955
|
-
VALUE function;
|
|
956
|
-
AbstractMemory* memory;
|
|
957
|
-
|
|
958
|
-
function = rbffi_Function_ForProc(rbReturnType, rbReturnValue);
|
|
959
|
-
|
|
960
|
-
TypedData_Get_Struct(function, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
|
|
961
|
-
|
|
962
|
-
*((void **) retval) = memory->address;
|
|
963
|
-
} else {
|
|
964
|
-
*((void **) retval) = NULL;
|
|
965
|
-
}
|
|
966
|
-
break;
|
|
967
|
-
|
|
968
|
-
case NATIVE_STRUCT:
|
|
969
|
-
if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_StructClass)) {
|
|
970
|
-
Struct* s;
|
|
971
|
-
AbstractMemory* memory;
|
|
972
|
-
|
|
973
|
-
TypedData_Get_Struct(rbReturnValue, Struct, &rbffi_struct_data_type, s);
|
|
974
|
-
memory = s->pointer;
|
|
975
|
-
|
|
976
|
-
if (memory->address != NULL) {
|
|
977
|
-
memcpy(retval, memory->address, returnType->ffiType->size);
|
|
978
|
-
|
|
979
|
-
} else {
|
|
980
|
-
memset(retval, 0, returnType->ffiType->size);
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
} else {
|
|
984
|
-
memset(retval, 0, returnType->ffiType->size);
|
|
985
|
-
}
|
|
986
|
-
break;
|
|
987
|
-
|
|
988
|
-
default:
|
|
989
|
-
*((ffi_arg *) retval) = 0;
|
|
990
|
-
break;
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
return Qnil;
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
static VALUE
|
|
997
|
-
save_callback_exception(VALUE data, VALUE exc)
|
|
998
|
-
{
|
|
999
|
-
struct gvl_callback* cb = (struct gvl_callback *) data;
|
|
1000
|
-
|
|
1001
|
-
memset(cb->retval, 0, ((Function *) cb->closure->info)->info->returnType->ffiType->size);
|
|
1002
|
-
if (cb->frame != NULL) cb->frame->exc = exc;
|
|
1003
|
-
|
|
1004
|
-
return Qnil;
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
static bool
|
|
1008
|
-
callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
|
|
1009
|
-
{
|
|
1010
|
-
FunctionType* fnInfo = (FunctionType *) ctx;
|
|
1011
|
-
ffi_status ffiStatus;
|
|
1012
|
-
|
|
1013
|
-
ffiStatus = ffi_prep_closure_loc(closure->pcl, &fnInfo->ffi_cif, callback_invoke, closure, code);
|
|
1014
|
-
if (ffiStatus != FFI_OK) {
|
|
1015
|
-
snprintf(errmsg, errmsgsize, "ffi_prep_closure_loc failed. status=%#x", ffiStatus);
|
|
1016
|
-
return false;
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
return true;
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
void
|
|
1023
|
-
rbffi_Function_Init(VALUE moduleFFI)
|
|
1024
|
-
{
|
|
1025
|
-
rbffi_FunctionInfo_Init(moduleFFI);
|
|
1026
|
-
/*
|
|
1027
|
-
* Document-class: FFI::Function < FFI::Pointer
|
|
1028
|
-
*/
|
|
1029
|
-
rbffi_FunctionClass = rb_define_class_under(moduleFFI, "Function", rbffi_PointerClass);
|
|
1030
|
-
|
|
1031
|
-
rb_global_variable(&rbffi_FunctionClass);
|
|
1032
|
-
rb_define_alloc_func(rbffi_FunctionClass, function_allocate);
|
|
1033
|
-
|
|
1034
|
-
rb_define_method(rbffi_FunctionClass, "initialize", function_initialize, -1);
|
|
1035
|
-
rb_define_method(rbffi_FunctionClass, "initialize_copy", function_initialize_copy, 1);
|
|
1036
|
-
rb_define_method(rbffi_FunctionClass, "call", function_call, -1);
|
|
1037
|
-
rb_define_method(rbffi_FunctionClass, "attach", function_attach, 2);
|
|
1038
|
-
rb_define_method(rbffi_FunctionClass, "free", function_release, 0);
|
|
1039
|
-
rb_define_method(rbffi_FunctionClass, "autorelease=", function_set_autorelease, 1);
|
|
1040
|
-
rb_define_private_method(rbffi_FunctionClass, "type", function_type, 0);
|
|
1041
|
-
/*
|
|
1042
|
-
* call-seq: autorelease
|
|
1043
|
-
* @return [Boolean]
|
|
1044
|
-
* Get +autorelease+ attribute.
|
|
1045
|
-
* Synonymous for {#autorelease?}.
|
|
1046
|
-
*/
|
|
1047
|
-
rb_define_method(rbffi_FunctionClass, "autorelease", function_autorelease_p, 0);
|
|
1048
|
-
/*
|
|
1049
|
-
* call-seq: autorelease?
|
|
1050
|
-
* @return [Boolean] +autorelease+ attribute
|
|
1051
|
-
* Get +autorelease+ attribute.
|
|
1052
|
-
*/
|
|
1053
|
-
rb_define_method(rbffi_FunctionClass, "autorelease?", function_autorelease_p, 0);
|
|
1054
|
-
|
|
1055
|
-
id_call = rb_intern("call");
|
|
1056
|
-
id_cbtable = rb_intern("@__ffi_callback_table__");
|
|
1057
|
-
id_cb_ref = rb_intern("@__ffi_callback__");
|
|
1058
|
-
id_to_native = rb_intern("to_native");
|
|
1059
|
-
id_from_native = rb_intern("from_native");
|
|
1060
|
-
#if defined(DEFER_ASYNC_CALLBACK) && defined(HAVE_RB_EXT_RACTOR_SAFE)
|
|
1061
|
-
async_cb_dispatcher_key = rb_ractor_local_storage_ptr_newkey(&async_cb_dispatcher_key_type);
|
|
1062
|
-
#endif
|
|
1063
|
-
}
|