ffi 1.10.0 → 1.11.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
- data/.gitignore +3 -0
- data/.gitmodules +2 -1
- data/.travis.yml +17 -18
- data/CHANGELOG.md +33 -0
- data/Gemfile +1 -1
- data/README.md +20 -17
- data/Rakefile +10 -83
- data/appveyor.yml +6 -1
- data/ext/ffi_c/Call.c +16 -33
- data/ext/ffi_c/Call.h +2 -5
- data/ext/ffi_c/Function.c +24 -108
- data/ext/ffi_c/Platform.c +0 -47
- data/ext/ffi_c/Thread.c +6 -222
- data/ext/ffi_c/Thread.h +2 -13
- data/ext/ffi_c/Type.c +0 -18
- data/ext/ffi_c/Type.h +0 -1
- data/ext/ffi_c/Variadic.c +9 -15
- data/ext/ffi_c/extconf.rb +34 -20
- data/ext/ffi_c/ffi.c +3 -8
- data/ext/ffi_c/libffi/configure.ac +5 -1
- data/ext/ffi_c/libffi/include/ffi_common.h +1 -1
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +2 -2
- data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/metag/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/moxie/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/riscv/ffi.c +42 -6
- data/ext/ffi_c/libffi/src/riscv/ffitarget.h +1 -0
- data/ext/ffi_c/libffi/src/riscv/sysv.S +86 -7
- data/ext/ffi_c/libffi/src/x86/ffi.c +2 -1
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +1 -1
- data/ext/ffi_c/libffi/src/x86/sysv.S +88 -2
- data/ext/ffi_c/libffi/src/x86/unix64.S +41 -0
- data/ext/ffi_c/rbffi.h +0 -2
- data/ffi.gemspec +11 -4
- data/lib/ffi/data_converter.rb +67 -0
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/platform.rb +2 -0
- data/lib/ffi/pointer.rb +1 -1
- data/lib/ffi/struct.rb +3 -63
- data/lib/ffi/struct_by_reference.rb +72 -0
- data/lib/ffi/struct_layout.rb +96 -0
- data/lib/ffi/tools/const_generator.rb +5 -4
- data/lib/ffi/tools/generator.rb +47 -2
- data/lib/ffi/tools/generator_task.rb +13 -17
- data/lib/ffi/tools/struct_generator.rb +4 -4
- data/lib/ffi/types.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- metadata +18 -13
- data/ext/ffi_c/DataConverter.c +0 -91
- data/ext/ffi_c/StructByReference.c +0 -190
- data/ext/ffi_c/StructByReference.h +0 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 041f37e7f1d2ed3857caabe7c68a68d3d8a9b403c5d03e8df59d0277a48f17e2
|
4
|
+
data.tar.gz: 4c9bcdce1d0ba85318109bb074a0e19c87f5c004440a491d5f532ac2ec20b82c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ae610d83039e9edc3ce4fe3708319cc4c1fc0d8d6dbddc96b4f4b51eec5875fb9052adfce7620664707a73696f3d17c4c1c956037ac252e1924a36fde57ad4c
|
7
|
+
data.tar.gz: 3a745c80a61c816826ded2c3e29eb13746e1686edcd14f98d06d012d31352b7eaf30e15d9517e662a80beb65f48e1af6e0bceddbf23346d3268ccf6d6ea820ea
|
data/.gitignore
CHANGED
data/.gitmodules
CHANGED
data/.travis.yml
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
dist: trusty
|
2
|
-
sudo: false
|
3
2
|
group: beta
|
4
3
|
language: ruby
|
5
|
-
|
6
|
-
- gem install bundler
|
4
|
+
|
7
5
|
script:
|
8
6
|
- bundle exec rake compile || bundle exec rake compile
|
9
7
|
- bundle exec rake test
|
8
|
+
- ITER=10 bundle exec rake bench:all
|
10
9
|
os:
|
11
10
|
- linux
|
12
11
|
- osx
|
@@ -16,28 +15,28 @@ rvm:
|
|
16
15
|
- 2.5.3
|
17
16
|
- 2.6.0
|
18
17
|
- ruby-head
|
19
|
-
|
18
|
+
|
20
19
|
env:
|
21
20
|
- CC=gcc
|
22
21
|
- CC=clang
|
23
22
|
matrix:
|
24
23
|
allow_failures:
|
25
|
-
- rvm: system
|
26
24
|
- os: osx
|
27
25
|
rvm: ruby-head
|
28
|
-
exclude: # ruby 2.4.2 needs build with xcode9 or later on osx
|
29
|
-
- os: osx
|
30
|
-
rvm: 2.4.2
|
31
26
|
include:
|
32
|
-
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
27
|
+
- name: powerpc
|
28
|
+
language: generic
|
29
|
+
before_install: |
|
30
|
+
docker run --rm --privileged multiarch/qemu-user-static:register --reset &&
|
31
|
+
docker build --rm -t ffi-powerpc -f spec/env/Dockerfile.powerpc .
|
32
|
+
script: |
|
33
|
+
docker run --rm -t -v `pwd`:/ffi ffi-powerpc
|
34
|
+
- name: armhf
|
35
|
+
language: generic
|
36
|
+
before_install: |
|
37
|
+
docker run --rm --privileged multiarch/qemu-user-static:register --reset &&
|
38
|
+
docker build --rm -t ffi-armhf -f spec/env/Dockerfile.armhf .
|
39
|
+
script: |
|
40
|
+
docker run --rm -t -v `pwd`:/ffi ffi-armhf
|
42
41
|
after_failure:
|
43
42
|
- "find build -name mkmf.log | xargs cat"
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,36 @@
|
|
1
|
+
1.11.1 / 2019-05-20
|
2
|
+
-------------------
|
3
|
+
|
4
|
+
Changed:
|
5
|
+
* Raise required ruby version to >=2.0. #699, #700
|
6
|
+
* Fix a possible linker error on ruby < 2.3 on Linux.
|
7
|
+
|
8
|
+
|
9
|
+
1.11.0 / 2019-05-17
|
10
|
+
-------------------
|
11
|
+
|
12
|
+
Added:
|
13
|
+
* Add ability to disable or force use of system libffi. #669
|
14
|
+
Use like `gem inst ffi -- --enable-system-libffi` .
|
15
|
+
* Add ability to call FFI callbacks from outside of FFI call frame. #584
|
16
|
+
* Add proper documentation to FFI::Generator and ::Task
|
17
|
+
* Add gemspec metadata. #696, #698
|
18
|
+
|
19
|
+
Changed:
|
20
|
+
* Fix stdcall on Win32. #649, #669
|
21
|
+
* Fix load paths for FFI::Generator::Task
|
22
|
+
* Fix FFI::Pointer#read_string(0) to return a binary String. #692
|
23
|
+
* Fix benchmark suite so that it runs on ruby-2.x
|
24
|
+
* Move FFI::Platform::CPU from C to Ruby. #663
|
25
|
+
* Move FFI::StructByReference to Ruby. #681
|
26
|
+
* Move FFI::DataConverter to Ruby (#661)
|
27
|
+
* Various cleanups and improvements of specs and benchmarks
|
28
|
+
|
29
|
+
Removed:
|
30
|
+
* Remove ruby-1.8 and 1.9 compatibility code. #683
|
31
|
+
* Remove unused spec files. #684
|
32
|
+
|
33
|
+
|
1
34
|
1.10.0 / 2019-01-06
|
2
35
|
-------------------
|
3
36
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
#
|
1
|
+
# Ruby-FFI https://github.com/ffi/ffi/wiki [](https://travis-ci.org/ffi/ffi) [](https://ci.appveyor.com/project/larskanis/ffi-aofqa/branch/master)
|
2
2
|
|
3
3
|
## Description
|
4
4
|
|
5
|
-
Ruby-FFI is a
|
5
|
+
Ruby-FFI is a gem for programmatically loading dynamically-linked native
|
6
6
|
libraries, binding functions within them, and calling those functions
|
7
7
|
from Ruby code. Moreover, a Ruby-FFI extension works without changes
|
8
|
-
on
|
9
|
-
using Ruby-FFI](https://
|
8
|
+
on CRuby (MRI), JRuby, Rubinius and TruffleRuby. [Discover why you should write your next extension
|
9
|
+
using Ruby-FFI](https://github.com/ffi/ffi/wiki/why-use-ffi).
|
10
10
|
|
11
|
-
## Features
|
11
|
+
## Features
|
12
12
|
|
13
13
|
* Intuitive DSL
|
14
14
|
* Supports all C native types
|
15
15
|
* C structs (also nested), enums and global variables
|
16
|
-
* Callbacks from C to
|
16
|
+
* Callbacks from C to Ruby
|
17
17
|
* Automatic garbage collection of native memory
|
18
18
|
|
19
19
|
## Synopsis
|
@@ -30,20 +30,23 @@ end
|
|
30
30
|
MyLib.puts 'Hello, World using libc!'
|
31
31
|
```
|
32
32
|
|
33
|
-
For less minimalistic and more
|
33
|
+
For less minimalistic and more examples you may look at:
|
34
34
|
|
35
|
-
* the samples
|
36
|
-
* the examples on the [wiki](https://
|
37
|
-
* the projects using FFI listed on
|
35
|
+
* the `samples/` folder
|
36
|
+
* the examples on the [wiki](https://github.com/ffi/ffi/wiki)
|
37
|
+
* the projects using FFI listed on the wiki: https://github.com/ffi/ffi/wiki/projects-using-ffi
|
38
38
|
|
39
39
|
## Requirements
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
*
|
44
|
-
* libffi development library - this is commonly in the libffi-dev or libffi-devel
|
41
|
+
When installing the gem on CRuby (MRI) or Rubinius, you will need:
|
42
|
+
* A C compiler (e.g., Xcode on macOS, `gcc` or `clang` on everything else)
|
43
|
+
* The `libffi` library and development headers - this is commonly in the `libffi-dev` or `libffi-devel` packages
|
45
44
|
|
46
|
-
On Linux systems running with [PaX](https://en.wikipedia.org/wiki/PaX) (Gentoo, Alpine, etc.) FFI may trigger `mprotect` errors. You may need to disable [mprotect](https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Restrict_mprotect.28.29) for ruby (`paxctl -m [/path/to/ruby]`) for the time being until a solution is found.
|
45
|
+
On Linux systems running with [PaX](https://en.wikipedia.org/wiki/PaX) (Gentoo, Alpine, etc.), FFI may trigger `mprotect` errors. You may need to disable [mprotect](https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Restrict_mprotect.28.29) for ruby (`paxctl -m [/path/to/ruby]`) for the time being until a solution is found.
|
46
|
+
|
47
|
+
On FreeBSD systems pkgconf must be installed for the gem to be able to compile using clang. Install either via packages `pkg install pkgconf` or from ports via `devel/pkgconf`.
|
48
|
+
|
49
|
+
On JRuby and TruffleRuby, there are no requirements to install the FFI gem, and `require 'ffi'` works even without installing the gem (i.e., the gem is preinstalled on these implementations).
|
47
50
|
|
48
51
|
## Installation
|
49
52
|
|
@@ -61,8 +64,7 @@ or from the git repository on github:
|
|
61
64
|
## License
|
62
65
|
|
63
66
|
The ffi library is covered by the BSD license, also see the LICENSE file.
|
64
|
-
The specs are
|
65
|
-
as Rubyspec, see the LICENSE.SPECS file.
|
67
|
+
The specs are covered by the same license as [ruby/spec](https://github.com/ruby/spec), the MIT license.
|
66
68
|
|
67
69
|
## Credits
|
68
70
|
|
@@ -74,6 +76,7 @@ The following people have submitted code, bug reports, or otherwise contributed
|
|
74
76
|
* Andreas Niederl <rico32@gmx.net>
|
75
77
|
* Andrew Cholakian <andrew@andrewvc.com>
|
76
78
|
* Antonio Terceiro <terceiro@softwarelivre.org>
|
79
|
+
* Benoit Daloze <eregontp@gmail.com>
|
77
80
|
* Brian Candler <B.Candler@pobox.com>
|
78
81
|
* Brian D. Burns <burns180@gmail.com>
|
79
82
|
* Bryan Kearney <bkearney@redhat.com>
|
data/Rakefile
CHANGED
@@ -3,82 +3,16 @@ require 'rbconfig'
|
|
3
3
|
require 'rake/clean'
|
4
4
|
require File.expand_path("./lib/ffi/version")
|
5
5
|
|
6
|
-
USE_RAKE_COMPILER = (RUBY_PLATFORM =~ /java/) ? false : true
|
7
|
-
if USE_RAKE_COMPILER
|
8
|
-
require 'rake/extensiontask'
|
9
|
-
end
|
10
|
-
|
11
6
|
require 'date'
|
12
7
|
require 'fileutils'
|
13
8
|
require 'rbconfig'
|
14
9
|
require 'rspec/core/rake_task'
|
15
10
|
require 'rubygems/package_task'
|
16
11
|
|
17
|
-
|
18
|
-
|
19
|
-
"dylib"
|
20
|
-
when /mswin|mingw/
|
21
|
-
"dll"
|
22
|
-
else
|
23
|
-
RbConfig::CONFIG['DLEXT']
|
24
|
-
end
|
25
|
-
|
26
|
-
CPU = case RbConfig::CONFIG['host_cpu'].downcase
|
27
|
-
when /i[3456]86/
|
28
|
-
# Darwin always reports i686, even when running in 64bit mode
|
29
|
-
if RbConfig::CONFIG['host_os'] =~ /darwin/ && 0xfee1deadbeef.is_a?(Fixnum)
|
30
|
-
"x86_64"
|
31
|
-
else
|
32
|
-
"i386"
|
33
|
-
end
|
34
|
-
|
35
|
-
when /amd64|x86_64/
|
36
|
-
"x86_64"
|
37
|
-
|
38
|
-
when /ppc64|powerpc64/
|
39
|
-
"powerpc64"
|
40
|
-
|
41
|
-
when /ppc|powerpc/
|
42
|
-
"powerpc"
|
43
|
-
|
44
|
-
when /^arm/
|
45
|
-
"arm"
|
46
|
-
|
47
|
-
else
|
48
|
-
RbConfig::CONFIG['host_cpu']
|
49
|
-
end
|
50
|
-
|
51
|
-
OS = case RbConfig::CONFIG['host_os'].downcase
|
52
|
-
when /linux/
|
53
|
-
"linux"
|
54
|
-
when /darwin/
|
55
|
-
"darwin"
|
56
|
-
when /freebsd/
|
57
|
-
"freebsd"
|
58
|
-
when /openbsd/
|
59
|
-
"openbsd"
|
60
|
-
when /sunos|solaris/
|
61
|
-
"solaris"
|
62
|
-
when /mswin|mingw/
|
63
|
-
"win32"
|
64
|
-
else
|
65
|
-
RbConfig::CONFIG['host_os'].downcase
|
66
|
-
end
|
67
|
-
|
68
|
-
def which(name)
|
69
|
-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
70
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
71
|
-
exts.each do |ext|
|
72
|
-
app = File.join(path, name+ext)
|
73
|
-
return app if File.executable? app
|
74
|
-
end
|
75
|
-
end
|
76
|
-
nil
|
12
|
+
def java?
|
13
|
+
/java/ === RUBY_PLATFORM
|
77
14
|
end
|
78
15
|
|
79
|
-
GMAKE = which('gmake').nil? ? 'make' : 'gmake'
|
80
|
-
|
81
|
-
LIBTEST = "build/libtest.#{LIBEXT}"
|
82
16
|
BUILD_DIR = "build"
|
83
17
|
BUILD_EXT_DIR = File.join(BUILD_DIR, "#{RbConfig::CONFIG['arch']}", 'ffi_c', RUBY_VERSION)
|
84
18
|
|
@@ -86,7 +20,7 @@ def gem_spec
|
|
86
20
|
@gem_spec ||= Gem::Specification.load('ffi.gemspec')
|
87
21
|
end
|
88
22
|
|
89
|
-
TEST_DEPS = [
|
23
|
+
TEST_DEPS = []
|
90
24
|
if RUBY_PLATFORM == "java"
|
91
25
|
RSpec::Core::RakeTask.new(:spec) do |config|
|
92
26
|
config.rspec_opts = YAML.load_file 'spec/spec.opts'
|
@@ -110,30 +44,22 @@ CLEAN.include 'build'
|
|
110
44
|
CLEAN.include 'conftest.dSYM'
|
111
45
|
CLEAN.include 'spec/ffi/fixtures/libtest.{dylib,so,dll}'
|
112
46
|
CLEAN.include 'spec/ffi/fixtures/*.o'
|
47
|
+
CLEAN.include 'spec/ffi/embed-test/ext/*.{o,def}'
|
48
|
+
CLEAN.include 'spec/ffi/embed-test/ext/Makefile'
|
113
49
|
CLEAN.include "pkg/ffi-*-{mingw32,java}"
|
114
50
|
CLEAN.include 'lib/1.*'
|
115
51
|
CLEAN.include 'lib/2.*'
|
116
|
-
CLEAN.include 'bin'
|
117
52
|
|
118
53
|
task :distclean => :clobber
|
119
54
|
|
120
|
-
desc "Build the native test lib"
|
121
|
-
file "build/libtest.#{LIBEXT}" => FileList['libtest/**/*.[ch]'] do
|
122
|
-
sh %{#{GMAKE} -f libtest/GNUmakefile CPU=#{CPU} OS=#{OS} }
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
desc "Build test helper lib"
|
127
|
-
task :libtest => "build/libtest.#{LIBEXT}"
|
128
|
-
|
129
55
|
desc "Test the extension"
|
130
56
|
task :test => [ :spec ]
|
131
57
|
|
132
58
|
|
133
59
|
namespace :bench do
|
134
60
|
ITER = ENV['ITER'] ? ENV['ITER'].to_i : 100000
|
135
|
-
bench_libs = "-Ilib
|
136
|
-
bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench_helper.rb" }
|
61
|
+
bench_libs = "-Ilib" unless RUBY_PLATFORM == "java"
|
62
|
+
bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench/bench_helper.rb" }
|
137
63
|
bench_files.each do |bench|
|
138
64
|
task File.basename(bench, ".rb")[6..-1] => TEST_DEPS do
|
139
65
|
sh %{#{Gem.ruby} #{bench_libs} #{bench} #{ITER}}
|
@@ -175,8 +101,8 @@ end
|
|
175
101
|
|
176
102
|
task 'gem:java' => 'java:gem'
|
177
103
|
|
178
|
-
|
179
|
-
|
104
|
+
unless java?
|
105
|
+
require 'rake/extensiontask'
|
180
106
|
Rake::ExtensionTask.new('ffi_c', gem_spec) do |ext|
|
181
107
|
ext.name = 'ffi_c' # indicate the name of the extension.
|
182
108
|
# ext.lib_dir = BUILD_DIR # put binaries into this folder.
|
@@ -212,6 +138,7 @@ file "ext/ffi_c/libffi/autogen.sh" => "ext/ffi_c/libffi" do
|
|
212
138
|
warn "Downloading libffi ..."
|
213
139
|
sh "git submodule update --init --recursive"
|
214
140
|
end
|
141
|
+
task :libffi => "ext/ffi_c/libffi/autogen.sh"
|
215
142
|
|
216
143
|
LIBFFI_GIT_FILES = `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0")
|
217
144
|
|
data/appveyor.yml
CHANGED
@@ -12,11 +12,16 @@ install:
|
|
12
12
|
- bundle install
|
13
13
|
build: off
|
14
14
|
build_script:
|
15
|
-
- bundle exec rake compile || bundle exec rake compile
|
15
|
+
- bundle exec rake libffi compile -- %EXTCONFOPTS% || bundle exec rake compile -- %EXTCONFOPTS%
|
16
16
|
test_script:
|
17
17
|
- bundle exec rake test
|
18
18
|
environment:
|
19
19
|
matrix:
|
20
20
|
- RUBYVER: "head-x64"
|
21
|
+
EXTCONFOPTS: "--disable-system-libffi"
|
21
22
|
- RUBYVER: 24
|
23
|
+
EXTCONFOPTS: "--disable-system-libffi"
|
22
24
|
- RUBYVER: 25-x64
|
25
|
+
EXTCONFOPTS: "--enable-system-libffi"
|
26
|
+
- RUBYVER: 25
|
27
|
+
EXTCONFOPTS: "--enable-system-libffi"
|
data/ext/ffi_c/Call.c
CHANGED
@@ -43,10 +43,8 @@
|
|
43
43
|
#endif
|
44
44
|
#include <errno.h>
|
45
45
|
#include <ruby.h>
|
46
|
-
#if defined(HAVE_RUBY_THREAD_H)
|
47
46
|
#include <ruby/thread.h>
|
48
|
-
#
|
49
|
-
#if defined(HAVE_NATIVETHREAD) && (defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)) && !defined(_WIN32)
|
47
|
+
#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32)
|
50
48
|
# include <signal.h>
|
51
49
|
# include <pthread.h>
|
52
50
|
#endif
|
@@ -116,7 +114,7 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
|
|
116
114
|
Type* paramType = paramTypes[i];
|
117
115
|
int type;
|
118
116
|
|
119
|
-
|
117
|
+
|
120
118
|
if (unlikely(paramType->nativeType == NATIVE_MAPPED)) {
|
121
119
|
VALUE values[] = { argv[argidx], Qnil };
|
122
120
|
argv[argidx] = rb_funcall2(((MappedType *) paramType)->rbConverter, id_to_native, 2, values);
|
@@ -297,8 +295,8 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
|
|
297
295
|
|
298
296
|
case NATIVE_STRING:
|
299
297
|
if (type == T_NIL) {
|
300
|
-
param->ptr = NULL;
|
301
|
-
|
298
|
+
param->ptr = NULL;
|
299
|
+
|
302
300
|
} else {
|
303
301
|
if (rb_safe_level() >= 1 && OBJ_TAINTED(argv[argidx])) {
|
304
302
|
rb_raise(rb_eSecurityError, "Unsafe string parameter");
|
@@ -345,9 +343,13 @@ static void *
|
|
345
343
|
call_blocking_function(void* data)
|
346
344
|
{
|
347
345
|
rbffi_blocking_call_t* b = (rbffi_blocking_call_t *) data;
|
346
|
+
#ifndef HAVE_RUBY_THREAD_HAS_GVL_P
|
348
347
|
b->frame->has_gvl = false;
|
348
|
+
#endif
|
349
349
|
ffi_call(&b->cif, FFI_FN(b->function), b->retval, b->ffiValues);
|
350
|
+
#ifndef HAVE_RUBY_THREAD_HAS_GVL_P
|
350
351
|
b->frame->has_gvl = true;
|
352
|
+
#endif
|
351
353
|
|
352
354
|
return NULL;
|
353
355
|
}
|
@@ -355,7 +357,7 @@ call_blocking_function(void* data)
|
|
355
357
|
VALUE
|
356
358
|
rbffi_do_blocking_call(void *data)
|
357
359
|
{
|
358
|
-
|
360
|
+
rb_thread_call_without_gvl(call_blocking_function, data, (void *) -1, NULL);
|
359
361
|
|
360
362
|
return Qnil;
|
361
363
|
}
|
@@ -376,28 +378,17 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
376
378
|
FFIStorage* params;
|
377
379
|
VALUE rbReturnValue;
|
378
380
|
rbffi_frame_t frame = { 0 };
|
379
|
-
|
381
|
+
|
380
382
|
retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
|
381
|
-
|
383
|
+
|
382
384
|
if (unlikely(fnInfo->blocking)) {
|
383
385
|
rbffi_blocking_call_t* bc;
|
384
386
|
|
385
|
-
/*
|
386
|
-
* due to the way thread switching works on older ruby variants, we
|
387
|
-
* cannot allocate anything passed to the blocking function on the stack
|
388
|
-
*/
|
389
|
-
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
387
|
+
/* allocate information passed to the blocking function on the stack */
|
390
388
|
ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
|
391
389
|
params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
|
392
390
|
bc = ALLOCA_N(rbffi_blocking_call_t, 1);
|
393
391
|
bc->retval = retval;
|
394
|
-
#else
|
395
|
-
ffiValues = ALLOC_N(void *, fnInfo->parameterCount);
|
396
|
-
params = ALLOC_N(FFIStorage, fnInfo->parameterCount);
|
397
|
-
bc = ALLOC_N(rbffi_blocking_call_t, 1);
|
398
|
-
bc->retval = xmalloc(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
|
399
|
-
bc->stkretval = retval;
|
400
|
-
#endif
|
401
392
|
bc->cif = fnInfo->ffi_cif;
|
402
393
|
bc->function = function;
|
403
394
|
bc->ffiValues = ffiValues;
|
@@ -408,18 +399,10 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
408
399
|
fnInfo->parameterCount, fnInfo->parameterTypes, params, ffiValues,
|
409
400
|
fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums);
|
410
401
|
|
411
|
-
rbffi_frame_push(&frame);
|
402
|
+
rbffi_frame_push(&frame);
|
412
403
|
rb_rescue2(rbffi_do_blocking_call, (VALUE) bc, rbffi_save_frame_exception, (VALUE) &frame, rb_eException, (VALUE) 0);
|
413
404
|
rbffi_frame_pop(&frame);
|
414
405
|
|
415
|
-
#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
|
416
|
-
memcpy(bc->stkretval, bc->retval, MAX(bc->cif.rtype->size, FFI_SIZEOF_ARG));
|
417
|
-
xfree(bc->params);
|
418
|
-
xfree(bc->ffiValues);
|
419
|
-
xfree(bc->retval);
|
420
|
-
xfree(bc);
|
421
|
-
#endif
|
422
|
-
|
423
406
|
} else {
|
424
407
|
|
425
408
|
ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
|
@@ -436,7 +419,7 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
436
419
|
|
437
420
|
if (unlikely(!fnInfo->ignoreErrno)) {
|
438
421
|
rbffi_save_errno();
|
439
|
-
}
|
422
|
+
}
|
440
423
|
|
441
424
|
if (RTEST(frame.exc) && frame.exc != Qnil) {
|
442
425
|
rb_exc_raise(frame.exc);
|
@@ -444,7 +427,7 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
444
427
|
|
445
428
|
RB_GC_GUARD(rbReturnValue) = rbffi_NativeValue_ToRuby(fnInfo->returnType, fnInfo->rbReturnType, retval);
|
446
429
|
RB_GC_GUARD(fnInfo->rbReturnType);
|
447
|
-
|
430
|
+
|
448
431
|
return rbReturnValue;
|
449
432
|
}
|
450
433
|
|
@@ -461,7 +444,7 @@ getPointer(VALUE value, int type)
|
|
461
444
|
return memory != NULL ? memory->address : NULL;
|
462
445
|
|
463
446
|
} else if (type == T_STRING) {
|
464
|
-
|
447
|
+
|
465
448
|
return StringValuePtr(value);
|
466
449
|
|
467
450
|
} else if (type == T_NIL) {
|