ffi 1.9.21 → 1.9.22
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +22 -0
- data/.gitmodules +3 -0
- data/.travis.yml +52 -0
- data/.yardopts +5 -0
- data/Gemfile +15 -0
- data/{spec/ffi/LICENSE.SPECS → LICENSE.SPECS} +1 -1
- data/README.md +1 -1
- data/Rakefile +28 -3
- data/appveyor.yml +22 -0
- data/ext/ffi_c/Call.c +1 -22
- data/ext/ffi_c/Call.h +0 -9
- data/ext/ffi_c/Closure.c +54 -0
- data/ext/ffi_c/{ClosurePool.h → Closure.h} +13 -23
- data/ext/ffi_c/Function.c +16 -25
- data/ext/ffi_c/Function.h +1 -2
- data/ext/ffi_c/FunctionInfo.c +0 -4
- data/ext/ffi_c/MethodHandle.c +33 -268
- data/ext/ffi_c/extconf.rb +3 -3
- data/ext/ffi_c/ffi.c +2 -2
- data/ext/ffi_c/libffi.bsd.mk +3 -3
- data/ext/ffi_c/libffi.darwin.mk +1 -1
- data/ext/ffi_c/libffi.gnu.mk +1 -1
- data/ext/ffi_c/libffi.mk +2 -2
- data/ext/ffi_c/libffi.vc.mk +1 -1
- data/ext/ffi_c/libffi.vc64.mk +1 -1
- data/ext/ffi_c/libffi/.appveyor.yml +48 -0
- data/ext/ffi_c/libffi/.gitignore +36 -0
- data/ext/ffi_c/libffi/.travis.yml +30 -0
- data/ext/ffi_c/libffi/.travis/install.sh +14 -0
- data/ext/ffi_c/libffi/Makefile.am +5 -3
- data/ext/ffi_c/libffi/acinclude.m4 +6 -0
- data/ext/ffi_c/libffi/autogen.sh +1 -1
- data/ext/ffi_c/libffi/config.guess +1466 -0
- data/ext/ffi_c/libffi/config.sub +1836 -0
- data/ext/ffi_c/libffi/configure.ac +2 -2
- data/ext/ffi_c/libffi/configure.host +15 -3
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +11 -15
- data/ext/ffi_c/libffi/include/ffi.h.in +6 -1
- data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +465 -59
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +33 -10
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +2 -2
- data/ext/ffi_c/libffi/src/arm/ffi.c +12 -1
- data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
- data/ext/ffi_c/libffi/src/closures.c +143 -97
- data/ext/ffi_c/libffi/src/ia64/unix.S +2 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +8 -0
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
- data/ext/ffi_c/libffi/src/mips/n32.S +2 -0
- data/ext/ffi_c/libffi/src/powerpc/aix.S +239 -1
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +250 -3
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +86 -5
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +3 -0
- data/ext/ffi_c/libffi/src/x86/ffi.c +3 -1
- data/ext/ffi_c/libffi/src/x86/ffi64.c +26 -5
- data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
- data/ext/ffi_c/libffi/src/x86/unix64.S +1 -1
- data/ext/ffi_c/libffi/src/x86/win64.S +1 -1
- data/ext/ffi_c/libffi/testsuite/Makefile.am +2 -1
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +2 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
- data/ffi.gemspec +14 -1
- data/lib/ffi/library.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- data/samples/getlogin.rb +8 -0
- data/samples/getpid.rb +8 -0
- data/samples/gettimeofday.rb +18 -0
- data/samples/hello.rb +7 -0
- data/samples/inotify.rb +60 -0
- data/samples/pty.rb +76 -0
- data/samples/qsort.rb +21 -0
- data/samples/sample_helper.rb +6 -0
- metadata +59 -81
- metadata.gz.sig +0 -0
- data/ext/ffi_c/ClosurePool.c +0 -283
- data/gen/Rakefile +0 -30
- data/libtest/Benchmark.c +0 -52
- data/libtest/BoolTest.c +0 -34
- data/libtest/BufferTest.c +0 -31
- data/libtest/ClosureTest.c +0 -205
- data/libtest/EnumTest.c +0 -51
- data/libtest/FunctionTest.c +0 -70
- data/libtest/GNUmakefile +0 -149
- data/libtest/GlobalVariable.c +0 -62
- data/libtest/LastErrorTest.c +0 -21
- data/libtest/NumberTest.c +0 -132
- data/libtest/PointerTest.c +0 -63
- data/libtest/ReferenceTest.c +0 -23
- data/libtest/StringTest.c +0 -34
- data/libtest/StructTest.c +0 -243
- data/libtest/UnionTest.c +0 -43
- data/libtest/VariadicTest.c +0 -99
- data/spec/ffi/async_callback_spec.rb +0 -35
- data/spec/ffi/bitmask_spec.rb +0 -575
- data/spec/ffi/bool_spec.rb +0 -32
- data/spec/ffi/buffer_spec.rb +0 -279
- data/spec/ffi/callback_spec.rb +0 -773
- data/spec/ffi/custom_param_type.rb +0 -37
- data/spec/ffi/custom_type_spec.rb +0 -74
- data/spec/ffi/dup_spec.rb +0 -52
- data/spec/ffi/enum_spec.rb +0 -423
- data/spec/ffi/errno_spec.rb +0 -20
- data/spec/ffi/ffi_spec.rb +0 -28
- data/spec/ffi/fixtures/Benchmark.c +0 -52
- data/spec/ffi/fixtures/BitmaskTest.c +0 -51
- data/spec/ffi/fixtures/BoolTest.c +0 -34
- data/spec/ffi/fixtures/BufferTest.c +0 -31
- data/spec/ffi/fixtures/ClosureTest.c +0 -205
- data/spec/ffi/fixtures/EnumTest.c +0 -51
- data/spec/ffi/fixtures/FunctionTest.c +0 -142
- data/spec/ffi/fixtures/GNUmakefile +0 -149
- data/spec/ffi/fixtures/GlobalVariable.c +0 -62
- data/spec/ffi/fixtures/LastErrorTest.c +0 -21
- data/spec/ffi/fixtures/NumberTest.c +0 -132
- data/spec/ffi/fixtures/PipeHelper.h +0 -21
- data/spec/ffi/fixtures/PipeHelperPosix.c +0 -41
- data/spec/ffi/fixtures/PipeHelperWindows.c +0 -72
- data/spec/ffi/fixtures/PointerTest.c +0 -63
- data/spec/ffi/fixtures/ReferenceTest.c +0 -23
- data/spec/ffi/fixtures/StringTest.c +0 -34
- data/spec/ffi/fixtures/StructTest.c +0 -243
- data/spec/ffi/fixtures/UnionTest.c +0 -43
- data/spec/ffi/fixtures/VariadicTest.c +0 -99
- data/spec/ffi/fixtures/classes.rb +0 -438
- data/spec/ffi/function_spec.rb +0 -97
- data/spec/ffi/io_spec.rb +0 -16
- data/spec/ffi/library_spec.rb +0 -286
- data/spec/ffi/long_double.rb +0 -30
- data/spec/ffi/managed_struct_spec.rb +0 -68
- data/spec/ffi/memorypointer_spec.rb +0 -78
- data/spec/ffi/number_spec.rb +0 -247
- data/spec/ffi/platform_spec.rb +0 -114
- data/spec/ffi/pointer_spec.rb +0 -285
- data/spec/ffi/rbx/attach_function_spec.rb +0 -34
- data/spec/ffi/rbx/memory_pointer_spec.rb +0 -198
- data/spec/ffi/rbx/spec_helper.rb +0 -6
- data/spec/ffi/rbx/struct_spec.rb +0 -18
- data/spec/ffi/spec_helper.rb +0 -93
- data/spec/ffi/string_spec.rb +0 -118
- data/spec/ffi/strptr_spec.rb +0 -50
- data/spec/ffi/struct_by_ref_spec.rb +0 -43
- data/spec/ffi/struct_callback_spec.rb +0 -69
- data/spec/ffi/struct_initialize_spec.rb +0 -35
- data/spec/ffi/struct_packed_spec.rb +0 -50
- data/spec/ffi/struct_spec.rb +0 -882
- data/spec/ffi/typedef_spec.rb +0 -91
- data/spec/ffi/union_spec.rb +0 -67
- data/spec/ffi/variadic_spec.rb +0 -132
- data/spec/spec.opts +0 -4
data/ext/ffi_c/Function.h
CHANGED
@@ -46,7 +46,7 @@ typedef struct FunctionType_ FunctionType;
|
|
46
46
|
|
47
47
|
#include "Type.h"
|
48
48
|
#include "Call.h"
|
49
|
-
#include "
|
49
|
+
#include "Closure.h"
|
50
50
|
|
51
51
|
struct FunctionType_ {
|
52
52
|
Type type; /* The native type of a FunctionInfo object */
|
@@ -60,7 +60,6 @@ struct FunctionType_ {
|
|
60
60
|
ffi_type** ffiParameterTypes;
|
61
61
|
ffi_cif ffi_cif;
|
62
62
|
Invoker invoke;
|
63
|
-
ClosurePool* closurePool;
|
64
63
|
int parameterCount;
|
65
64
|
int flags;
|
66
65
|
ffi_abi abi;
|
data/ext/ffi_c/FunctionInfo.c
CHANGED
@@ -72,7 +72,6 @@ fntype_allocate(VALUE klass)
|
|
72
72
|
fnInfo->rbParameterTypes = Qnil;
|
73
73
|
fnInfo->rbEnums = Qnil;
|
74
74
|
fnInfo->invoke = rbffi_CallFunction;
|
75
|
-
fnInfo->closurePool = NULL;
|
76
75
|
|
77
76
|
return obj;
|
78
77
|
}
|
@@ -95,9 +94,6 @@ fntype_free(FunctionType* fnInfo)
|
|
95
94
|
xfree(fnInfo->ffiParameterTypes);
|
96
95
|
xfree(fnInfo->nativeParameterTypes);
|
97
96
|
xfree(fnInfo->callbackParameters);
|
98
|
-
if (fnInfo->closurePool != NULL) {
|
99
|
-
rbffi_ClosurePool_Free(fnInfo->closurePool);
|
100
|
-
}
|
101
97
|
xfree(fnInfo);
|
102
98
|
}
|
103
99
|
|
data/ext/ffi_c/MethodHandle.c
CHANGED
@@ -26,30 +26,6 @@
|
|
26
26
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
27
|
*/
|
28
28
|
|
29
|
-
#ifndef _MSC_VER
|
30
|
-
#include <sys/param.h>
|
31
|
-
#endif
|
32
|
-
#include <sys/types.h>
|
33
|
-
#ifndef _WIN32
|
34
|
-
# include <sys/mman.h>
|
35
|
-
#endif
|
36
|
-
#include <stdio.h>
|
37
|
-
#ifndef _MSC_VER
|
38
|
-
# include <stdint.h>
|
39
|
-
# include <stdbool.h>
|
40
|
-
#else
|
41
|
-
# include "win32/stdint.h"
|
42
|
-
# include "win32/stdbool.h"
|
43
|
-
#endif
|
44
|
-
#ifndef _WIN32
|
45
|
-
# include <unistd.h>
|
46
|
-
#endif
|
47
|
-
#include <errno.h>
|
48
|
-
#include <ruby.h>
|
49
|
-
#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32) && !defined(__WIN32__)
|
50
|
-
# include <pthread.h>
|
51
|
-
#endif
|
52
|
-
|
53
29
|
#include <ffi.h>
|
54
30
|
#include "rbffi.h"
|
55
31
|
#include "compat.h"
|
@@ -59,79 +35,16 @@
|
|
59
35
|
#include "Type.h"
|
60
36
|
#include "LastError.h"
|
61
37
|
#include "Call.h"
|
62
|
-
#include "
|
38
|
+
#include "Closure.h"
|
63
39
|
#include "MethodHandle.h"
|
64
40
|
|
65
|
-
|
66
|
-
#define
|
67
|
-
|
68
|
-
#ifndef roundup
|
69
|
-
# define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
|
70
|
-
#endif
|
71
|
-
#ifdef _WIN32
|
72
|
-
typedef char* caddr_t;
|
73
|
-
#endif
|
74
|
-
|
75
|
-
#ifdef USE_RAW
|
76
|
-
# define METHOD_CLOSURE ffi_raw_closure
|
77
|
-
# define METHOD_PARAMS ffi_raw*
|
78
|
-
#else
|
79
|
-
# define METHOD_CLOSURE ffi_closure
|
80
|
-
# define METHOD_PARAMS void**
|
81
|
-
#endif
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
static bool prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize);
|
86
|
-
static long trampoline_size(void);
|
87
|
-
|
88
|
-
#if defined(__x86_64__) && (defined(__linux__) || defined(__APPLE__))
|
89
|
-
# define CUSTOM_TRAMPOLINE 1
|
90
|
-
#endif
|
91
|
-
|
41
|
+
#define METHOD_CLOSURE ffi_closure
|
42
|
+
#define METHOD_PARAMS void**
|
92
43
|
|
93
44
|
struct MethodHandle {
|
94
45
|
Closure* closure;
|
95
46
|
};
|
96
47
|
|
97
|
-
static ClosurePool* defaultClosurePool;
|
98
|
-
|
99
|
-
|
100
|
-
MethodHandle*
|
101
|
-
rbffi_MethodHandle_Alloc(FunctionType* fnInfo, void* function)
|
102
|
-
{
|
103
|
-
MethodHandle* handle;
|
104
|
-
Closure* closure = rbffi_Closure_Alloc(defaultClosurePool);
|
105
|
-
if (closure == NULL) {
|
106
|
-
rb_raise(rb_eNoMemError, "failed to allocate closure from pool");
|
107
|
-
return NULL;
|
108
|
-
}
|
109
|
-
|
110
|
-
handle = xcalloc(1, sizeof(*handle));
|
111
|
-
handle->closure = closure;
|
112
|
-
closure->info = fnInfo;
|
113
|
-
closure->function = function;
|
114
|
-
|
115
|
-
return handle;
|
116
|
-
}
|
117
|
-
|
118
|
-
void
|
119
|
-
rbffi_MethodHandle_Free(MethodHandle* handle)
|
120
|
-
{
|
121
|
-
if (handle != NULL) {
|
122
|
-
rbffi_Closure_Free(handle->closure);
|
123
|
-
}
|
124
|
-
}
|
125
|
-
|
126
|
-
void*
|
127
|
-
rbffi_MethodHandle_CodeAddress(MethodHandle* handle)
|
128
|
-
{
|
129
|
-
return handle->closure->code;
|
130
|
-
}
|
131
|
-
|
132
|
-
#ifndef CUSTOM_TRAMPOLINE
|
133
|
-
static void attached_method_invoke(ffi_cif* cif, void* retval, METHOD_PARAMS parameters, void* user_data);
|
134
|
-
|
135
48
|
static ffi_type* methodHandleParamTypes[] = {
|
136
49
|
&ffi_type_sint,
|
137
50
|
&ffi_type_pointer,
|
@@ -140,219 +53,71 @@ static ffi_type* methodHandleParamTypes[] = {
|
|
140
53
|
|
141
54
|
static ffi_cif mh_cif;
|
142
55
|
|
143
|
-
static bool
|
144
|
-
prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
|
145
|
-
{
|
146
|
-
ffi_status ffiStatus;
|
147
|
-
|
148
|
-
#if defined(USE_RAW)
|
149
|
-
ffiStatus = ffi_prep_raw_closure(code, &mh_cif, attached_method_invoke, closure);
|
150
|
-
#else
|
151
|
-
ffiStatus = ffi_prep_closure(code, &mh_cif, attached_method_invoke, closure);
|
152
|
-
#endif
|
153
|
-
if (ffiStatus != FFI_OK) {
|
154
|
-
snprintf(errmsg, errmsgsize, "ffi_prep_closure failed. status=%#x", ffiStatus);
|
155
|
-
return false;
|
156
|
-
}
|
157
|
-
|
158
|
-
return true;
|
159
|
-
}
|
160
|
-
|
161
|
-
|
162
|
-
static long
|
163
|
-
trampoline_size(void)
|
164
|
-
{
|
165
|
-
return sizeof(METHOD_CLOSURE);
|
166
|
-
}
|
167
|
-
|
168
|
-
/*
|
169
|
-
* attached_method_invoke is used functions with more than 6 parameters, or
|
170
|
-
* with struct param or return values
|
171
|
-
*/
|
172
56
|
static void
|
173
57
|
attached_method_invoke(ffi_cif* cif, void* mretval, METHOD_PARAMS parameters, void* user_data)
|
174
58
|
{
|
175
59
|
Closure* handle = (Closure *) user_data;
|
176
60
|
FunctionType* fnInfo = (FunctionType *) handle->info;
|
177
61
|
|
178
|
-
#ifdef USE_RAW
|
179
|
-
int argc = parameters[0].sint;
|
180
|
-
VALUE* argv = *(VALUE **) ¶meters[1];
|
181
|
-
#else
|
182
62
|
int argc = *(int *) parameters[0];
|
183
63
|
VALUE* argv = *(VALUE **) parameters[1];
|
184
|
-
#endif
|
185
64
|
|
186
65
|
*(VALUE *) mretval = (*fnInfo->invoke)(argc, argv, handle->function, fnInfo);
|
187
66
|
}
|
188
67
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
#if defined(CUSTOM_TRAMPOLINE)
|
194
|
-
#if defined(__x86_64__)
|
195
|
-
|
196
|
-
static VALUE custom_trampoline(int argc, VALUE* argv, VALUE self, Closure*);
|
197
|
-
|
198
|
-
#define TRAMPOLINE_CTX_MAGIC (0xfee1deadcafebabe)
|
199
|
-
#define TRAMPOLINE_FUN_MAGIC (0xfeedfacebeeff00d)
|
200
|
-
|
201
|
-
/*
|
202
|
-
* This is a hand-coded trampoline to speedup entry from ruby to the FFI translation
|
203
|
-
* layer for x86_64 arches.
|
204
|
-
*
|
205
|
-
* Since a ruby function has exactly 3 arguments, and the first 6 arguments are
|
206
|
-
* passed in registers for x86_64, we can tack on a context pointer by simply
|
207
|
-
* putting a value in %rcx, then jumping to the C trampoline code.
|
208
|
-
*
|
209
|
-
* This results in approx a 30% speedup for x86_64 FFI dispatch
|
210
|
-
*/
|
211
|
-
__asm__(
|
212
|
-
".text\n\t"
|
213
|
-
".globl ffi_trampoline\n\t"
|
214
|
-
".globl _ffi_trampoline\n\t"
|
215
|
-
"ffi_trampoline:\n\t"
|
216
|
-
"_ffi_trampoline:\n\t"
|
217
|
-
"movabsq $0xfee1deadcafebabe, %rcx\n\t"
|
218
|
-
"movabsq $0xfeedfacebeeff00d, %r11\n\t"
|
219
|
-
"jmpq *%r11\n\t"
|
220
|
-
".globl ffi_trampoline_end\n\t"
|
221
|
-
"ffi_trampoline_end:\n\t"
|
222
|
-
".globl _ffi_trampoline_end\n\t"
|
223
|
-
"_ffi_trampoline_end:\n\t"
|
224
|
-
);
|
225
|
-
|
226
|
-
static VALUE
|
227
|
-
custom_trampoline(int argc, VALUE* argv, VALUE self, Closure* handle)
|
228
|
-
{
|
229
|
-
FunctionType* fnInfo = (FunctionType *) handle->info;
|
230
|
-
VALUE rbReturnValue;
|
231
|
-
|
232
|
-
RB_GC_GUARD(rbReturnValue) = (*fnInfo->invoke)(argc, argv, handle->function, fnInfo);
|
233
|
-
RB_GC_GUARD(self);
|
234
|
-
|
235
|
-
return rbReturnValue;
|
236
|
-
}
|
237
|
-
|
238
|
-
#elif defined(__i386__) && 0
|
239
|
-
|
240
|
-
static VALUE custom_trampoline(caddr_t args, Closure*);
|
241
|
-
#define TRAMPOLINE_CTX_MAGIC (0xfee1dead)
|
242
|
-
#define TRAMPOLINE_FUN_MAGIC (0xbeefcafe)
|
243
|
-
|
244
|
-
/*
|
245
|
-
* This is a hand-coded trampoline to speed-up entry from ruby to the FFI translation
|
246
|
-
* layer for i386 arches.
|
247
|
-
*
|
248
|
-
* This does not make a discernible difference vs a raw closure, so for now,
|
249
|
-
* it is not enabled.
|
250
|
-
*/
|
251
|
-
__asm__(
|
252
|
-
".text\n\t"
|
253
|
-
".globl ffi_trampoline\n\t"
|
254
|
-
".globl _ffi_trampoline\n\t"
|
255
|
-
"ffi_trampoline:\n\t"
|
256
|
-
"_ffi_trampoline:\n\t"
|
257
|
-
"subl $12, %esp\n\t"
|
258
|
-
"leal 16(%esp), %eax\n\t"
|
259
|
-
"movl %eax, (%esp)\n\t"
|
260
|
-
"movl $0xfee1dead, 4(%esp)\n\t"
|
261
|
-
"movl $0xbeefcafe, %eax\n\t"
|
262
|
-
"call *%eax\n\t"
|
263
|
-
"addl $12, %esp\n\t"
|
264
|
-
"ret\n\t"
|
265
|
-
".globl ffi_trampoline_end\n\t"
|
266
|
-
"ffi_trampoline_end:\n\t"
|
267
|
-
".globl _ffi_trampoline_end\n\t"
|
268
|
-
"_ffi_trampoline_end:\n\t"
|
269
|
-
);
|
270
|
-
|
271
|
-
static VALUE
|
272
|
-
custom_trampoline(caddr_t args, Closure* handle)
|
68
|
+
MethodHandle*
|
69
|
+
rbffi_MethodHandle_Alloc(FunctionType* fnInfo, void* function)
|
273
70
|
{
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
#endif /* __x86_64__ else __i386__ */
|
279
|
-
|
280
|
-
extern void ffi_trampoline(int argc, VALUE* argv, VALUE self);
|
281
|
-
extern void ffi_trampoline_end(void);
|
282
|
-
static int trampoline_offsets(long *, long *);
|
283
|
-
|
284
|
-
static long trampoline_ctx_offset, trampoline_func_offset;
|
71
|
+
ffi_status ffiStatus;
|
72
|
+
MethodHandle* handle;
|
73
|
+
Closure* closure;
|
285
74
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
for (ptr = (caddr_t) &ffi_trampoline + off; ptr < (caddr_t) &ffi_trampoline_end; ++ptr) {
|
291
|
-
if (*(long *) ptr == value) {
|
292
|
-
return ptr - (caddr_t) &ffi_trampoline;
|
293
|
-
}
|
75
|
+
closure = rbffi_Closure_Alloc();
|
76
|
+
if (closure == NULL) {
|
77
|
+
rb_raise(rb_eNoMemError, "failed to allocate closure from pool");
|
78
|
+
return NULL;
|
294
79
|
}
|
80
|
+
closure->info = fnInfo;
|
81
|
+
closure->function = function;
|
295
82
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
{
|
302
|
-
|
303
|
-
|
304
|
-
return -1;
|
83
|
+
ffiStatus = ffi_prep_closure_loc(closure->libffi_closure,
|
84
|
+
&mh_cif, /* method signature */
|
85
|
+
attached_method_invoke,
|
86
|
+
closure, /* user_data for attached_method_invoke */
|
87
|
+
closure->libffi_trampoline);
|
88
|
+
if (ffiStatus != FFI_OK) {
|
89
|
+
rb_raise(rb_eRuntimeError, "ffi_prep_closure_loc failed. status=%#x", ffiStatus);
|
90
|
+
return false;
|
305
91
|
}
|
306
92
|
|
307
|
-
|
308
|
-
|
309
|
-
return -1;
|
310
|
-
}
|
93
|
+
handle = xcalloc(1, sizeof(*handle));
|
94
|
+
handle->closure = closure;
|
311
95
|
|
312
|
-
return
|
96
|
+
return handle;
|
313
97
|
}
|
314
98
|
|
315
|
-
|
316
|
-
|
99
|
+
void
|
100
|
+
rbffi_MethodHandle_Free(MethodHandle* handle)
|
317
101
|
{
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
/* Patch the context and function addresses into the stub code */
|
322
|
-
*(intptr_t *)(ptr + trampoline_ctx_offset) = (intptr_t) closure;
|
323
|
-
*(intptr_t *)(ptr + trampoline_func_offset) = (intptr_t) custom_trampoline;
|
324
|
-
|
325
|
-
return true;
|
102
|
+
if (handle != NULL) {
|
103
|
+
rbffi_Closure_Free(handle->closure);
|
104
|
+
}
|
326
105
|
}
|
327
106
|
|
328
|
-
|
329
|
-
|
107
|
+
void*
|
108
|
+
rbffi_MethodHandle_CodeAddress(MethodHandle* handle)
|
330
109
|
{
|
331
|
-
return
|
110
|
+
return handle->closure->libffi_trampoline;
|
332
111
|
}
|
333
112
|
|
334
|
-
#endif /* CUSTOM_TRAMPOLINE */
|
335
|
-
|
336
|
-
|
337
113
|
void
|
338
114
|
rbffi_MethodHandle_Init(VALUE module)
|
339
115
|
{
|
340
|
-
#ifndef CUSTOM_TRAMPOLINE
|
341
116
|
ffi_status ffiStatus;
|
342
|
-
#endif
|
343
117
|
|
344
|
-
defaultClosurePool = rbffi_ClosurePool_New((int) trampoline_size(), prep_trampoline, NULL);
|
345
|
-
|
346
|
-
#if defined(CUSTOM_TRAMPOLINE)
|
347
|
-
if (trampoline_offsets(&trampoline_ctx_offset, &trampoline_func_offset) != 0) {
|
348
|
-
rb_raise(rb_eFatal, "Could not locate offsets in trampoline code");
|
349
|
-
}
|
350
|
-
#else
|
351
118
|
ffiStatus = ffi_prep_cif(&mh_cif, FFI_DEFAULT_ABI, 3, &ffi_type_ulong,
|
352
119
|
methodHandleParamTypes);
|
353
120
|
if (ffiStatus != FFI_OK) {
|
354
121
|
rb_raise(rb_eFatal, "ffi_prep_cif failed. status=%#x", ffiStatus);
|
355
122
|
}
|
356
|
-
|
357
|
-
#endif
|
358
123
|
}
|
data/ext/ffi_c/extconf.rb
CHANGED
@@ -11,15 +11,15 @@ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
|
|
11
11
|
$CFLAGS.gsub!(/[\s+]-std=[^\s]+/, '')
|
12
12
|
# solaris 10 needs -c99 for <stdbool.h>
|
13
13
|
$CFLAGS << " -std=c99" if RbConfig::CONFIG['host_os'] =~ /solaris(!?2\.11)/
|
14
|
-
|
14
|
+
|
15
15
|
if ENV['RUBY_CC_VERSION'].nil? && (pkg_config("libffi") ||
|
16
16
|
have_header("ffi.h") ||
|
17
17
|
find_header("ffi.h", "/usr/local/include", "/usr/include/ffi"))
|
18
18
|
|
19
|
-
# We need at least ffi_call and
|
19
|
+
# We need at least ffi_call and ffi_closure_alloc
|
20
20
|
libffi_ok = have_library("ffi", "ffi_call", [ "ffi.h" ]) ||
|
21
21
|
have_library("libffi", "ffi_call", [ "ffi.h" ])
|
22
|
-
libffi_ok &&= have_func("
|
22
|
+
libffi_ok &&= have_func("ffi_closure_alloc")
|
23
23
|
|
24
24
|
# Check if the raw api is available.
|
25
25
|
$defs << "-DHAVE_RAW_API" if have_func("ffi_raw_call") && have_func("ffi_prep_raw_closure")
|
data/ext/ffi_c/ffi.c
CHANGED
@@ -46,7 +46,7 @@
|
|
46
46
|
#include "Types.h"
|
47
47
|
#include "LastError.h"
|
48
48
|
#include "Function.h"
|
49
|
-
#include "
|
49
|
+
#include "Closure.h"
|
50
50
|
#include "MethodHandle.h"
|
51
51
|
#include "Call.h"
|
52
52
|
#include "ArrayType.h"
|
@@ -79,7 +79,7 @@ Init_ffi_c(void)
|
|
79
79
|
rbffi_ArrayType_Init(moduleFFI);
|
80
80
|
rbffi_LastError_Init(moduleFFI);
|
81
81
|
rbffi_Call_Init(moduleFFI);
|
82
|
-
|
82
|
+
rbffi_Closure_Init(moduleFFI);
|
83
83
|
rbffi_MethodHandle_Init(moduleFFI);
|
84
84
|
rbffi_Platform_Init(moduleFFI);
|
85
85
|
rbffi_AbstractMemory_Init(moduleFFI);
|
data/ext/ffi_c/libffi.bsd.mk
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
# Makefile for BSD systems
|
4
4
|
#
|
5
5
|
|
6
|
-
INCFLAGS += -I${LIBFFI_BUILD_DIR}/include
|
7
6
|
LOCAL_LIBS += ${LIBFFI} -lpthread
|
8
7
|
|
9
8
|
LIBFFI_CFLAGS = ${FFI_MMAP_EXEC} -pthread
|
10
9
|
LIBFFI_BUILD_DIR = ${.CURDIR}/libffi-${arch}
|
10
|
+
INCFLAGS := -I${LIBFFI_BUILD_DIR}/include -I${INCFLAGS}
|
11
11
|
|
12
12
|
.if ${srcdir} == "."
|
13
13
|
LIBFFI_SRC_DIR := ${.CURDIR}/libffi
|
@@ -23,9 +23,9 @@ LIBFFI_CONFIGURE = ${LIBFFI_SRC_DIR}/configure --disable-static \
|
|
23
23
|
|
24
24
|
$(OBJS): ${LIBFFI}
|
25
25
|
|
26
|
-
$(LIBFFI):
|
26
|
+
$(LIBFFI):
|
27
27
|
@mkdir -p ${LIBFFI_BUILD_DIR}
|
28
|
-
@if [ ! -f $(
|
28
|
+
@if [ ! -f $(LIBFFI_SRC_DIR)/configure ]; then \
|
29
29
|
echo "Running autoreconf for libffi"; \
|
30
30
|
cd "$(LIBFFI_SRC_DIR)" && \
|
31
31
|
/bin/sh $(LIBFFI_AUTOGEN) > /dev/null; \
|