ffi 1.16.3 → 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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +51 -0
- data/Gemfile +9 -2
- data/README.md +1 -1
- data/Rakefile +18 -6
- data/ext/ffi_c/AbstractMemory.c +39 -38
- data/ext/ffi_c/ArrayType.c +2 -2
- data/ext/ffi_c/Buffer.c +4 -4
- data/ext/ffi_c/Call.c +12 -6
- data/ext/ffi_c/Call.h +3 -2
- data/ext/ffi_c/DynamicLibrary.c +2 -2
- data/ext/ffi_c/Function.c +52 -34
- data/ext/ffi_c/FunctionInfo.c +1 -1
- data/ext/ffi_c/LastError.c +4 -4
- data/ext/ffi_c/MemoryPointer.c +2 -2
- data/ext/ffi_c/Pointer.c +14 -11
- data/ext/ffi_c/Struct.c +11 -4
- data/ext/ffi_c/StructLayout.c +13 -13
- data/ext/ffi_c/Type.c +17 -16
- data/ext/ffi_c/Types.c +7 -1
- data/ext/ffi_c/Types.h +0 -1
- data/ext/ffi_c/Variadic.c +6 -3
- data/ext/ffi_c/libffi/.allow-ai-service +0 -0
- data/ext/ffi_c/libffi/.github/workflows/build.yml +34 -15
- data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +2 -1
- data/ext/ffi_c/libffi/LICENSE +1 -1
- data/ext/ffi_c/libffi/README.md +10 -5
- data/ext/ffi_c/libffi/configure +1254 -940
- data/ext/ffi_c/libffi/configure.ac +2 -2
- data/ext/ffi_c/libffi/configure.host +1 -1
- data/ext/ffi_c/libffi/doc/libffi.texi +1 -1
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +6 -6
- data/ext/ffi_c/libffi/include/ffi.h.in +2 -11
- data/ext/ffi_c/libffi/include/ffi_common.h +4 -2
- data/ext/ffi_c/libffi/libffi.map.in +5 -0
- data/ext/ffi_c/libffi/libtool-version +1 -1
- data/ext/ffi_c/libffi/ltmain.sh +8 -20
- data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +1 -1
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +26 -13
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +198 -46
- data/ext/ffi_c/libffi/src/closures.c +3 -3
- data/ext/ffi_c/libffi/src/debug.c +2 -2
- data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
- data/ext/ffi_c/libffi/src/loongarch64/ffi.c +3 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +12 -4
- data/ext/ffi_c/libffi/src/mips/n32.S +65 -14
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +36 -24
- data/ext/ffi_c/libffi/src/sparc/ffi64.c +7 -1
- data/ext/ffi_c/libffi/src/tramp.c +1 -1
- data/ext/ffi_c/libffi/src/types.c +4 -6
- data/ext/ffi_c/libffi/src/wasm32/ffi.c +13 -0
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +1 -1
- data/ext/ffi_c/libffi/testsuite/Makefile.am +79 -127
- data/ext/ffi_c/libffi/testsuite/Makefile.in +79 -127
- data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +6 -0
- 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.darwin.mk +2 -2
- 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/ffi.rb +59 -0
- 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 +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 +37 -18
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a6a87ee152caf4030d9a90bedcefece7f4717639dc96443727b1e1c492db617
|
4
|
+
data.tar.gz: 722b6e07fb23b25c2ad2c2e426040e2fb3f929e6dda3c00c26ac7fbc7c7820aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4b65f1f9f9852a7d74c0739eb940f487a85354466b998caf4e637b20046c91a4338c389992de8d42118536624db2bbab4b4de799477af3591701e823355a69c
|
7
|
+
data.tar.gz: 6877266da6f47d6d921b8535ee63737caefeb89a937489a1c4756273b87bdcfec93f13e5c9a4dd7c7c56a680d0b1822aecf0197b9b92f778778732cf9fa6556e
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,54 @@
|
|
1
|
+
1.17.1 / 2024-12-30
|
2
|
+
-------------------
|
3
|
+
|
4
|
+
Fixed:
|
5
|
+
* #1117 Restart async callback dispatcher thread after fork.
|
6
|
+
* #1133 Add ruby-3.4 native gem.
|
7
|
+
* #1134 Fix FFI::DataConverter non-generic usage in RBS files.
|
8
|
+
|
9
|
+
|
10
|
+
1.17.0 / 2024-06-02
|
11
|
+
-------------------
|
12
|
+
|
13
|
+
Fixed:
|
14
|
+
* Add FFI::AbstractMemory#read_array_of_string . It was defined but not exposed to Ruby nor tested. #1070
|
15
|
+
|
16
|
+
|
17
|
+
1.17.0.rc2 / 2024-04-22
|
18
|
+
-------------------
|
19
|
+
|
20
|
+
Fixed:
|
21
|
+
* Add missing write barriers to StructLayout#initialize causing a segfault with GC.stress. #1079
|
22
|
+
|
23
|
+
|
24
|
+
1.17.0.rc1 / 2024-04-08
|
25
|
+
-------------------
|
26
|
+
|
27
|
+
Fixed:
|
28
|
+
* Fix type definitions on `aarch64-linux`. #1067, #1066
|
29
|
+
* Use RB_TEST for `Pointer.autorelease=` . #1065
|
30
|
+
So that `false` and `nil` are treated as falsey and anything else as truthy.
|
31
|
+
* Replace Fixnum by Integer. #1064
|
32
|
+
Fixnum is no longer present in the ruby language.
|
33
|
+
* Update `FFI::NativeType` doc. #1061
|
34
|
+
* Store FFI::Type::Mapped of FFI::StrPtrConverter in global instead of custom type map
|
35
|
+
* Various documentation fixes. #1042
|
36
|
+
* Update `FFI::Pointer#==` to return `false` if a pointer is compared to a non-pointer object, which is the expected behavior. #1083
|
37
|
+
* Avoid warning about undefined wariable `@ffi_functions` #1085
|
38
|
+
* Fix a very unlikely GC bug when using a callback block. # 1089
|
39
|
+
|
40
|
+
Added:
|
41
|
+
* Provide binary gems for many platforms. #990
|
42
|
+
* Add Windows fat binary gem for Ruby-3.3
|
43
|
+
* Add RBS type definitions for many user facing parts of the FFI API. #1042
|
44
|
+
* Improve fallback search path logic. #1088
|
45
|
+
Respect LD_LIBRARY_PATH and DYLD_LIBRARY_PATH on Macos.
|
46
|
+
* Update libffi to current git master branch.
|
47
|
+
|
48
|
+
Removed:
|
49
|
+
* Remove `enum CHAR_ARRAY` which is no longer used. #1063
|
50
|
+
|
51
|
+
|
1
52
|
1.16.3 / 2023-10-04
|
2
53
|
-------------------
|
3
54
|
|
data/Gemfile
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
group :development do
|
4
|
+
gem 'bigdecimal' # necessary on ruby-3.3+
|
5
|
+
gem 'bundler', '>= 1.16', '< 3'
|
4
6
|
gem 'rake', '~> 13.0'
|
5
7
|
gem 'rake-compiler', '~> 1.1'
|
6
|
-
gem 'rake-compiler-dock', '~> 1.0'
|
8
|
+
gem 'rake-compiler-dock', '~> 1.7.0'
|
7
9
|
gem 'rspec', '~> 3.0'
|
8
|
-
gem 'bundler', '>= 1.16', '< 3'
|
9
10
|
end
|
10
11
|
|
11
12
|
group :doc do
|
12
13
|
gem 'kramdown'
|
13
14
|
gem 'yard', '~> 0.9'
|
14
15
|
end
|
16
|
+
|
17
|
+
group :type_check do
|
18
|
+
if RUBY_VERSION >= "2.6" && %w[ ruby truffleruby ].include?(RUBY_ENGINE)
|
19
|
+
gem 'rbs', '~> 3.0'
|
20
|
+
end
|
21
|
+
end
|
data/README.md
CHANGED
@@ -114,7 +114,7 @@ The following people have submitted code, bug reports, or otherwise contributed
|
|
114
114
|
* Jurij Smakov <jurij@wooyd.org>
|
115
115
|
* KISHIMOTO, Makoto <ksmakoto@dd.iij4u.or.jp>
|
116
116
|
* Kim Burgestrand <kim@burgestrand.se>
|
117
|
-
* Lars Kanis <
|
117
|
+
* Lars Kanis <lars@greiz-reinsdorf.de>
|
118
118
|
* Luc Heinrich <luc@honk-honk.com>
|
119
119
|
* Luis Lavena <luislavena@gmail.com>
|
120
120
|
* Matijs van Zuijlen <matijs@matijs.net>
|
data/Rakefile
CHANGED
@@ -13,7 +13,7 @@ BUILD_EXT_DIR = File.join(BUILD_DIR, "#{RbConfig::CONFIG['arch']}", 'ffi_c', RUB
|
|
13
13
|
|
14
14
|
gem_spec = Bundler.load_gemspec('ffi.gemspec')
|
15
15
|
|
16
|
-
RSpec::Core::RakeTask.new(:spec
|
16
|
+
RSpec::Core::RakeTask.new(:spec) do |config|
|
17
17
|
config.rspec_opts = YAML.load_file 'spec/spec.opts'
|
18
18
|
end
|
19
19
|
|
@@ -84,10 +84,22 @@ end
|
|
84
84
|
task 'gem:java' => 'java:gem'
|
85
85
|
|
86
86
|
FfiGemHelper.install_tasks
|
87
|
-
# Register
|
88
|
-
Bundler::GemHelper.instance.cross_platforms = %w[
|
89
|
-
|
90
|
-
|
87
|
+
# Register binary gems to be pushed to rubygems.org
|
88
|
+
Bundler::GemHelper.instance.cross_platforms = %w[
|
89
|
+
x86-mingw32
|
90
|
+
x64-mingw-ucrt
|
91
|
+
x64-mingw32
|
92
|
+
x86-linux-gnu
|
93
|
+
x86-linux-musl
|
94
|
+
x86_64-linux-gnu
|
95
|
+
x86_64-linux-musl
|
96
|
+
arm-linux-gnu
|
97
|
+
arm-linux-musl
|
98
|
+
aarch64-linux-gnu
|
99
|
+
aarch64-linux-musl
|
100
|
+
x86_64-darwin
|
101
|
+
arm64-darwin
|
102
|
+
]
|
91
103
|
|
92
104
|
if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
|
93
105
|
require 'rake/extensiontask'
|
@@ -124,7 +136,7 @@ namespace "gem" do
|
|
124
136
|
desc "Build the native gem for #{plat}"
|
125
137
|
task plat => ['prepare', 'build'] do
|
126
138
|
RakeCompilerDock.sh <<-EOT, platform: plat
|
127
|
-
|
139
|
+
sudo apt-get update && sudo apt-get install -y libltdl-dev &&
|
128
140
|
bundle --local &&
|
129
141
|
rake native:#{plat} pkg/#{gem_spec.full_name}-#{plat}.gem MAKE='nice make -j`nproc`' RUBY_CC_VERSION=${RUBY_CC_VERSION/:2.4.0/}
|
130
142
|
EOT
|
data/ext/ffi_c/AbstractMemory.c
CHANGED
@@ -324,7 +324,7 @@ memory_clear(VALUE self)
|
|
324
324
|
/*
|
325
325
|
* call-seq: memory.size
|
326
326
|
* Return memory size in bytes (alias: #total)
|
327
|
-
* @return [
|
327
|
+
* @return [Integer]
|
328
328
|
*/
|
329
329
|
static VALUE
|
330
330
|
memory_size(VALUE self)
|
@@ -340,7 +340,7 @@ memory_size(VALUE self)
|
|
340
340
|
* call-seq: memory.get(type, offset)
|
341
341
|
* Return data of given type contained in memory.
|
342
342
|
* @param [Symbol, Type] type_name type of data to get
|
343
|
-
* @param [
|
343
|
+
* @param [Integer] offset point in buffer to start from
|
344
344
|
* @return [Object]
|
345
345
|
* @raise {ArgumentError} if type is not supported
|
346
346
|
*/
|
@@ -373,7 +373,7 @@ undefined_type: {
|
|
373
373
|
/*
|
374
374
|
* call-seq: memory.put(type, offset, value)
|
375
375
|
* @param [Symbol, Type] type_name type of data to put
|
376
|
-
* @param [
|
376
|
+
* @param [Integer] offset point in buffer to start from
|
377
377
|
* @return [nil]
|
378
378
|
* @raise {ArgumentError} if type is not supported
|
379
379
|
*/
|
@@ -407,8 +407,8 @@ undefined_type: {
|
|
407
407
|
/*
|
408
408
|
* call-seq: memory.get_string(offset, length=nil)
|
409
409
|
* Return string contained in memory.
|
410
|
-
* @param [
|
411
|
-
* @param [
|
410
|
+
* @param [Integer] offset point in buffer to start from
|
411
|
+
* @param [Integer] length string's length in bytes. If nil, a (memory size - offset) length string is returned).
|
412
412
|
* @return [String]
|
413
413
|
* @raise {IndexError} if +length+ is too great
|
414
414
|
* @raise {NullPointerError} if memory not initialized
|
@@ -435,8 +435,8 @@ memory_get_string(int argc, VALUE* argv, VALUE self)
|
|
435
435
|
/*
|
436
436
|
* call-seq: memory.get_array_of_string(offset, count=nil)
|
437
437
|
* Return an array of strings contained in memory.
|
438
|
-
* @param [
|
439
|
-
* @param [
|
438
|
+
* @param [Integer] offset point in memory to start from
|
439
|
+
* @param [Integer] count number of strings to get. If nil, return all strings
|
440
440
|
* @return [Array<String>]
|
441
441
|
* @raise {IndexError} if +offset+ is too great
|
442
442
|
* @raise {NullPointerError} if memory not initialized
|
@@ -485,7 +485,7 @@ memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
|
|
485
485
|
* call-seq: memory.read_array_of_string(count=nil)
|
486
486
|
* Return an array of strings contained in memory. Same as:
|
487
487
|
* memory.get_array_of_string(0, count)
|
488
|
-
* @param [
|
488
|
+
* @param [Integer] count number of strings to get. If nil, return all strings
|
489
489
|
* @return [Array<String>]
|
490
490
|
*/
|
491
491
|
static VALUE
|
@@ -505,7 +505,7 @@ memory_read_array_of_string(int argc, VALUE* argv, VALUE self)
|
|
505
505
|
|
506
506
|
/*
|
507
507
|
* call-seq: memory.put_string(offset, str)
|
508
|
-
* @param [
|
508
|
+
* @param [Integer] offset
|
509
509
|
* @param [String] str
|
510
510
|
* @return [self]
|
511
511
|
* @raise {SecurityError} when writing unsafe string to memory
|
@@ -535,8 +535,8 @@ memory_put_string(VALUE self, VALUE offset, VALUE str)
|
|
535
535
|
/*
|
536
536
|
* call-seq: memory.get_bytes(offset, length)
|
537
537
|
* Return string contained in memory.
|
538
|
-
* @param [
|
539
|
-
* @param [
|
538
|
+
* @param [Integer] offset point in buffer to start from
|
539
|
+
* @param [Integer] length string's length in bytes.
|
540
540
|
* @return [String]
|
541
541
|
* @raise {IndexError} if +length+ is too great
|
542
542
|
* @raise {NullPointerError} if memory not initialized
|
@@ -559,10 +559,10 @@ memory_get_bytes(VALUE self, VALUE offset, VALUE length)
|
|
559
559
|
/*
|
560
560
|
* call-seq: memory.put_bytes(offset, str, index=0, length=nil)
|
561
561
|
* Put a string in memory.
|
562
|
-
* @param [
|
562
|
+
* @param [Integer] offset point in buffer to start from
|
563
563
|
* @param [String] str string to put to memory
|
564
|
-
* @param [
|
565
|
-
* @param [
|
564
|
+
* @param [Integer] index
|
565
|
+
* @param [Integer] length string's length in bytes. If nil, a (memory size - offset) length string is returned).
|
566
566
|
* @return [self]
|
567
567
|
* @raise {IndexError} if +length+ is too great
|
568
568
|
* @raise {NullPointerError} if memory not initialized
|
@@ -601,7 +601,7 @@ memory_put_bytes(int argc, VALUE* argv, VALUE self)
|
|
601
601
|
|
602
602
|
/*
|
603
603
|
* call-seq: memory.read_bytes(length)
|
604
|
-
* @param [
|
604
|
+
* @param [Integer] length of string to return
|
605
605
|
* @return [String]
|
606
606
|
* equivalent to :
|
607
607
|
* memory.get_bytes(0, length)
|
@@ -615,8 +615,8 @@ memory_read_bytes(VALUE self, VALUE length)
|
|
615
615
|
/*
|
616
616
|
* call-seq: memory.write_bytes(str, index=0, length=nil)
|
617
617
|
* @param [String] str string to put to memory
|
618
|
-
* @param [
|
619
|
-
* @param [
|
618
|
+
* @param [Integer] index
|
619
|
+
* @param [Integer] length string's length in bytes. If nil, a (memory size - offset) length string is returned).
|
620
620
|
* @return [self]
|
621
621
|
* equivalent to :
|
622
622
|
* memory.put_bytes(0, str, index, length)
|
@@ -637,7 +637,7 @@ memory_write_bytes(int argc, VALUE* argv, VALUE self)
|
|
637
637
|
|
638
638
|
/*
|
639
639
|
* call-seq: memory.type_size
|
640
|
-
* @return [
|
640
|
+
* @return [Integer] type size in bytes
|
641
641
|
* Get the memory's type size.
|
642
642
|
*/
|
643
643
|
static VALUE
|
@@ -653,7 +653,7 @@ memory_type_size(VALUE self)
|
|
653
653
|
/*
|
654
654
|
* Document-method: []
|
655
655
|
* call-seq: memory[idx]
|
656
|
-
* @param [
|
656
|
+
* @param [Integer] idx index to access in memory
|
657
657
|
* @return
|
658
658
|
* Memory read accessor.
|
659
659
|
*/
|
@@ -861,8 +861,8 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
861
861
|
|
862
862
|
/*
|
863
863
|
* Document-method: put_float32
|
864
|
-
* call-seq: memory.
|
865
|
-
* @param [
|
864
|
+
* call-seq: memory.put_float32(offset, value)
|
865
|
+
* @param [Integer] offset
|
866
866
|
* @param [Numeric] value
|
867
867
|
* @return [self]
|
868
868
|
* Put +value+ as a 32-bit float in memory at offset +offset+ (alias: #put_float).
|
@@ -871,7 +871,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
871
871
|
/*
|
872
872
|
* Document-method: get_float32
|
873
873
|
* call-seq: memory.get_float32(offset)
|
874
|
-
* @param [
|
874
|
+
* @param [Integer] offset
|
875
875
|
* @return [Float]
|
876
876
|
* Get a 32-bit float from memory at offset +offset+ (alias: #get_float).
|
877
877
|
*/
|
@@ -902,7 +902,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
902
902
|
/*
|
903
903
|
* Document-method: put_array_of_float32
|
904
904
|
* call-seq: memory.put_array_of_float32(offset, ary)
|
905
|
-
* @param [
|
905
|
+
* @param [Integer] offset
|
906
906
|
* @param [Array<Numeric>] ary
|
907
907
|
* @return [self]
|
908
908
|
* Put values from +ary+ as 32-bit floats in memory from offset +offset+ (alias: #put_array_of_float).
|
@@ -911,8 +911,8 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
911
911
|
/*
|
912
912
|
* Document-method: get_array_of_float32
|
913
913
|
* call-seq: memory.get_array_of_float32(offset, length)
|
914
|
-
* @param [
|
915
|
-
* @param [
|
914
|
+
* @param [Integer] offset
|
915
|
+
* @param [Integer] length number of Float to get
|
916
916
|
* @return [Array<Float>]
|
917
917
|
* Get 32-bit floats in memory from offset +offset+ (alias: #get_array_of_float).
|
918
918
|
*/
|
@@ -931,7 +931,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
931
931
|
/*
|
932
932
|
* Document-method: read_array_of_float
|
933
933
|
* call-seq: memory.read_array_of_float(length)
|
934
|
-
* @param [
|
934
|
+
* @param [Integer] length number of Float to read
|
935
935
|
* @return [Array<Float>]
|
936
936
|
* Read 32-bit floats from memory.
|
937
937
|
*
|
@@ -944,7 +944,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
944
944
|
/*
|
945
945
|
* Document-method: put_float64
|
946
946
|
* call-seq: memory.put_float64(offset, value)
|
947
|
-
* @param [
|
947
|
+
* @param [Integer] offset
|
948
948
|
* @param [Numeric] value
|
949
949
|
* @return [self]
|
950
950
|
* Put +value+ as a 64-bit float (double) in memory at offset +offset+ (alias: #put_double).
|
@@ -953,7 +953,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
953
953
|
/*
|
954
954
|
* Document-method: get_float64
|
955
955
|
* call-seq: memory.get_float64(offset)
|
956
|
-
* @param [
|
956
|
+
* @param [Integer] offset
|
957
957
|
* @return [Float]
|
958
958
|
* Get a 64-bit float (double) from memory at offset +offset+ (alias: #get_double).
|
959
959
|
*/
|
@@ -984,7 +984,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
984
984
|
/*
|
985
985
|
* Document-method: put_array_of_float64
|
986
986
|
* call-seq: memory.put_array_of_float64(offset, ary)
|
987
|
-
* @param [
|
987
|
+
* @param [Integer] offset
|
988
988
|
* @param [Array<Numeric>] ary
|
989
989
|
* @return [self]
|
990
990
|
* Put values from +ary+ as 64-bit floats (doubles) in memory from offset +offset+ (alias: #put_array_of_double).
|
@@ -993,8 +993,8 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
993
993
|
/*
|
994
994
|
* Document-method: get_array_of_float64
|
995
995
|
* call-seq: memory.get_array_of_float64(offset, length)
|
996
|
-
* @param [
|
997
|
-
* @param [
|
996
|
+
* @param [Integer] offset
|
997
|
+
* @param [Integer] length number of Float to get
|
998
998
|
* @return [Array<Float>]
|
999
999
|
* Get 64-bit floats (doubles) in memory from offset +offset+ (alias: #get_array_of_double).
|
1000
1000
|
*/
|
@@ -1013,7 +1013,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
1013
1013
|
/*
|
1014
1014
|
* Document-method: read_array_of_double
|
1015
1015
|
* call-seq: memory.read_array_of_double(length)
|
1016
|
-
* @param [
|
1016
|
+
* @param [Integer] length number of Float to read
|
1017
1017
|
* @return [Array<Float>]
|
1018
1018
|
* Read 64-bit floats (doubles) from memory.
|
1019
1019
|
*
|
@@ -1026,7 +1026,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
1026
1026
|
/*
|
1027
1027
|
* Document-method: put_pointer
|
1028
1028
|
* call-seq: memory.put_pointer(offset, value)
|
1029
|
-
* @param [
|
1029
|
+
* @param [Integer] offset
|
1030
1030
|
* @param [nil,Pointer, Integer, #to_ptr] value
|
1031
1031
|
* @return [self]
|
1032
1032
|
* Put +value+ in memory from +offset+..
|
@@ -1035,7 +1035,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
1035
1035
|
/*
|
1036
1036
|
* Document-method: get_pointer
|
1037
1037
|
* call-seq: memory.get_pointer(offset)
|
1038
|
-
* @param [
|
1038
|
+
* @param [Integer] offset
|
1039
1039
|
* @return [Pointer]
|
1040
1040
|
* Get a {Pointer} to the memory from +offset+.
|
1041
1041
|
*/
|
@@ -1064,7 +1064,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
1064
1064
|
/*
|
1065
1065
|
* Document-method: put_array_of_pointer
|
1066
1066
|
* call-seq: memory.put_array_of_pointer(offset, ary)
|
1067
|
-
* @param [
|
1067
|
+
* @param [Integer] offset
|
1068
1068
|
* @param [Array<#to_ptr>] ary
|
1069
1069
|
* @return [self]
|
1070
1070
|
* Put an array of {Pointer} into memory from +offset+.
|
@@ -1073,8 +1073,8 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
1073
1073
|
/*
|
1074
1074
|
* Document-method: get_array_of_pointer
|
1075
1075
|
* call-seq: memory.get_array_of_pointer(offset, length)
|
1076
|
-
* @param [
|
1077
|
-
* @param [
|
1076
|
+
* @param [Integer] offset
|
1077
|
+
* @param [Integer] length
|
1078
1078
|
* @return [Array<Pointer>]
|
1079
1079
|
* Get an array of {Pointer} of length +length+ from +offset+.
|
1080
1080
|
*/
|
@@ -1093,7 +1093,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
1093
1093
|
/*
|
1094
1094
|
* Document-method: read_array_of_pointer
|
1095
1095
|
* call-seq: memory.read_array_of_pointer(length)
|
1096
|
-
* @param [
|
1096
|
+
* @param [Integer] length
|
1097
1097
|
* @return [Array<Pointer>]
|
1098
1098
|
* Read an array of {Pointer} of length +length+.
|
1099
1099
|
*
|
@@ -1109,6 +1109,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
1109
1109
|
rb_define_method(classMemory, "read_bytes", memory_read_bytes, 1);
|
1110
1110
|
rb_define_method(classMemory, "write_bytes", memory_write_bytes, -1);
|
1111
1111
|
rb_define_method(classMemory, "get_array_of_string", memory_get_array_of_string, -1);
|
1112
|
+
rb_define_method(classMemory, "read_array_of_string", memory_read_array_of_string, -1);
|
1112
1113
|
|
1113
1114
|
rb_define_method(classMemory, "get", memory_get, 2);
|
1114
1115
|
rb_define_method(classMemory, "put", memory_put, 3);
|
data/ext/ffi_c/ArrayType.c
CHANGED
@@ -110,7 +110,7 @@ array_type_memsize(const void *data)
|
|
110
110
|
/*
|
111
111
|
* call-seq: initialize(component_type, length)
|
112
112
|
* @param [Type] component_type
|
113
|
-
* @param [
|
113
|
+
* @param [Integer] length
|
114
114
|
* @return [self]
|
115
115
|
* A new instance of ArrayType.
|
116
116
|
*/
|
@@ -140,7 +140,7 @@ array_type_initialize(VALUE self, VALUE rbComponentType, VALUE rbLength)
|
|
140
140
|
|
141
141
|
/*
|
142
142
|
* call-seq: length
|
143
|
-
* @return [
|
143
|
+
* @return [Integer]
|
144
144
|
* Get array's length
|
145
145
|
*/
|
146
146
|
static VALUE
|
data/ext/ffi_c/Buffer.c
CHANGED
@@ -114,7 +114,7 @@ buffer_release(void *data)
|
|
114
114
|
/*
|
115
115
|
* call-seq: initialize(size, count=1, clear=false)
|
116
116
|
* @param [Integer, Symbol, #size] Type or size in bytes of a buffer cell
|
117
|
-
* @param [
|
117
|
+
* @param [Integer] count number of cell in the Buffer
|
118
118
|
* @param [Boolean] clear if true, set the buffer to all-zero
|
119
119
|
* @return [self]
|
120
120
|
* @raise {NoMemoryError} if failed to allocate memory for Buffer
|
@@ -219,7 +219,7 @@ slice(VALUE self, long offset, long len)
|
|
219
219
|
|
220
220
|
/*
|
221
221
|
* call-seq: + offset
|
222
|
-
* @param [
|
222
|
+
* @param [Integer] offset
|
223
223
|
* @return [Buffer] a new instance of Buffer pointing from offset until end of previous buffer.
|
224
224
|
* Add a Buffer with an offset
|
225
225
|
*/
|
@@ -236,8 +236,8 @@ buffer_plus(VALUE self, VALUE rbOffset)
|
|
236
236
|
|
237
237
|
/*
|
238
238
|
* call-seq: slice(offset, length)
|
239
|
-
* @param [
|
240
|
-
* @param [
|
239
|
+
* @param [Integer] offset
|
240
|
+
* @param [Integer] length
|
241
241
|
* @return [Buffer] a new instance of Buffer
|
242
242
|
* Slice an existing Buffer.
|
243
243
|
*/
|
data/ext/ffi_c/Call.c
CHANGED
@@ -86,10 +86,11 @@ static inline void* getPointer(VALUE value, int type);
|
|
86
86
|
|
87
87
|
static ID id_to_ptr, id_map_symbol, id_to_native;
|
88
88
|
|
89
|
-
|
89
|
+
VALUE
|
90
90
|
rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
|
91
91
|
FFIStorage* paramStorage, void** ffiValues,
|
92
|
-
VALUE* callbackParameters, int callbackCount,
|
92
|
+
VALUE* callbackParameters, int callbackCount,
|
93
|
+
VALUE enums)
|
93
94
|
{
|
94
95
|
VALUE callbackProc = Qnil;
|
95
96
|
FFIStorage* param = ¶mStorage[0];
|
@@ -327,6 +328,7 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
|
|
327
328
|
rb_raise(rb_eArgError, "Invalid parameter type: %d", paramType->nativeType);
|
328
329
|
}
|
329
330
|
}
|
331
|
+
return callbackProc;
|
330
332
|
}
|
331
333
|
|
332
334
|
static void *
|
@@ -362,6 +364,7 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
362
364
|
FFIStorage* params;
|
363
365
|
VALUE rbReturnValue;
|
364
366
|
rbffi_frame_t frame = { 0 };
|
367
|
+
VALUE callbackProc;
|
365
368
|
|
366
369
|
retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
|
367
370
|
|
@@ -379,9 +382,10 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
379
382
|
bc->params = params;
|
380
383
|
bc->frame = &frame;
|
381
384
|
|
382
|
-
rbffi_SetupCallParams(argc, argv,
|
385
|
+
callbackProc = rbffi_SetupCallParams(argc, argv,
|
383
386
|
fnInfo->parameterCount, fnInfo->parameterTypes, params, ffiValues,
|
384
|
-
fnInfo->callbackParameters, fnInfo->callbackCount,
|
387
|
+
fnInfo->callbackParameters, fnInfo->callbackCount,
|
388
|
+
fnInfo->rbEnums);
|
385
389
|
|
386
390
|
rbffi_frame_push(&frame);
|
387
391
|
rb_rescue2(rbffi_do_blocking_call, (VALUE) bc, rbffi_save_frame_exception, (VALUE) &frame, rb_eException, (VALUE) 0);
|
@@ -392,14 +396,16 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
392
396
|
ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
|
393
397
|
params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
|
394
398
|
|
395
|
-
rbffi_SetupCallParams(argc, argv,
|
399
|
+
callbackProc = rbffi_SetupCallParams(argc, argv,
|
396
400
|
fnInfo->parameterCount, fnInfo->parameterTypes, params, ffiValues,
|
397
|
-
fnInfo->callbackParameters, fnInfo->callbackCount,
|
401
|
+
fnInfo->callbackParameters, fnInfo->callbackCount,
|
402
|
+
fnInfo->rbEnums);
|
398
403
|
|
399
404
|
rbffi_frame_push(&frame);
|
400
405
|
ffi_call(&fnInfo->ffi_cif, FFI_FN(function), retval, ffiValues);
|
401
406
|
rbffi_frame_pop(&frame);
|
402
407
|
}
|
408
|
+
RB_GC_GUARD(callbackProc);
|
403
409
|
|
404
410
|
if (unlikely(!fnInfo->ignoreErrno)) {
|
405
411
|
rbffi_save_errno();
|
data/ext/ffi_c/Call.h
CHANGED
@@ -73,9 +73,10 @@ typedef union {
|
|
73
73
|
|
74
74
|
extern void rbffi_Call_Init(VALUE moduleFFI);
|
75
75
|
|
76
|
-
extern
|
76
|
+
extern VALUE rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
|
77
77
|
FFIStorage* paramStorage, void** ffiValues,
|
78
|
-
VALUE* callbackParameters, int callbackCount,
|
78
|
+
VALUE* callbackParameters, int callbackCount,
|
79
|
+
VALUE enums);
|
79
80
|
|
80
81
|
struct FunctionType_;
|
81
82
|
extern VALUE rbffi_CallFunction(int argc, VALUE* argv, void* function, struct FunctionType_* fnInfo);
|
data/ext/ffi_c/DynamicLibrary.c
CHANGED
@@ -128,7 +128,7 @@ library_open(VALUE klass, VALUE libname, VALUE libflags)
|
|
128
128
|
/*
|
129
129
|
* call-seq: initialize(libname, libflags)
|
130
130
|
* @param [String] libname name of library to open
|
131
|
-
* @param [
|
131
|
+
* @param [Integer] libflags flags for library to open
|
132
132
|
* @return [FFI::DynamicLibrary]
|
133
133
|
* @raise {LoadError} if +libname+ cannot be opened
|
134
134
|
* A new DynamicLibrary instance.
|
@@ -232,7 +232,7 @@ dl_error(char* buf, int size)
|
|
232
232
|
|
233
233
|
// Get the associated message
|
234
234
|
LPSTR message = NULL;
|
235
|
-
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
235
|
+
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
236
236
|
NULL, error, 0, (LPSTR)&message, 0, NULL);
|
237
237
|
|
238
238
|
// Update the passed in buffer
|
data/ext/ffi_c/Function.c
CHANGED
@@ -215,6 +215,52 @@ async_cb_dispatcher_set(struct async_cb_dispatcher *ctx)
|
|
215
215
|
async_cb_dispatcher = ctx;
|
216
216
|
}
|
217
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);
|
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
|
+
}
|
253
|
+
|
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
|
+
}
|
218
264
|
#endif
|
219
265
|
|
220
266
|
static VALUE
|
@@ -391,15 +437,6 @@ rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
|
|
391
437
|
return callback;
|
392
438
|
}
|
393
439
|
|
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
440
|
static VALUE
|
404
441
|
function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
|
405
442
|
{
|
@@ -426,31 +463,7 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
|
|
426
463
|
}
|
427
464
|
|
428
465
|
#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
|
-
}
|
466
|
+
fn->dispatcher = async_cb_dispatcher_ensure_created();
|
454
467
|
#endif
|
455
468
|
|
456
469
|
fn->closure = rbffi_Closure_Alloc(fn->info->closurePool);
|
@@ -1060,4 +1073,9 @@ rbffi_Function_Init(VALUE moduleFFI)
|
|
1060
1073
|
#if defined(DEFER_ASYNC_CALLBACK) && defined(HAVE_RB_EXT_RACTOR_SAFE)
|
1061
1074
|
async_cb_dispatcher_key = rb_ractor_local_storage_ptr_newkey(&async_cb_dispatcher_key_type);
|
1062
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
|
1063
1081
|
}
|