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.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -0
  3. data/Gemfile +4 -2
  4. data/README.md +10 -2
  5. data/Rakefile +31 -43
  6. data/ext/ffi_c/AbstractMemory.c +24 -25
  7. data/ext/ffi_c/Buffer.c +4 -9
  8. data/ext/ffi_c/Call.c +3 -14
  9. data/ext/ffi_c/ClosurePool.c +75 -25
  10. data/ext/ffi_c/ClosurePool.h +3 -1
  11. data/ext/ffi_c/DynamicLibrary.c +1 -6
  12. data/ext/ffi_c/Function.c +15 -35
  13. data/ext/ffi_c/FunctionInfo.c +3 -8
  14. data/ext/ffi_c/LastError.c +2 -6
  15. data/ext/ffi_c/LongDouble.c +5 -3
  16. data/ext/ffi_c/LongDouble.h +0 -4
  17. data/ext/ffi_c/MemoryPointer.c +3 -8
  18. data/ext/ffi_c/MethodHandle.c +21 -31
  19. data/ext/ffi_c/MethodHandle.h +3 -2
  20. data/ext/ffi_c/Platform.c +3 -7
  21. data/ext/ffi_c/Pointer.c +25 -26
  22. data/ext/ffi_c/Struct.c +3 -6
  23. data/ext/ffi_c/StructByValue.c +2 -7
  24. data/ext/ffi_c/StructLayout.c +9 -7
  25. data/ext/ffi_c/Thread.c +0 -8
  26. data/ext/ffi_c/Thread.h +1 -9
  27. data/ext/ffi_c/Type.c +1 -1
  28. data/ext/ffi_c/Variadic.c +2 -7
  29. data/ext/ffi_c/compat.h +4 -0
  30. data/ext/ffi_c/extconf.rb +33 -23
  31. data/ext/ffi_c/libffi/.travis.yml +4 -0
  32. data/ext/ffi_c/libffi/.travis/bfin-sim.exp +1 -1
  33. data/ext/ffi_c/libffi/.travis/build.sh +4 -0
  34. data/ext/ffi_c/libffi/.travis/m32r-sim.exp +1 -1
  35. data/ext/ffi_c/libffi/.travis/moxie-sim.exp +1 -1
  36. data/ext/ffi_c/libffi/.travis/or1k-sim.exp +1 -1
  37. data/ext/ffi_c/libffi/.travis/powerpc-eabisim.exp +1 -1
  38. data/ext/ffi_c/libffi/.travis/wine-sim.exp +1 -1
  39. data/ext/ffi_c/libffi/Makefile.am +49 -58
  40. data/ext/ffi_c/libffi/README.md +11 -1
  41. data/ext/ffi_c/libffi/config.guess +552 -331
  42. data/ext/ffi_c/libffi/config.sub +1321 -1306
  43. data/ext/ffi_c/libffi/configure.ac +31 -10
  44. data/ext/ffi_c/libffi/configure.host +32 -20
  45. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  46. data/ext/ffi_c/libffi/doc/libffi.texi +997 -0
  47. data/ext/ffi_c/libffi/doc/version.texi +4 -0
  48. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -1
  49. data/ext/ffi_c/libffi/include/ffi.h.in +8 -0
  50. data/ext/ffi_c/libffi/libffi.map.in +8 -12
  51. data/ext/ffi_c/libffi/libtool-version +1 -1
  52. data/ext/ffi_c/libffi/msvcc.sh +11 -11
  53. data/ext/ffi_c/libffi/src/aarch64/ffi.c +51 -35
  54. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +10 -5
  55. data/ext/ffi_c/libffi/src/aarch64/internal.h +1 -0
  56. data/ext/ffi_c/libffi/src/aarch64/sysv.S +14 -3
  57. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +1 -1
  58. data/ext/ffi_c/libffi/src/arm/ffi.c +22 -0
  59. data/ext/ffi_c/libffi/src/arm/sysv.S +4 -4
  60. data/ext/ffi_c/libffi/src/closures.c +33 -10
  61. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  62. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  63. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  64. data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
  65. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  66. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  67. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  68. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  69. data/ext/ffi_c/libffi/src/mips/ffi.c +5 -1
  70. data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
  71. data/ext/ffi_c/libffi/src/pa/ffi.c +46 -91
  72. data/ext/ffi_c/libffi/src/pa/ffitarget.h +1 -6
  73. data/ext/ffi_c/libffi/src/pa/hpux32.S +4 -2
  74. data/ext/ffi_c/libffi/src/pa/linux.S +4 -2
  75. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +13 -1
  76. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +1 -1
  77. data/ext/ffi_c/libffi/src/powerpc/linux64.S +8 -0
  78. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +13 -1
  79. data/ext/ffi_c/libffi/src/powerpc/sysv.S +5 -7
  80. data/ext/ffi_c/libffi/src/prep_cif.c +1 -1
  81. data/ext/ffi_c/libffi/src/x86/ffi.c +15 -6
  82. data/ext/ffi_c/libffi/src/x86/ffi64.c +17 -8
  83. data/ext/ffi_c/libffi/src/x86/ffitarget.h +15 -2
  84. data/ext/ffi_c/libffi/src/x86/ffiw64.c +15 -8
  85. data/ext/ffi_c/libffi/src/x86/sysv.S +15 -6
  86. data/ext/ffi_c/libffi/src/x86/unix64.S +59 -4
  87. data/ext/ffi_c/libffi/src/x86/win64.S +7 -3
  88. data/ext/ffi_c/libffi/src/x86/win64_intel.S +3 -2
  89. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +22 -2
  90. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +4 -4
  91. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2 -2
  92. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +2 -0
  93. data/ffi.gemspec +2 -2
  94. data/lib/ffi.rb +10 -2
  95. data/lib/ffi/abstract_memory.rb +44 -0
  96. data/lib/ffi/autopointer.rb +1 -1
  97. data/lib/ffi/ffi.rb +1 -0
  98. data/lib/ffi/io.rb +3 -3
  99. data/lib/ffi/library.rb +6 -2
  100. data/lib/ffi/managedstruct.rb +2 -2
  101. data/lib/ffi/platform.rb +21 -8
  102. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  103. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  104. data/lib/ffi/platform/arm-linux/types.conf +32 -4
  105. data/lib/ffi/platform/i386-windows/types.conf +26 -79
  106. data/lib/ffi/platform/powerpc-linux/types.conf +32 -2
  107. data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
  108. data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
  109. data/lib/ffi/platform/x86_64-darwin/types.conf +4 -0
  110. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +4 -22
  111. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  112. data/lib/ffi/platform/x86_64-linux/types.conf +21 -0
  113. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  114. data/lib/ffi/platform/x86_64-windows/types.conf +10 -78
  115. data/lib/ffi/pointer.rb +21 -14
  116. data/lib/ffi/struct.rb +8 -2
  117. data/lib/ffi/tools/types_generator.rb +2 -0
  118. data/lib/ffi/variadic.rb +1 -1
  119. data/lib/ffi/version.rb +1 -1
  120. data/samples/getlogin.rb +1 -1
  121. data/samples/getpid.rb +1 -1
  122. data/samples/gettimeofday.rb +8 -8
  123. data/samples/hello.rb +2 -1
  124. data/samples/inotify.rb +1 -1
  125. data/samples/pty.rb +1 -2
  126. data/samples/qsort.rb +0 -1
  127. metadata +18 -12
  128. data/.appveyor.yml +0 -27
  129. data/.gitignore +0 -25
  130. data/.gitmodules +0 -4
  131. data/.travis.yml +0 -44
  132. data/.yardopts +0 -5
  133. data/ext/ffi_c/win32/stdbool.h +0 -8
  134. data/ext/ffi_c/win32/stdint.h +0 -201
  135. data/samples/sample_helper.rb +0 -6
@@ -28,13 +28,8 @@
28
28
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
  */
30
30
 
31
- #ifndef _MSC_VER
32
- # include <stdint.h>
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) ~0x7UL);
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) ~0x7UL);
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
 
@@ -34,13 +34,8 @@
34
34
  #endif
35
35
  #include <sys/types.h>
36
36
  #include <stdio.h>
37
- #ifndef _MSC_VER
38
- # include <stdint.h>
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, (void *) -1, NULL);
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
  }
@@ -34,13 +34,8 @@
34
34
  # include <sys/mman.h>
35
35
  #endif
36
36
  #include <stdio.h>
37
- #ifndef _MSC_VER
38
- # include <stdint.h>
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
- caddr_t code = NULL;
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
- caddr_t page = mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
253
- return (page != (caddr_t) -1) ? page : NULL;
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
  {
@@ -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; /* The native trampoline code location */
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
  };
@@ -29,9 +29,7 @@
29
29
 
30
30
  #include <sys/types.h>
31
31
  #include <stdio.h>
32
- #ifndef _MSC_VER
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
 
@@ -37,15 +37,8 @@
37
37
  #endif
38
38
 
39
39
  #include <stdio.h>
40
- #ifndef _MSC_VER
41
- # include <stdint.h>
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 = rb_hash_new();
301
- rb_ivar_set(proc, id_cbtable, cbTable);
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 (rbffi_native_thread_p(cb.frame)) {
480
- if(rbffi_thread_has_gvl_p(cb.frame)) {
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
- param = rbffi_longdouble_new(*(long double *) parameters[i]);
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 = ffi_prep_closure(code, &fnInfo->ffi_cif, callback_invoke, closure);
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, "ffi_prep_closure failed. status=%#x", ffiStatus);
849
+ snprintf(errmsg, errmsgsize, "ffi_prep_closure_loc failed. status=%#x", ffiStatus);
870
850
  return false;
871
851
  }
872
852
 
@@ -33,12 +33,8 @@
33
33
  #include <sys/types.h>
34
34
  #include <stdio.h>
35
35
 
36
- #ifndef _MSC_VER
37
- # include <stdint.h>
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)