ffi 1.17.2 → 1.17.3
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 +25 -0
- data/Gemfile +7 -4
- data/README.md +1 -0
- data/Rakefile +7 -4
- data/Steepfile +8 -0
- data/ext/ffi_c/DynamicLibrary.c +1 -1
- data/ext/ffi_c/Function.c +2 -0
- data/ext/ffi_c/MethodHandle.c +4 -2
- data/ext/ffi_c/libffi/.ci/Containerfile.ppc64le +12 -0
- data/ext/ffi_c/libffi/.ci/build.sh +38 -33
- data/ext/ffi_c/libffi/.ci/install.sh +46 -50
- data/ext/ffi_c/libffi/.ci/site.exp +6 -0
- data/ext/ffi_c/libffi/.gail-labels +44 -0
- data/ext/ffi_c/libffi/.github/workflows/build.yml +212 -333
- data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +58 -3
- data/ext/ffi_c/libffi/.github/workflows/label-new-issue.yaml +15 -0
- data/ext/ffi_c/libffi/.github/workflows/tarball.yml +55 -0
- data/ext/ffi_c/libffi/LICENSE +1 -1
- data/ext/ffi_c/libffi/Makefile.am +17 -13
- data/ext/ffi_c/libffi/Makefile.in +37 -30
- data/ext/ffi_c/libffi/README.md +22 -3
- data/ext/ffi_c/libffi/configure +105 -121
- data/ext/ffi_c/libffi/configure.ac +21 -8
- data/ext/ffi_c/libffi/configure.host +6 -1
- data/ext/ffi_c/libffi/doc/Makefile.in +3 -0
- data/ext/ffi_c/libffi/doc/libffi.texi +24 -1
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -28
- data/ext/ffi_c/libffi/include/Makefile.in +3 -0
- data/ext/ffi_c/libffi/include/ffi.h.in +19 -1
- data/ext/ffi_c/libffi/libffi.map.in +13 -1
- data/ext/ffi_c/libffi/libtool-version +1 -1
- data/ext/ffi_c/libffi/m4/asmcfi.m4 +28 -11
- data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +13 -3
- data/ext/ffi_c/libffi/man/Makefile.in +3 -0
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +7 -1
- data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
- data/ext/ffi_c/libffi/src/pa/linux.S +4 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +6 -0
- data/ext/ffi_c/libffi/src/riscv/ffi.c +39 -16
- data/ext/ffi_c/libffi/src/riscv/internal.h +7 -0
- data/ext/ffi_c/libffi/src/riscv/sysv.S +24 -0
- data/ext/ffi_c/libffi/src/tramp.c +6 -1
- data/ext/ffi_c/libffi/src/types.c +23 -1
- data/ext/ffi_c/libffi/src/{wasm32 → wasm}/ffi.c +157 -54
- data/ext/ffi_c/libffi/src/{wasm32 → wasm}/ffitarget.h +17 -0
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +0 -3
- data/ext/ffi_c/libffi/src/x86/sysv.S +1 -3
- data/ext/ffi_c/libffi/src/x86/sysv_intel.S +1 -3
- data/ext/ffi_c/libffi/testsuite/Makefile.am +3 -2
- data/ext/ffi_c/libffi/testsuite/Makefile.in +6 -2
- data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +2 -2
- data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +4 -4
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +269 -256
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +3 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/longjmp.c +60 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_dbls_struct.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +1 -2
- data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest.cc +2 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc +2 -0
- data/ext/ffi_c/libffi/testsuite/libffi.threads/ffitest.h +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.threads/threads.exp +50 -0
- data/ext/ffi_c/libffi/testsuite/libffi.threads/tsan.c +74 -0
- data/ext/ffi_c/libffi.mk +5 -0
- data/ffi.gemspec +4 -5
- data/lib/ffi/autopointer.rb +6 -0
- data/lib/ffi/compat.rb +11 -0
- data/lib/ffi/function.rb +23 -0
- data/lib/ffi/library.rb +19 -3
- data/lib/ffi/struct_by_reference.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- data/samples/hello_ractor.rb +9 -1
- data/samples/qsort_ractor.rb +9 -1
- data/sig/ffi/auto_pointer.rbs +1 -1
- data/sig/ffi/errno.rbs +8 -0
- data/sig/ffi/platform.rbs +49 -0
- data/sig/ffi/struct.rbs +2 -2
- data/sig/ffi/struct_by_reference.rbs +1 -1
- data/sig/ffi.rbs +4 -1
- data.tar.gz.sig +0 -0
- metadata +33 -79
- metadata.gz.sig +0 -0
- data/ext/ffi_c/libffi/.appveyor/site.exp +0 -16
- data/ext/ffi_c/libffi/.appveyor.yml +0 -84
- data/lib/ffi/tools/types_generator.rb +0 -137
- data/rakelib/ffi_gem_helper.rb +0 -65
- /data/ext/ffi_c/libffi/{.appveyor → .ci}/unix-noexec.exp +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* Area: ffi_call
|
|
2
|
+
Purpose: Test longjmp over ffi_call frames */
|
|
3
|
+
|
|
4
|
+
/* Test code adapted from Lars Kanis' bug report:
|
|
5
|
+
https://github.com/libffi/libffi/issues/905 */
|
|
6
|
+
|
|
7
|
+
/* { dg-do run } */
|
|
8
|
+
|
|
9
|
+
#include "ffitest.h"
|
|
10
|
+
#include "ffi_common.h"
|
|
11
|
+
|
|
12
|
+
#include <setjmp.h>
|
|
13
|
+
|
|
14
|
+
static jmp_buf buf;
|
|
15
|
+
|
|
16
|
+
static void ABI_ATTR lev2(const char *str) {
|
|
17
|
+
printf("lev2 %s\n", str);
|
|
18
|
+
// jumps back to where setjmp was called - making setjmp now return 1
|
|
19
|
+
longjmp(buf, 1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static void ABI_ATTR lev1(const char *str) {
|
|
23
|
+
lev2(str);
|
|
24
|
+
|
|
25
|
+
// will not be reached
|
|
26
|
+
printf("lev1 %s\n", str);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
int main()
|
|
30
|
+
{
|
|
31
|
+
ffi_cif cif;
|
|
32
|
+
ffi_type *args[1];
|
|
33
|
+
void *values[1];
|
|
34
|
+
char *s;
|
|
35
|
+
ffi_arg rc;
|
|
36
|
+
/* Initialize the argument info vectors */
|
|
37
|
+
args[0] = &ffi_type_pointer;
|
|
38
|
+
values[0] = &s;
|
|
39
|
+
/* Initialize the cif */
|
|
40
|
+
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
|
41
|
+
&ffi_type_sint, args) == FFI_OK)
|
|
42
|
+
{
|
|
43
|
+
s = "direct call";
|
|
44
|
+
if (!setjmp(buf)){
|
|
45
|
+
// works on x64 and arm64
|
|
46
|
+
lev1(s);
|
|
47
|
+
} else {
|
|
48
|
+
printf("back to main\n");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
s = "through libffi";
|
|
52
|
+
if (!setjmp(buf)){
|
|
53
|
+
// works on x64 but segfaults on arm64
|
|
54
|
+
ffi_call(&cif, (void (*)(void))lev1, &rc, values);
|
|
55
|
+
} else {
|
|
56
|
+
printf("back to main\n");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
@@ -216,8 +216,7 @@ cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __
|
|
|
216
216
|
ui8_5, si8_5);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
int
|
|
220
|
-
main(int argc __UNUSED__, const char** argv __UNUSED__)
|
|
219
|
+
int main (void)
|
|
221
220
|
{
|
|
222
221
|
void *code;
|
|
223
222
|
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#include "../libffi.call/ffitest.h"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc.
|
|
2
|
+
|
|
3
|
+
# This program is free software; you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation; either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with this program; see the file COPYING3. If not see
|
|
15
|
+
# <http://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+
dg-init
|
|
18
|
+
libffi-init
|
|
19
|
+
|
|
20
|
+
global srcdir subdir
|
|
21
|
+
|
|
22
|
+
if { [string match $compiler_vendor "microsoft"] } {
|
|
23
|
+
# -wd4005 macro redefinition
|
|
24
|
+
# -wd4244 implicit conversion to type of smaller size
|
|
25
|
+
# -wd4305 truncation to smaller type
|
|
26
|
+
# -wd4477 printf %lu of uintptr_t
|
|
27
|
+
# -wd4312 implicit conversion to type of greater size
|
|
28
|
+
# -wd4311 pointer truncation to unsigned long
|
|
29
|
+
# -EHsc C++ Exception Handling (no SEH exceptions)
|
|
30
|
+
set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc";
|
|
31
|
+
} else {
|
|
32
|
+
set additional_options "";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]]
|
|
36
|
+
|
|
37
|
+
# No pthreads for windows or wasm
|
|
38
|
+
if { [string match $compiler_vendor "microsoft"] || [istarget "wasm*-*-*"] } {
|
|
39
|
+
foreach test $tlist {
|
|
40
|
+
unsupported "$test"
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
run-many-tests $tlist $additional_options
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
dg-finish
|
|
47
|
+
|
|
48
|
+
# Local Variables:
|
|
49
|
+
# tcl-indent-level:4
|
|
50
|
+
# End:
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/* { dg-do run } */
|
|
2
|
+
|
|
3
|
+
#include "ffitest.h"
|
|
4
|
+
|
|
5
|
+
#include <pthread.h>
|
|
6
|
+
#include <stdio.h>
|
|
7
|
+
#include <stdlib.h>
|
|
8
|
+
|
|
9
|
+
#define NUM_THREADS 20
|
|
10
|
+
|
|
11
|
+
#if defined(_POSIX_BARRIERS) && _POSIX_BARRIERS > 0
|
|
12
|
+
pthread_barrier_t barrier;
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
typedef float (*callback_fn)(float, float);
|
|
16
|
+
|
|
17
|
+
void callback(ffi_cif *cif __UNUSED__, void *ret, void **args, void *userdata __UNUSED__) {
|
|
18
|
+
float a = *(float *)args[0];
|
|
19
|
+
float b = *(float *)args[1];
|
|
20
|
+
*(float *)ret = a / 2 + b / 2;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
void *thread_func(void *arg) {
|
|
24
|
+
#if defined(_POSIX_BARRIERS) && _POSIX_BARRIERS > 0
|
|
25
|
+
pthread_barrier_wait(&barrier);
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
ffi_cif cif;
|
|
29
|
+
ffi_type *args[2] = { &ffi_type_float, &ffi_type_float };
|
|
30
|
+
|
|
31
|
+
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_float, args) != FFI_OK) {
|
|
32
|
+
fprintf(stderr, "ffi_prep_cif failed\n");
|
|
33
|
+
return NULL;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
ffi_closure *closure = ffi_closure_alloc(sizeof(ffi_closure), (void **)&arg);
|
|
37
|
+
|
|
38
|
+
if (ffi_prep_closure_loc(closure, &cif, callback, NULL, arg) != FFI_OK) {
|
|
39
|
+
fprintf(stderr, "ffi_prep_closure_loc failed\n");
|
|
40
|
+
return NULL;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
callback_fn fn = (callback_fn)arg;
|
|
44
|
+
(void) fn(4.0f, 6.0f);
|
|
45
|
+
|
|
46
|
+
ffi_closure_free(closure);
|
|
47
|
+
return NULL;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
int main() {
|
|
51
|
+
pthread_t threads[NUM_THREADS];
|
|
52
|
+
|
|
53
|
+
#if defined(_POSIX_BARRIERS) && _POSIX_BARRIERS > 0
|
|
54
|
+
pthread_barrier_init(&barrier, NULL, NUM_THREADS);
|
|
55
|
+
#endif
|
|
56
|
+
|
|
57
|
+
for (int i = 0; i < NUM_THREADS; ++i) {
|
|
58
|
+
if (pthread_create(&threads[i], NULL, thread_func, NULL) != 0) {
|
|
59
|
+
perror("pthread_create");
|
|
60
|
+
exit(EXIT_FAILURE);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
for (int i = 0; i < NUM_THREADS; ++i) {
|
|
65
|
+
pthread_join(threads[i], NULL);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#if defined(_POSIX_BARRIERS) && _POSIX_BARRIERS > 0
|
|
69
|
+
pthread_barrier_destroy(&barrier);
|
|
70
|
+
#endif
|
|
71
|
+
|
|
72
|
+
printf("Completed\n");
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
data/ext/ffi_c/libffi.mk
CHANGED
data/ffi.gemspec
CHANGED
|
@@ -15,9 +15,10 @@ Gem::Specification.new do |s|
|
|
|
15
15
|
s.metadata['wiki_uri'] = 'https://github.com/ffi/ffi/wiki'
|
|
16
16
|
s.metadata['source_code_uri'] = 'https://github.com/ffi/ffi/'
|
|
17
17
|
s.metadata['mailing_list_uri'] = 'http://groups.google.com/group/ruby-ffi'
|
|
18
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
|
18
19
|
end
|
|
19
20
|
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
20
|
-
f =~ /^(\.|bench|gen|libtest|nbproject|spec)/
|
|
21
|
+
f =~ /^(\.|bench|gen|libtest|nbproject|spec|rakelib)/
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
# Add libffi git files
|
|
@@ -35,8 +36,6 @@ Gem::Specification.new do |s|
|
|
|
35
36
|
s.license = 'BSD-3-Clause'
|
|
36
37
|
s.require_paths << 'ext/ffi_c'
|
|
37
38
|
s.required_ruby_version = '>= 2.5'
|
|
38
|
-
|
|
39
|
-
s.
|
|
40
|
-
s.add_development_dependency 'rake-compiler-dock', '~> 1.0'
|
|
41
|
-
s.add_development_dependency 'rspec', '~> 2.14.1'
|
|
39
|
+
|
|
40
|
+
s.metadata['msys2_mingw_dependencies'] = 'libffi'
|
|
42
41
|
end
|
data/lib/ffi/autopointer.rb
CHANGED
data/lib/ffi/compat.rb
CHANGED
|
@@ -40,4 +40,15 @@ module FFI
|
|
|
40
40
|
obj.freeze
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
|
+
|
|
44
|
+
if defined?(Ractor.shareable_proc)
|
|
45
|
+
# This is for FFI internal use only.
|
|
46
|
+
def self.shareable_proc(**kwargs, &block)
|
|
47
|
+
Ractor.shareable_proc(**kwargs, &block)
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
def self.shareable_proc(**_kwargs, &block)
|
|
51
|
+
block
|
|
52
|
+
end
|
|
53
|
+
end
|
|
43
54
|
end
|
data/lib/ffi/function.rb
CHANGED
|
@@ -51,6 +51,29 @@ module FFI
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
if RUBY_PLATFORM == 'aarch64-mingw-ucrt'
|
|
55
|
+
# Use a workaround for https://github.com/libffi/libffi/issues/905
|
|
56
|
+
def attach(mod, name)
|
|
57
|
+
this = self
|
|
58
|
+
body = proc do |*args, &block|
|
|
59
|
+
this.call(*args, &block)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
mod.define_method(name, body)
|
|
63
|
+
mod.define_singleton_method(name, body)
|
|
64
|
+
|
|
65
|
+
# Store function Proc's for re-definition as Ractor-shareable in Library#freeze
|
|
66
|
+
funcs = mod.instance_variable_get("@ffi_function_procs")
|
|
67
|
+
unless funcs
|
|
68
|
+
funcs = {}
|
|
69
|
+
mod.instance_variable_set("@ffi_function_procs", funcs)
|
|
70
|
+
end
|
|
71
|
+
funcs[name] = self
|
|
72
|
+
|
|
73
|
+
self
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
54
77
|
# Stash the Function in a module variable so it can be inspected by attached_functions.
|
|
55
78
|
# On CRuby it also ensures that it does not get garbage collected.
|
|
56
79
|
module RegisterAttach
|
data/lib/ffi/library.rb
CHANGED
|
@@ -287,7 +287,7 @@ module FFI
|
|
|
287
287
|
if type.is_a?(Class) && type < FFI::Struct
|
|
288
288
|
# If it is a global struct, just attach directly to the pointer
|
|
289
289
|
s = s = type.new(address) # Assigning twice to suppress unused variable warning
|
|
290
|
-
self.module_eval
|
|
290
|
+
self.module_eval(<<-code, __FILE__, __LINE__)
|
|
291
291
|
@ffi_gsvars = {} unless defined?(@ffi_gsvars)
|
|
292
292
|
@ffi_gsvars[#{mname.inspect}] = s
|
|
293
293
|
def self.#{mname}
|
|
@@ -302,7 +302,7 @@ module FFI
|
|
|
302
302
|
#
|
|
303
303
|
# Attach to this module as mname/mname=
|
|
304
304
|
#
|
|
305
|
-
self.module_eval
|
|
305
|
+
self.module_eval(<<-code, __FILE__, __LINE__)
|
|
306
306
|
@ffi_gvars = {} unless defined?(@ffi_gvars)
|
|
307
307
|
@ffi_gvars[#{mname.inspect}] = s
|
|
308
308
|
def self.#{mname}
|
|
@@ -564,12 +564,28 @@ module FFI
|
|
|
564
564
|
# Freeze all definitions of the module
|
|
565
565
|
#
|
|
566
566
|
# This freezes the module's definitions, so that it can be used in a Ractor.
|
|
567
|
-
# No further
|
|
567
|
+
# No further functions or variables can be attached and no further enums or typedefs can be created in this module afterwards.
|
|
568
568
|
def freeze
|
|
569
|
+
# @ffi_function_procs is only used on aarch64-mingw-ucrt
|
|
570
|
+
instance_variable_get("@ffi_function_procs")&.each do |name, func|
|
|
571
|
+
# Redefine attached functions as Ractor-shareable.
|
|
572
|
+
# The function Proc can't be shareable from the beginning, since it references enums and typedefs.
|
|
573
|
+
this = FFI.make_shareable(func)
|
|
574
|
+
body = FFI.shareable_proc(self: nil) do |*args, &block|
|
|
575
|
+
this.call(*args, &block)
|
|
576
|
+
end
|
|
577
|
+
undef_method(name)
|
|
578
|
+
singleton_class.undef_method(name)
|
|
579
|
+
|
|
580
|
+
define_method(name, body)
|
|
581
|
+
define_singleton_method(name, body)
|
|
582
|
+
end
|
|
583
|
+
|
|
569
584
|
instance_variables.each do |name|
|
|
570
585
|
var = instance_variable_get(name)
|
|
571
586
|
FFI.make_shareable(var)
|
|
572
587
|
end
|
|
588
|
+
super
|
|
573
589
|
nil
|
|
574
590
|
end
|
|
575
591
|
end
|
data/lib/ffi/version.rb
CHANGED
data/samples/hello_ractor.rb
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
# See the ffi wiki for how to use FFI with Ractors:
|
|
2
|
+
# https://github.com/ffi/ffi/wiki/Ractors
|
|
3
|
+
|
|
1
4
|
require 'ffi'
|
|
2
5
|
|
|
6
|
+
class Ractor
|
|
7
|
+
# compat with Ruby-3.4 and older
|
|
8
|
+
alias value take unless method_defined? :value
|
|
9
|
+
end
|
|
10
|
+
|
|
3
11
|
module Foo
|
|
4
12
|
extend FFI::Library
|
|
5
13
|
ffi_lib FFI::Library::LIBC
|
|
@@ -8,4 +16,4 @@ module Foo
|
|
|
8
16
|
end
|
|
9
17
|
Ractor.new do
|
|
10
18
|
Foo.cputs("Hello, World via libc puts using FFI in a Ractor")
|
|
11
|
-
end.
|
|
19
|
+
end.value
|
data/samples/qsort_ractor.rb
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
# See the ffi wiki for how to use FFI with Ractors:
|
|
2
|
+
# https://github.com/ffi/ffi/wiki/Ractors
|
|
3
|
+
|
|
1
4
|
require 'ffi'
|
|
2
5
|
|
|
6
|
+
class Ractor
|
|
7
|
+
# compat with Ruby-3.4 and older
|
|
8
|
+
alias value take unless method_defined? :value
|
|
9
|
+
end
|
|
10
|
+
|
|
3
11
|
module LibC
|
|
4
12
|
extend FFI::Library
|
|
5
13
|
ffi_lib FFI::Library::LIBC
|
|
@@ -23,6 +31,6 @@ res = Ractor.new(p) do |p|
|
|
|
23
31
|
i1 < i2 ? -1 : i1 > i2 ? 1 : 0
|
|
24
32
|
end
|
|
25
33
|
puts "After qsort #{p.get_array_of_int32(0, 3).join(', ')}"
|
|
26
|
-
end.
|
|
34
|
+
end.value
|
|
27
35
|
|
|
28
36
|
puts "After ractor termination #{p.get_array_of_int32(0, 3).join(', ')}"
|
data/sig/ffi/auto_pointer.rbs
CHANGED
|
@@ -12,7 +12,7 @@ module FFI
|
|
|
12
12
|
def release: (Pointer ptr) -> void
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def initialize: (Pointer pointer, Method | ^(
|
|
15
|
+
def initialize: (Pointer pointer, Method | ^(instance) -> void | Releaser::_Proc[instance] callable) -> self
|
|
16
16
|
| (Pointer pointer) -> self # where class < `def self.release: (instance pointer) -> void`
|
|
17
17
|
|
|
18
18
|
extend DataConverter[Pointer, instance, nil]
|
data/sig/ffi/errno.rbs
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module FFI
|
|
2
|
+
class PlatformError < LoadError
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
module Platform
|
|
6
|
+
OS: String
|
|
7
|
+
|
|
8
|
+
OSVERSION: Integer
|
|
9
|
+
|
|
10
|
+
CPU: String
|
|
11
|
+
|
|
12
|
+
ARCH: String
|
|
13
|
+
|
|
14
|
+
IS_GNU: bool
|
|
15
|
+
IS_LINUX: bool
|
|
16
|
+
IS_MAC: bool
|
|
17
|
+
IS_FREEBSD: bool
|
|
18
|
+
IS_NETBSD: bool
|
|
19
|
+
IS_OPENBSD: bool
|
|
20
|
+
IS_DRAGONFLYBSD: bool
|
|
21
|
+
IS_SOLARIS: bool
|
|
22
|
+
IS_WINDOWS: bool
|
|
23
|
+
IS_BSD: bool
|
|
24
|
+
|
|
25
|
+
NAME: String
|
|
26
|
+
|
|
27
|
+
CONF_DIR: String
|
|
28
|
+
|
|
29
|
+
LIBPREFIX: String
|
|
30
|
+
|
|
31
|
+
LIBSUFFIX: String
|
|
32
|
+
|
|
33
|
+
LIBC: String
|
|
34
|
+
|
|
35
|
+
LITTLE_ENDIAN: Integer
|
|
36
|
+
|
|
37
|
+
BIG_ENDIAN: Integer
|
|
38
|
+
|
|
39
|
+
def self.bsd?: () -> bool
|
|
40
|
+
def self.windows?: () -> bool
|
|
41
|
+
def self.mac?: () -> bool
|
|
42
|
+
def self.solaris?: () -> bool
|
|
43
|
+
def self.unix?: () -> bool
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def self.is_os: (String os) -> bool
|
|
48
|
+
end
|
|
49
|
+
end
|
data/sig/ffi/struct.rbs
CHANGED
|
@@ -4,7 +4,7 @@ module FFI
|
|
|
4
4
|
|
|
5
5
|
type ptr = Type::Mapped[
|
|
6
6
|
StructByReference[Struct[AbstractMemory, untyped], AbstractMemory],
|
|
7
|
-
AbstractMemory,
|
|
7
|
+
AbstractMemory, Struct[AbstractMemory, untyped], untyped
|
|
8
8
|
]
|
|
9
9
|
def self.ptr: (?untyped flags) -> ptr # https://github.com/ffi/ffi/issues/1073
|
|
10
10
|
alias self.by_ref self.ptr
|
|
@@ -22,7 +22,7 @@ module FFI
|
|
|
22
22
|
|
|
23
23
|
def self.auto_ptr: () -> Type::Mapped[
|
|
24
24
|
ManagedStructConverter[ManagedStruct[AutoPointer, untyped], AutoPointer],
|
|
25
|
-
Pointer,
|
|
25
|
+
Pointer, ManagedStruct[AutoPointer, untyped], untyped
|
|
26
26
|
]
|
|
27
27
|
def self.layout: (*layout | Integer) -> StructLayout
|
|
28
28
|
| (Hash[Symbol, layout]) -> StructLayout
|
data/sig/ffi.rbs
CHANGED
|
@@ -14,9 +14,12 @@ module FFI
|
|
|
14
14
|
CURRENT_PROCESS: current_process
|
|
15
15
|
USE_THIS_PROCESS_AS_LIBRARY: current_process
|
|
16
16
|
|
|
17
|
+
class NotFoundError < LoadError
|
|
18
|
+
end
|
|
19
|
+
|
|
17
20
|
private def self.custom_typedefs: () -> type_map
|
|
18
21
|
def self.errno: () -> Integer
|
|
19
|
-
def self.errno=: (Integer) ->
|
|
22
|
+
def self.errno=: (Integer) -> Integer
|
|
20
23
|
def self.find_type: (ffi_auto_type name, ?type_map? type_map) -> Type
|
|
21
24
|
def self.make_shareable: [T] (T obj) -> T
|
|
22
25
|
def self.map_library_name: (_ToS lib) -> String
|
data.tar.gz.sig
CHANGED
|
Binary file
|