8000 Revert "Revert "Revert "[ruby/fiddle] Use ffi_closure_free by default… · github/ruby@d732bc5 · GitHub
[go: up one dir, main page]

Skip to content

Commit d732bc5

Browse files
committed
Revert "Revert "Revert "[ruby/fiddle] Use ffi_closure_free by default. (#20)"""
This reverts commit 87f6154. It turned out that the change fails to build on macOS https://rubyci.org/logs/rubyci.s3.amazonaws.com/osx1014/ruby-master/log/20200304T074503Z.fail.html.gz ``` + make 'TESTS=--hide-skip -v fiddle' RUBYOPT=-w test-all dyld: lazy symbol binding failed: Symbol not found: _ffi_closure_alloc Referenced from: /Users/hsbt/Documents/cb/tmp/build/20200304T074503Z/ruby/.ext/x86_64-darwin18/fiddle.bundle Expected in: flat namespace dyld: Symbol not found: _ffi_closure_alloc Referenced from: /Users/hsbt/Documents/cb/tmp/build/20200304T074503Z/ruby/.ext/x86_64-darwin18/fiddle.bundle Expected in: flat namespace make: *** [yes-test-all] Abort trap: 6 ```
1 parent 87f6154 commit d732bc5

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

ext/fiddle/closure.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,25 @@ typedef struct {
1313
ffi_type **argv;
1414
} fiddle_closure;
1515

16+
#if defined(USE_FFI_CLOSURE_ALLOC)
17+
#elif defined(__OpenBSD__) || defined(__APPLE__) || defined(__linux__)
18+
# define USE_FFI_CLOSURE_ALLOC 0
19+
#elif defined(RUBY_LIBFFI_MODVERSION) && RUBY_LIBFFI_MODVERSION < 3000005 && \
20+
(defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64))
21+
# define USE_FFI_CLOSURE_ALLOC 0
22+
#else
23+
# define USE_FFI_CLOSURE_ALLOC 1
24+
#endif
25+
1626
static void
1727
dealloc(void * ptr)
1828
{
1929
fiddle_closure * cls = (fiddle_closure *)ptr;
30+
#if USE_FFI_CLOSURE_ALLOC
2031
ffi_closure_free(cls->pcl);
32+
#else
33+
munmap(cls->pcl, sizeof(*cls->pcl));
34+
#endif
2135
if (cls->argv) xfree(cls->argv);
2236
xfree(cls);
2337
}
@@ -191,7 +205,12 @@ allocate(VALUE klass)
191205
VALUE i = TypedData_Make_Struct(klass, fiddle_closure,
192206
&closure_data_type, closure);
193207

208+
#if USE_FFI_CLOSURE_ALLOC
194209
closure->pcl = ffi_closure_alloc(sizeof(ffi_closure), &closure->code);
210+
#else
211+
closure->pcl = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
212+
MAP_ANON | MAP_PRIVATE, -1, 0);
213+
#endif
195214

196215
return i;
197216
}
@@ -238,8 +257,17 @@ initialize(int rbargc, VALUE argv[], VALUE self)
238257
if (FFI_OK != result)
239258
rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
240259

260+
#if USE_FFI_CLOSURE_ALLOC
241261
result = ffi_prep_closure_loc(pcl, cif, callback,
242262
(void *)self, cl->code);
263+
#else
264+
result = ffi_prep_closure(pcl, cif, callback, (void *)self);
265+
cl->code = (void *)pcl;
266+
i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC);
267+
if (i) {
268+
rb_sys_fail("mprotect");
269+
}
270+
#endif
243271

244272
if (FFI_OK != result)
245273
rb_raise(rb_eRuntimeError, "error prepping closure %d", result);

ext/fiddle/extconf.rb

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
if ! bundle
88
dir_config 'libffi'
99

10-
pkg_config("libffi")
10+
pkg_config("libffi") and
11+
ver = pkg_config("libffi", "modversion")
1112

1213
if have_header(ffi_header = 'ffi.h')
1314
true
@@ -27,20 +28,20 @@
2728
Dir.glob("#{$srcdir}/libffi-*/").each{|dir| FileUtils.rm_rf(dir)}
2829
extlibs.run(["--cache=#{cache_dir}", ext_dir])
2930
end
30-
libffi_dir = bundle != false &&
31+
ver = bundle != false &&
3132
Dir.glob("#{$srcdir}/libffi-*/")
3233
.map {|n| File.basename(n)}
3334
.max_by {|n| n.scan(/\d+/).map(&:to_i)}
34-
unless libffi_dir
35+
unless ver
3536
raise "missing libffi. Please install libffi."
3637
end
3738

38-
srcdir = "#{$srcdir}/#{libffi_dir}"
39+
srcdir = "#{$srcdir}/#{ver}"
3940
ffi_header = 'ffi.h'
4041
libffi = Struct.new(*%I[dir srcdir builddir include lib a cflags ldflags opt arch]).new
41-
libffi.dir = libffi_dir
42+
libffi.dir = ver
4243
if $srcdir == "."
43-
libffi.builddir = "#{libffi_dir}/#{RUBY_PLATFORM}"
44+
libffi.builddir = "#{ver}/#{RUBY_PLATFORM}"
4445
libffi.srcdir = "."
4546
else
4647
libffi.builddir = libffi.dir
@@ -51,6 +52,7 @@
5152
libffi.a = "#{libffi.lib}/libffi_convenience.#{$LIBEXT}"
5253
nowarn = CONFIG.merge("warnflags"=>"")
5354
libffi.cflags = RbConfig.expand("$(CFLAGS)".dup, nowarn)
55+
ver = ver[/libffi-(.*)/, 1]
5456

5557
FileUtils.mkdir_p(libffi.dir)
5658
libffi.opt = CONFIG['configure_args'][/'(-C)'/, 1]
@@ -110,6 +112,12 @@
110112
$INCFLAGS << " -I" << libffi.include
111113
end
112114

115+
if ver
116+
ver = ver.gsub(/-rc\d+/, '') # If ver contains rc version, just ignored.
117+
ver = (ver.split('.') + [0,0])[0,3]
118+
$defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % ver }})
119+
end
120+
113121
have_header 'sys/mman.h'
114122

115123
if have_header "dlfcn.h"

0 commit comments

Comments
 (0)
0