ffi 1.12.2 → 1.14.2
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/CHANGELOG.md +82 -0
- data/Gemfile +4 -2
- data/README.md +10 -2
- data/Rakefile +31 -43
- data/ext/ffi_c/AbstractMemory.c +24 -25
- data/ext/ffi_c/Buffer.c +4 -9
- data/ext/ffi_c/Call.c +3 -14
- data/ext/ffi_c/ClosurePool.c +75 -25
- data/ext/ffi_c/ClosurePool.h +3 -1
- data/ext/ffi_c/DynamicLibrary.c +1 -6
- data/ext/ffi_c/Function.c +15 -35
- data/ext/ffi_c/FunctionInfo.c +3 -8
- data/ext/ffi_c/LastError.c +2 -6
- data/ext/ffi_c/LongDouble.c +5 -3
- data/ext/ffi_c/LongDouble.h +0 -4
- data/ext/ffi_c/MemoryPointer.c +3 -8
- data/ext/ffi_c/MethodHandle.c +21 -31
- data/ext/ffi_c/MethodHandle.h +3 -2
- data/ext/ffi_c/Platform.c +3 -7
- data/ext/ffi_c/Pointer.c +25 -26
- data/ext/ffi_c/Struct.c +3 -6
- data/ext/ffi_c/StructByValue.c +2 -7
- data/ext/ffi_c/StructLayout.c +9 -7
- data/ext/ffi_c/Thread.c +0 -8
- data/ext/ffi_c/Thread.h +1 -9
- data/ext/ffi_c/Type.c +1 -1
- data/ext/ffi_c/Variadic.c +2 -7
- data/ext/ffi_c/compat.h +4 -0
- data/ext/ffi_c/extconf.rb +33 -23
- data/ext/ffi_c/libffi/.travis.yml +4 -0
- data/ext/ffi_c/libffi/.travis/bfin-sim.exp +1 -1
- data/ext/ffi_c/libffi/.travis/build.sh +4 -0
- data/ext/ffi_c/libffi/.travis/m32r-sim.exp +1 -1
- data/ext/ffi_c/libffi/.travis/moxie-sim.exp +1 -1
- data/ext/ffi_c/libffi/.travis/or1k-sim.exp +1 -1
- data/ext/ffi_c/libffi/.travis/powerpc-eabisim.exp +1 -1
- data/ext/ffi_c/libffi/.travis/wine-sim.exp +1 -1
- data/ext/ffi_c/libffi/Makefile.am +49 -58
- data/ext/ffi_c/libffi/README.md +11 -1
- data/ext/ffi_c/libffi/config.guess +552 -331
- data/ext/ffi_c/libffi/config.sub +1321 -1306
- data/ext/ffi_c/libffi/configure.ac +31 -10
- data/ext/ffi_c/libffi/configure.host +32 -20
- data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
- data/ext/ffi_c/libffi/doc/libffi.texi +997 -0
- data/ext/ffi_c/libffi/doc/version.texi +4 -0
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -1
- data/ext/ffi_c/libffi/include/ffi.h.in +8 -0
- data/ext/ffi_c/libffi/libffi.map.in +8 -12
- data/ext/ffi_c/libffi/libtool-version +1 -1
- data/ext/ffi_c/libffi/msvcc.sh +11 -11
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +51 -35
- data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +10 -5
- data/ext/ffi_c/libffi/src/aarch64/internal.h +1 -0
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +14 -3
- data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +1 -1
- data/ext/ffi_c/libffi/src/arm/ffi.c +22 -0
- data/ext/ffi_c/libffi/src/arm/sysv.S +4 -4
- data/ext/ffi_c/libffi/src/closures.c +33 -10
- data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
- data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
- data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
- data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
- data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
- data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
- data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
- data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +5 -1
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
- data/ext/ffi_c/libffi/src/pa/ffi.c +46 -91
- data/ext/ffi_c/libffi/src/pa/ffitarget.h +1 -6
- data/ext/ffi_c/libffi/src/pa/hpux32.S +4 -2
- data/ext/ffi_c/libffi/src/pa/linux.S +4 -2
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +13 -1
- data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +1 -1
- data/ext/ffi_c/libffi/src/powerpc/linux64.S +8 -0
- data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +13 -1
- data/ext/ffi_c/libffi/src/powerpc/sysv.S +5 -7
- data/ext/ffi_c/libffi/src/prep_cif.c +1 -1
- data/ext/ffi_c/libffi/src/x86/ffi.c +15 -6
- data/ext/ffi_c/libffi/src/x86/ffi64.c +17 -8
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +15 -2
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +15 -8
- data/ext/ffi_c/libffi/src/x86/sysv.S +15 -6
- data/ext/ffi_c/libffi/src/x86/unix64.S +59 -4
- data/ext/ffi_c/libffi/src/x86/win64.S +7 -3
- data/ext/ffi_c/libffi/src/x86/win64_intel.S +3 -2
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +22 -2
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2 -2
- data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +2 -0
- data/ffi.gemspec +2 -2
- data/lib/ffi.rb +10 -2
- data/lib/ffi/abstract_memory.rb +44 -0
- data/lib/ffi/autopointer.rb +1 -1
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/io.rb +3 -3
- data/lib/ffi/library.rb +6 -2
- data/lib/ffi/managedstruct.rb +2 -2
- data/lib/ffi/platform.rb +21 -8
- data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
- data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
- data/lib/ffi/platform/arm-linux/types.conf +32 -4
- data/lib/ffi/platform/i386-windows/types.conf +26 -79
- data/lib/ffi/platform/powerpc-linux/types.conf +32 -2
- data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
- data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
- data/lib/ffi/platform/x86_64-darwin/types.conf +4 -0
- data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +4 -22
- data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
- data/lib/ffi/platform/x86_64-linux/types.conf +21 -0
- data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
- data/lib/ffi/platform/x86_64-windows/types.conf +10 -78
- data/lib/ffi/pointer.rb +21 -14
- data/lib/ffi/struct.rb +8 -2
- data/lib/ffi/tools/types_generator.rb +2 -0
- data/lib/ffi/variadic.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- data/samples/getlogin.rb +1 -1
- data/samples/getpid.rb +1 -1
- data/samples/gettimeofday.rb +8 -8
- data/samples/hello.rb +2 -1
- data/samples/inotify.rb +1 -1
- data/samples/pty.rb +1 -2
- data/samples/qsort.rb +0 -1
- metadata +18 -12
- data/.appveyor.yml +0 -27
- data/.gitignore +0 -25
- data/.gitmodules +0 -4
- data/.travis.yml +0 -44
- data/.yardopts +0 -5
- data/ext/ffi_c/win32/stdbool.h +0 -8
- data/ext/ffi_c/win32/stdint.h +0 -201
- data/samples/sample_helper.rb +0 -6
data/ext/ffi_c/Buffer.c
CHANGED
|
@@ -28,13 +28,8 @@
|
|
|
28
28
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
# include <stdbool.h>
|
|
34
|
-
#else
|
|
35
|
-
# include "win32/stdbool.h"
|
|
36
|
-
# include "win32/stdint.h"
|
|
37
|
-
#endif
|
|
31
|
+
#include <stdint.h>
|
|
32
|
+
#include <stdbool.h>
|
|
38
33
|
#include <limits.h>
|
|
39
34
|
#include <ruby.h>
|
|
40
35
|
#include "rbffi.h"
|
|
@@ -114,7 +109,7 @@ buffer_initialize(int argc, VALUE* argv, VALUE self)
|
|
|
114
109
|
}
|
|
115
110
|
|
|
116
111
|
/* ensure the memory is aligned on at least a 8 byte boundary */
|
|
117
|
-
p->memory.address = (void *) (((uintptr_t) p->data.storage + 0x7) & (uintptr_t) ~
|
|
112
|
+
p->memory.address = (void *) (((uintptr_t) p->data.storage + 0x7) & (uintptr_t) ~0x7ULL);
|
|
118
113
|
|
|
119
114
|
if (p->memory.size > 0 && (nargs < 3 || RTEST(rbClear))) {
|
|
120
115
|
memset(p->memory.address, 0, p->memory.size);
|
|
@@ -154,7 +149,7 @@ buffer_initialize_copy(VALUE self, VALUE other)
|
|
|
154
149
|
return Qnil;
|
|
155
150
|
}
|
|
156
151
|
|
|
157
|
-
dst->memory.address = (void *) (((uintptr_t) dst->data.storage + 0x7) & (uintptr_t) ~
|
|
152
|
+
dst->memory.address = (void *) (((uintptr_t) dst->data.storage + 0x7) & (uintptr_t) ~0x7ULL);
|
|
158
153
|
dst->memory.size = src->size;
|
|
159
154
|
dst->memory.typeSize = src->typeSize;
|
|
160
155
|
|
data/ext/ffi_c/Call.c
CHANGED
|
@@ -34,13 +34,8 @@
|
|
|
34
34
|
#endif
|
|
35
35
|
#include <sys/types.h>
|
|
36
36
|
#include <stdio.h>
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
# include <stdbool.h>
|
|
40
|
-
#else
|
|
41
|
-
# include "win32/stdbool.h"
|
|
42
|
-
# include "win32/stdint.h"
|
|
43
|
-
#endif
|
|
37
|
+
#include <stdint.h>
|
|
38
|
+
#include <stdbool.h>
|
|
44
39
|
#include <errno.h>
|
|
45
40
|
#include <ruby.h>
|
|
46
41
|
#include <ruby/thread.h>
|
|
@@ -339,13 +334,7 @@ static void *
|
|
|
339
334
|
call_blocking_function(void* data)
|
|
340
335
|
{
|
|
341
336
|
rbffi_blocking_call_t* b = (rbffi_blocking_call_t *) data;
|
|
342
|
-
#ifndef HAVE_RUBY_THREAD_HAS_GVL_P
|
|
343
|
-
b->frame->has_gvl = false;
|
|
344
|
-
#endif
|
|
345
337
|
ffi_call(&b->cif, FFI_FN(b->function), b->retval, b->ffiValues);
|
|
346
|
-
#ifndef HAVE_RUBY_THREAD_HAS_GVL_P
|
|
347
|
-
b->frame->has_gvl = true;
|
|
348
|
-
#endif
|
|
349
338
|
|
|
350
339
|
return NULL;
|
|
351
340
|
}
|
|
@@ -353,7 +342,7 @@ call_blocking_function(void* data)
|
|
|
353
342
|
VALUE
|
|
354
343
|
rbffi_do_blocking_call(VALUE data)
|
|
355
344
|
{
|
|
356
|
-
rb_thread_call_without_gvl(call_blocking_function, (void*)data, (
|
|
345
|
+
rb_thread_call_without_gvl(call_blocking_function, (void*)data, (rb_unblock_function_t *) -1, NULL);
|
|
357
346
|
|
|
358
347
|
return Qnil;
|
|
359
348
|
}
|
data/ext/ffi_c/ClosurePool.c
CHANGED
|
@@ -34,13 +34,8 @@
|
|
|
34
34
|
# include <sys/mman.h>
|
|
35
35
|
#endif
|
|
36
36
|
#include <stdio.h>
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
# include <stdbool.h>
|
|
40
|
-
#else
|
|
41
|
-
# include "win32/stdbool.h"
|
|
42
|
-
# include "win32/stdint.h"
|
|
43
|
-
#endif
|
|
37
|
+
#include <stdint.h>
|
|
38
|
+
#include <stdbool.h>
|
|
44
39
|
#if defined(__CYGWIN__) || !defined(_WIN32)
|
|
45
40
|
# include <unistd.h>
|
|
46
41
|
#else
|
|
@@ -51,9 +46,6 @@
|
|
|
51
46
|
#include <errno.h>
|
|
52
47
|
#include <ruby.h>
|
|
53
48
|
|
|
54
|
-
#if defined(_MSC_VER) && !defined(INT8_MIN)
|
|
55
|
-
# include "win32/stdint.h"
|
|
56
|
-
#endif
|
|
57
49
|
#include <ffi.h>
|
|
58
50
|
#include "rbffi.h"
|
|
59
51
|
#include "compat.h"
|
|
@@ -66,13 +58,9 @@
|
|
|
66
58
|
|
|
67
59
|
#include "ClosurePool.h"
|
|
68
60
|
|
|
69
|
-
|
|
70
61
|
#ifndef roundup
|
|
71
62
|
# define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
|
|
72
63
|
#endif
|
|
73
|
-
#ifdef _WIN32
|
|
74
|
-
typedef char* caddr_t;
|
|
75
|
-
#endif
|
|
76
64
|
|
|
77
65
|
typedef struct Memory {
|
|
78
66
|
void* code;
|
|
@@ -96,7 +84,7 @@ static bool freePage(void *);
|
|
|
96
84
|
static bool protectPage(void *);
|
|
97
85
|
|
|
98
86
|
ClosurePool*
|
|
99
|
-
rbffi_ClosurePool_New(int closureSize,
|
|
87
|
+
rbffi_ClosurePool_New(int closureSize,
|
|
100
88
|
bool (*prep)(void* ctx, void *code, Closure* closure, char* errbuf, size_t errbufsize),
|
|
101
89
|
void* ctx)
|
|
102
90
|
{
|
|
@@ -107,7 +95,7 @@ rbffi_ClosurePool_New(int closureSize,
|
|
|
107
95
|
pool->ctx = ctx;
|
|
108
96
|
pool->prep = prep;
|
|
109
97
|
pool->refcnt = 1;
|
|
110
|
-
|
|
98
|
+
|
|
111
99
|
return pool;
|
|
112
100
|
}
|
|
113
101
|
|
|
@@ -115,10 +103,14 @@ void
|
|
|
115
103
|
cleanup_closure_pool(ClosurePool* pool)
|
|
116
104
|
{
|
|
117
105
|
Memory* memory;
|
|
118
|
-
|
|
106
|
+
|
|
119
107
|
for (memory = pool->blocks; memory != NULL; ) {
|
|
120
108
|
Memory* next = memory->next;
|
|
109
|
+
#if !USE_FFI_ALLOC
|
|
121
110
|
freePage(memory->code);
|
|
111
|
+
#else
|
|
112
|
+
ffi_closure_free(memory->code);
|
|
113
|
+
#endif
|
|
122
114
|
free(memory->data);
|
|
123
115
|
free(memory);
|
|
124
116
|
memory = next;
|
|
@@ -137,12 +129,14 @@ rbffi_ClosurePool_Free(ClosurePool* pool)
|
|
|
137
129
|
}
|
|
138
130
|
}
|
|
139
131
|
|
|
132
|
+
#if !USE_FFI_ALLOC
|
|
133
|
+
|
|
140
134
|
Closure*
|
|
141
135
|
rbffi_Closure_Alloc(ClosurePool* pool)
|
|
142
136
|
{
|
|
143
137
|
Closure *list = NULL;
|
|
144
138
|
Memory* block = NULL;
|
|
145
|
-
|
|
139
|
+
void *code = NULL;
|
|
146
140
|
char errmsg[256];
|
|
147
141
|
int nclosures;
|
|
148
142
|
long trampolineSize;
|
|
@@ -152,7 +146,7 @@ rbffi_Closure_Alloc(ClosurePool* pool)
|
|
|
152
146
|
Closure* closure = pool->list;
|
|
153
147
|
pool->list = pool->list->next;
|
|
154
148
|
pool->refcnt++;
|
|
155
|
-
|
|
149
|
+
|
|
156
150
|
return closure;
|
|
157
151
|
}
|
|
158
152
|
|
|
@@ -161,17 +155,18 @@ rbffi_Closure_Alloc(ClosurePool* pool)
|
|
|
161
155
|
block = calloc(1, sizeof(*block));
|
|
162
156
|
list = calloc(nclosures, sizeof(*list));
|
|
163
157
|
code = allocatePage();
|
|
164
|
-
|
|
158
|
+
|
|
165
159
|
if (block == NULL || list == NULL || code == NULL) {
|
|
166
160
|
snprintf(errmsg, sizeof(errmsg), "failed to allocate a page. errno=%d (%s)", errno, strerror(errno));
|
|
167
161
|
goto error;
|
|
168
162
|
}
|
|
169
|
-
|
|
163
|
+
|
|
170
164
|
for (i = 0; i < nclosures; ++i) {
|
|
171
165
|
Closure* closure = &list[i];
|
|
172
166
|
closure->next = &list[i + 1];
|
|
173
167
|
closure->pool = pool;
|
|
174
|
-
closure->code = (code + (i * trampolineSize));
|
|
168
|
+
closure->code = ((char *)code + (i * trampolineSize));
|
|
169
|
+
closure->pcl = closure->code;
|
|
175
170
|
|
|
176
171
|
if (!(*pool->prep)(pool->ctx, closure->code, closure, errmsg, sizeof(errmsg))) {
|
|
177
172
|
goto error;
|
|
@@ -202,12 +197,63 @@ error:
|
|
|
202
197
|
if (code != NULL) {
|
|
203
198
|
freePage(code);
|
|
204
199
|
}
|
|
205
|
-
|
|
200
|
+
|
|
206
201
|
|
|
207
202
|
rb_raise(rb_eRuntimeError, "%s", errmsg);
|
|
208
203
|
return NULL;
|
|
209
204
|
}
|
|
210
205
|
|
|
206
|
+
#else
|
|
207
|
+
|
|
208
|
+
Closure*
|
|
209
|
+
rbffi_Closure_Alloc(ClosurePool* pool)
|
|
210
|
+
{
|
|
211
|
+
Closure *closure = NULL;
|
|
212
|
+
Memory* block = NULL;
|
|
213
|
+
void *code = NULL;
|
|
214
|
+
void *pcl = NULL;
|
|
215
|
+
char errmsg[256];
|
|
216
|
+
|
|
217
|
+
block = calloc(1, sizeof(*block));
|
|
218
|
+
closure = calloc(1, sizeof(*closure));
|
|
219
|
+
pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
|
220
|
+
|
|
221
|
+
if (block == NULL || closure == NULL || pcl == NULL) {
|
|
222
|
+
snprintf(errmsg, sizeof(errmsg), "failed to allocate a page. errno=%d (%s)", errno, strerror(errno));
|
|
223
|
+
goto error;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
closure->pool = pool;
|
|
227
|
+
closure->code = code;
|
|
228
|
+
closure->pcl = pcl;
|
|
229
|
+
|
|
230
|
+
if (!(*pool->prep)(pool->ctx, closure->code, closure, errmsg, sizeof(errmsg))) {
|
|
231
|
+
goto error;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* Track the allocated page + Closure memory area */
|
|
235
|
+
block->data = closure;
|
|
236
|
+
block->code = pcl;
|
|
237
|
+
pool->blocks = block;
|
|
238
|
+
|
|
239
|
+
/* Thread the new block onto the free list, apart from the first one. */
|
|
240
|
+
pool->refcnt++;
|
|
241
|
+
|
|
242
|
+
return closure;
|
|
243
|
+
|
|
244
|
+
error:
|
|
245
|
+
free(block);
|
|
246
|
+
free(closure);
|
|
247
|
+
if (pcl != NULL) {
|
|
248
|
+
ffi_closure_free(pcl);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
rb_raise(rb_eRuntimeError, "%s", errmsg);
|
|
252
|
+
return NULL;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
#endif /* !USE_FFI_ALLOC */
|
|
256
|
+
|
|
211
257
|
void
|
|
212
258
|
rbffi_Closure_Free(Closure* closure)
|
|
213
259
|
{
|
|
@@ -243,14 +289,16 @@ getPageSize()
|
|
|
243
289
|
#endif
|
|
244
290
|
}
|
|
245
291
|
|
|
292
|
+
#if !USE_FFI_ALLOC
|
|
293
|
+
|
|
246
294
|
static void*
|
|
247
295
|
allocatePage(void)
|
|
248
296
|
{
|
|
249
297
|
#if !defined(__CYGWIN__) && (defined(_WIN32) || defined(__WIN32__))
|
|
250
298
|
return VirtualAlloc(NULL, pageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
251
299
|
#else
|
|
252
|
-
|
|
253
|
-
return (page != (
|
|
300
|
+
void *page = mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
|
301
|
+
return (page != (void *) -1) ? page : NULL;
|
|
254
302
|
#endif
|
|
255
303
|
}
|
|
256
304
|
|
|
@@ -275,6 +323,8 @@ protectPage(void* page)
|
|
|
275
323
|
#endif
|
|
276
324
|
}
|
|
277
325
|
|
|
326
|
+
#endif /* !USE_FFI_ALLOC */
|
|
327
|
+
|
|
278
328
|
void
|
|
279
329
|
rbffi_ClosurePool_Init(VALUE module)
|
|
280
330
|
{
|
data/ext/ffi_c/ClosurePool.h
CHANGED
|
@@ -35,7 +35,9 @@ typedef struct Closure_ Closure;
|
|
|
35
35
|
struct Closure_ {
|
|
36
36
|
void* info; /* opaque handle for storing closure-instance specific data */
|
|
37
37
|
void* function; /* closure-instance specific function, called by custom trampoline */
|
|
38
|
-
void* code; /*
|
|
38
|
+
void* code; /* Executable address for the native trampoline code location */
|
|
39
|
+
void* pcl; /* Writeable address for the native trampoline code location */
|
|
40
|
+
|
|
39
41
|
struct ClosurePool_* pool;
|
|
40
42
|
Closure* next;
|
|
41
43
|
};
|
data/ext/ffi_c/DynamicLibrary.c
CHANGED
|
@@ -29,9 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
#include <sys/types.h>
|
|
31
31
|
#include <stdio.h>
|
|
32
|
-
#
|
|
33
|
-
# include <stdint.h>
|
|
34
|
-
#endif
|
|
32
|
+
#include <stdint.h>
|
|
35
33
|
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(__CYGWIN__)
|
|
36
34
|
# include <winsock2.h>
|
|
37
35
|
# define _WINSOCKAPI_
|
|
@@ -41,9 +39,6 @@
|
|
|
41
39
|
# include <dlfcn.h>
|
|
42
40
|
#endif
|
|
43
41
|
#include <ruby.h>
|
|
44
|
-
#if defined(_MSC_VER) && !defined(INT8_MIN)
|
|
45
|
-
# include "win32/stdint.h"
|
|
46
|
-
#endif
|
|
47
42
|
|
|
48
43
|
#include <ffi.h>
|
|
49
44
|
|
data/ext/ffi_c/Function.c
CHANGED
|
@@ -37,15 +37,8 @@
|
|
|
37
37
|
#endif
|
|
38
38
|
|
|
39
39
|
#include <stdio.h>
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
# include <stdbool.h>
|
|
43
|
-
#else
|
|
44
|
-
# include "win32/stdbool.h"
|
|
45
|
-
# if !defined(INT8_MIN)
|
|
46
|
-
# include "win32/stdint.h"
|
|
47
|
-
# endif
|
|
48
|
-
#endif
|
|
40
|
+
#include <stdint.h>
|
|
41
|
+
#include <stdbool.h>
|
|
49
42
|
#include <ruby.h>
|
|
50
43
|
#include <ruby/thread.h>
|
|
51
44
|
|
|
@@ -99,26 +92,8 @@ static VALUE async_cb_event(void *);
|
|
|
99
92
|
static VALUE async_cb_call(void *);
|
|
100
93
|
#endif
|
|
101
94
|
|
|
102
|
-
#ifdef HAVE_RUBY_THREAD_HAS_GVL_P
|
|
103
95
|
extern int ruby_thread_has_gvl_p(void);
|
|
104
|
-
#define rbffi_thread_has_gvl_p(frame) ruby_thread_has_gvl_p()
|
|
105
|
-
#else
|
|
106
|
-
static int rbffi_thread_has_gvl_p(rbffi_frame_t *frame)
|
|
107
|
-
{
|
|
108
|
-
return frame != NULL && frame->has_gvl;
|
|
109
|
-
}
|
|
110
|
-
#endif
|
|
111
|
-
|
|
112
|
-
#ifdef HAVE_RUBY_NATIVE_THREAD_P
|
|
113
96
|
extern int ruby_native_thread_p(void);
|
|
114
|
-
#define rbffi_native_thread_p(frame) ruby_native_thread_p()
|
|
115
|
-
#else
|
|
116
|
-
static int rbffi_native_thread_p(rbffi_frame_t *frame)
|
|
117
|
-
{
|
|
118
|
-
return frame != NULL;
|
|
119
|
-
}
|
|
120
|
-
#endif
|
|
121
|
-
|
|
122
97
|
|
|
123
98
|
VALUE rbffi_FunctionClass = Qnil;
|
|
124
99
|
|
|
@@ -274,11 +249,11 @@ VALUE
|
|
|
274
249
|
rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
|
|
275
250
|
{
|
|
276
251
|
VALUE callback, cbref, cbTable;
|
|
277
|
-
Function* fp;
|
|
278
252
|
|
|
279
253
|
cbref = RTEST(rb_ivar_defined(proc, id_cb_ref)) ? rb_ivar_get(proc, id_cb_ref) : Qnil;
|
|
280
254
|
/* If the first callback reference has the same function function signature, use it */
|
|
281
255
|
if (cbref != Qnil && CLASS_OF(cbref) == rbffi_FunctionClass) {
|
|
256
|
+
Function* fp;
|
|
282
257
|
Data_Get_Struct(cbref, Function, fp);
|
|
283
258
|
if (fp->rbFunctionInfo == rbFunctionInfo) {
|
|
284
259
|
return cbref;
|
|
@@ -297,8 +272,10 @@ rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
|
|
|
297
272
|
rb_ivar_set(proc, id_cb_ref, callback);
|
|
298
273
|
} else {
|
|
299
274
|
/* The proc instance has been used as more than one type of callback, store extras in a hash */
|
|
300
|
-
cbTable
|
|
301
|
-
|
|
275
|
+
if(cbTable == Qnil) {
|
|
276
|
+
cbTable = rb_hash_new();
|
|
277
|
+
rb_ivar_set(proc, id_cbtable, cbTable);
|
|
278
|
+
}
|
|
302
279
|
rb_hash_aset(cbTable, rbFunctionInfo, callback);
|
|
303
280
|
}
|
|
304
281
|
|
|
@@ -476,8 +453,8 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
|
|
476
453
|
|
|
477
454
|
if (cb.frame != NULL) cb.frame->exc = Qnil;
|
|
478
455
|
|
|
479
|
-
if (
|
|
480
|
-
if(
|
|
456
|
+
if (ruby_native_thread_p()) {
|
|
457
|
+
if(ruby_thread_has_gvl_p()) {
|
|
481
458
|
callback_with_gvl(&cb);
|
|
482
459
|
} else {
|
|
483
460
|
rb_thread_call_with_gvl(callback_with_gvl, &cb);
|
|
@@ -721,7 +698,7 @@ invoke_callback(VALUE data)
|
|
|
721
698
|
param = rb_float_new(*(double *) parameters[i]);
|
|
722
699
|
break;
|
|
723
700
|
case NATIVE_LONGDOUBLE:
|
|
724
|
-
|
|
701
|
+
param = rbffi_longdouble_new(*(long double *) parameters[i]);
|
|
725
702
|
break;
|
|
726
703
|
case NATIVE_STRING:
|
|
727
704
|
param = (*(void **) parameters[i] != NULL) ? rb_str_new2(*(char **) parameters[i]) : Qnil;
|
|
@@ -793,6 +770,9 @@ invoke_callback(VALUE data)
|
|
|
793
770
|
case NATIVE_FLOAT64:
|
|
794
771
|
*((double *) retval) = NUM2DBL(rbReturnValue);
|
|
795
772
|
break;
|
|
773
|
+
case NATIVE_LONGDOUBLE:
|
|
774
|
+
*((long double *) retval) = rbffi_num2longdouble(rbReturnValue);
|
|
775
|
+
break;
|
|
796
776
|
case NATIVE_POINTER:
|
|
797
777
|
if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
|
|
798
778
|
*((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
|
|
@@ -864,9 +844,9 @@ callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errm
|
|
|
864
844
|
FunctionType* fnInfo = (FunctionType *) ctx;
|
|
865
845
|
ffi_status ffiStatus;
|
|
866
846
|
|
|
867
|
-
ffiStatus =
|
|
847
|
+
ffiStatus = ffi_prep_closure_loc(closure->pcl, &fnInfo->ffi_cif, callback_invoke, closure, code);
|
|
868
848
|
if (ffiStatus != FFI_OK) {
|
|
869
|
-
snprintf(errmsg, errmsgsize, "
|
|
849
|
+
snprintf(errmsg, errmsgsize, "ffi_prep_closure_loc failed. status=%#x", ffiStatus);
|
|
870
850
|
return false;
|
|
871
851
|
}
|
|
872
852
|
|
data/ext/ffi_c/FunctionInfo.c
CHANGED
|
@@ -33,12 +33,8 @@
|
|
|
33
33
|
#include <sys/types.h>
|
|
34
34
|
#include <stdio.h>
|
|
35
35
|
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
# include <stdbool.h>
|
|
39
|
-
#else
|
|
40
|
-
# include "win32/stdbool.h"
|
|
41
|
-
#endif
|
|
36
|
+
#include <stdint.h>
|
|
37
|
+
#include <stdbool.h>
|
|
42
38
|
|
|
43
39
|
#include <errno.h>
|
|
44
40
|
#include <ruby.h>
|
|
@@ -172,7 +168,7 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
|
|
|
172
168
|
VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
|
|
173
169
|
rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
|
|
174
170
|
}
|
|
175
|
-
|
|
171
|
+
|
|
176
172
|
if (rb_obj_is_kind_of(fnInfo->rbReturnType, rbffi_StructByValueClass)) {
|
|
177
173
|
fnInfo->hasStruct = true;
|
|
178
174
|
}
|
|
@@ -180,7 +176,6 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
|
|
|
180
176
|
Data_Get_Struct(fnInfo->rbReturnType, Type, fnInfo->returnType);
|
|
181
177
|
fnInfo->ffiReturnType = fnInfo->returnType->ffiType;
|
|
182
178
|
|
|
183
|
-
|
|
184
179
|
#if defined(X86_WIN32)
|
|
185
180
|
rbConventionStr = (rbConvention != Qnil) ? rb_funcall2(rbConvention, rb_intern("to_s"), 0, NULL) : Qnil;
|
|
186
181
|
fnInfo->abi = (rbConventionStr != Qnil && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0)
|