ffi 1.13.0 → 1.15.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +127 -0
  3. data/Gemfile +1 -4
  4. data/README.md +14 -2
  5. data/Rakefile +43 -29
  6. data/ext/ffi_c/AbstractMemory.c +24 -25
  7. data/ext/ffi_c/Buffer.c +2 -7
  8. data/ext/ffi_c/Call.c +3 -9
  9. data/ext/ffi_c/ClosurePool.c +64 -11
  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 +31 -16
  13. data/ext/ffi_c/Function.h +0 -4
  14. data/ext/ffi_c/FunctionInfo.c +2 -6
  15. data/ext/ffi_c/LastError.c +2 -6
  16. data/ext/ffi_c/MemoryPointer.c +2 -7
  17. data/ext/ffi_c/MemoryPointer.h +0 -4
  18. data/ext/ffi_c/MethodHandle.c +4 -8
  19. data/ext/ffi_c/Platform.c +4 -9
  20. data/ext/ffi_c/Pointer.c +24 -25
  21. data/ext/ffi_c/Pointer.h +0 -4
  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 +2 -6
  25. data/ext/ffi_c/Thread.c +0 -5
  26. data/ext/ffi_c/Thread.h +1 -6
  27. data/ext/ffi_c/Type.c +1 -1
  28. data/ext/ffi_c/Types.c +6 -7
  29. data/ext/ffi_c/Types.h +3 -4
  30. data/ext/ffi_c/Variadic.c +14 -9
  31. data/ext/ffi_c/extconf.rb +25 -10
  32. data/ext/ffi_c/libffi/.travis/bfin-sim.exp +1 -1
  33. data/ext/ffi_c/libffi/.travis/m32r-sim.exp +1 -1
  34. data/ext/ffi_c/libffi/.travis/moxie-sim.exp +1 -1
  35. data/ext/ffi_c/libffi/.travis/or1k-sim.exp +1 -1
  36. data/ext/ffi_c/libffi/.travis/powerpc-eabisim.exp +1 -1
  37. data/ext/ffi_c/libffi/.travis/wine-sim.exp +1 -1
  38. data/ext/ffi_c/libffi/Makefile.am +48 -58
  39. data/ext/ffi_c/libffi/Makefile.in +420 -156
  40. data/ext/ffi_c/libffi/README.md +4 -0
  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 +158 -96
  44. data/ext/ffi_c/libffi/configure.ac +6 -1
  45. data/ext/ffi_c/libffi/configure.host +32 -20
  46. data/ext/ffi_c/libffi/doc/Makefile.in +8 -5
  47. data/ext/ffi_c/libffi/fficonfig.h.in +6 -0
  48. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -1
  49. data/ext/ffi_c/libffi/include/Makefile.in +8 -5
  50. data/ext/ffi_c/libffi/install-sh +23 -13
  51. data/ext/ffi_c/libffi/ltmain.sh +156 -61
  52. data/ext/ffi_c/libffi/man/Makefile.in +8 -5
  53. data/ext/ffi_c/libffi/missing +8 -8
  54. data/ext/ffi_c/libffi/msvcc.sh +11 -11
  55. data/ext/ffi_c/libffi/src/aarch64/ffi.c +45 -35
  56. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +10 -5
  57. data/ext/ffi_c/libffi/src/aarch64/internal.h +1 -0
  58. data/ext/ffi_c/libffi/src/aarch64/sysv.S +1 -1
  59. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +1 -1
  60. data/ext/ffi_c/libffi/src/arm/ffi.c +22 -0
  61. data/ext/ffi_c/libffi/src/arm/sysv.S +4 -4
  62. data/ext/ffi_c/libffi/src/closures.c +23 -6
  63. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  64. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  65. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  66. data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
  67. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  68. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  69. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  70. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  71. data/ext/ffi_c/libffi/src/mips/ffi.c +5 -1
  72. data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
  73. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +13 -1
  74. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +1 -1
  75. data/ext/ffi_c/libffi/src/powerpc/linux64.S +8 -0
  76. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +13 -1
  77. data/ext/ffi_c/libffi/src/prep_cif.c +1 -1
  78. data/ext/ffi_c/libffi/src/x86/ffi.c +8 -2
  79. data/ext/ffi_c/libffi/src/x86/ffi64.c +7 -0
  80. data/ext/ffi_c/libffi/src/x86/ffiw64.c +5 -0
  81. data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
  82. data/ext/ffi_c/libffi/src/x86/unix64.S +1 -2
  83. data/ext/ffi_c/libffi/src/x86/win64.S +3 -2
  84. data/ext/ffi_c/libffi/src/x86/win64_intel.S +3 -2
  85. data/ext/ffi_c/libffi/testsuite/Makefile.in +9 -6
  86. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +22 -2
  87. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +4 -4
  88. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2 -2
  89. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +2 -0
  90. data/ffi.gemspec +1 -2
  91. data/lib/ffi/abstract_memory.rb +44 -0
  92. data/lib/ffi/autopointer.rb +1 -1
  93. data/lib/ffi/ffi.rb +1 -0
  94. data/lib/ffi/io.rb +3 -3
  95. data/lib/ffi/library.rb +3 -3
  96. data/lib/ffi/managedstruct.rb +2 -2
  97. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  98. data/lib/ffi/platform/aarch64-freebsd/types.conf +2 -2
  99. data/lib/ffi/platform/aarch64-freebsd12/types.conf +113 -60
  100. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  101. data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
  102. data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
  103. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +4 -22
  104. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  105. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  106. data/lib/ffi/platform.rb +17 -7
  107. data/lib/ffi/pointer.rb +2 -2
  108. data/lib/ffi/tools/const_generator.rb +6 -4
  109. data/lib/ffi/tools/struct_generator.rb +2 -1
  110. data/lib/ffi/variadic.rb +1 -10
  111. data/lib/ffi/version.rb +1 -1
  112. data/lib/ffi.rb +3 -4
  113. data/rakelib/ffi_gem_helper.rb +65 -0
  114. metadata +21 -28
  115. data/.appveyor.yml +0 -30
  116. data/.github/workflows/ci.yml +0 -64
  117. data/.gitignore +0 -25
  118. data/.gitmodules +0 -4
  119. data/.travis.yml +0 -58
  120. data/.yardopts +0 -5
  121. data/ext/ffi_c/win32/stdbool.h +0 -8
  122. data/ext/ffi_c/win32/stdint.h +0 -201
@@ -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
 
data/ext/ffi_c/Function.c CHANGED
@@ -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
 
@@ -256,11 +249,11 @@ VALUE
256
249
  rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
257
250
  {
258
251
  VALUE callback, cbref, cbTable;
259
- Function* fp;
260
252
 
261
253
  cbref = RTEST(rb_ivar_defined(proc, id_cb_ref)) ? rb_ivar_get(proc, id_cb_ref) : Qnil;
262
254
  /* If the first callback reference has the same function function signature, use it */
263
255
  if (cbref != Qnil && CLASS_OF(cbref) == rbffi_FunctionClass) {
256
+ Function* fp;
264
257
  Data_Get_Struct(cbref, Function, fp);
265
258
  if (fp->rbFunctionInfo == rbFunctionInfo) {
266
259
  return cbref;
@@ -279,14 +272,27 @@ rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
279
272
  rb_ivar_set(proc, id_cb_ref, callback);
280
273
  } else {
281
274
  /* The proc instance has been used as more than one type of callback, store extras in a hash */
282
- cbTable = rb_hash_new();
283
- 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
+ }
284
279
  rb_hash_aset(cbTable, rbFunctionInfo, callback);
285
280
  }
286
281
 
287
282
  return callback;
288
283
  }
289
284
 
285
+ #if !defined(_WIN32) && defined(DEFER_ASYNC_CALLBACK)
286
+ static void
287
+ after_fork_callback(void)
288
+ {
289
+ /* Ensure that a new dispatcher thread is started in a forked process */
290
+ async_cb_thread = Qnil;
291
+ pthread_mutex_init(&async_cb_mutex, NULL);
292
+ pthread_cond_init(&async_cb_cond, NULL);
293
+ }
294
+ #endif
295
+
290
296
  static VALUE
291
297
  function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
292
298
  {
@@ -314,7 +320,16 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
314
320
 
315
321
  #if defined(DEFER_ASYNC_CALLBACK)
316
322
  if (async_cb_thread == Qnil) {
323
+
324
+ #if !defined(_WIN32)
325
+ if( pthread_atfork(NULL, NULL, after_fork_callback) ){
326
+ rb_warn("FFI: unable to register fork callback");
327
+ }
328
+ #endif
329
+
317
330
  async_cb_thread = rb_thread_create(async_cb_event, NULL);
331
+ /* Name thread, for better debugging */
332
+ rb_funcall(async_cb_thread, rb_intern("name="), 1, rb_str_new2("FFI Callback Dispatcher"));
318
333
  }
319
334
  #endif
320
335
 
@@ -530,7 +545,9 @@ async_cb_event(void* unused)
530
545
  rb_thread_call_without_gvl(async_cb_wait, &w, async_cb_stop, &w);
531
546
  if (w.cb != NULL) {
532
547
  /* Start up a new ruby thread to run the ruby callback */
533
- rb_thread_create(async_cb_call, w.cb);
548
+ VALUE new_thread = rb_thread_create(async_cb_call, w.cb);
549
+ /* Name thread, for better debugging */
550
+ rb_funcall(new_thread, rb_intern("name="), 1, rb_str_new2("FFI Callback Runner"));
534
551
  }
535
552
  }
536
553
 
@@ -716,7 +733,6 @@ invoke_callback(VALUE data)
716
733
  break;
717
734
 
718
735
  case NATIVE_FUNCTION:
719
- case NATIVE_CALLBACK:
720
736
  case NATIVE_STRUCT:
721
737
  param = rbffi_NativeValue_ToRuby(paramType, rbParamType, parameters[i]);
722
738
  break;
@@ -792,7 +808,6 @@ invoke_callback(VALUE data)
792
808
  break;
793
809
 
794
810
  case NATIVE_FUNCTION:
795
- case NATIVE_CALLBACK:
796
811
  if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
797
812
 
798
813
  *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
@@ -849,7 +864,7 @@ callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errm
849
864
  FunctionType* fnInfo = (FunctionType *) ctx;
850
865
  ffi_status ffiStatus;
851
866
 
852
- ffiStatus = ffi_prep_closure_loc(code, &fnInfo->ffi_cif, callback_invoke, closure, code);
867
+ ffiStatus = ffi_prep_closure_loc(closure->pcl, &fnInfo->ffi_cif, callback_invoke, closure, code);
853
868
  if (ffiStatus != FFI_OK) {
854
869
  snprintf(errmsg, errmsgsize, "ffi_prep_closure_loc failed. status=%#x", ffiStatus);
855
870
  return false;
data/ext/ffi_c/Function.h CHANGED
@@ -34,11 +34,7 @@
34
34
  extern "C" {
35
35
  #endif
36
36
 
37
- #ifndef _MSC_VER
38
37
  # include <stdbool.h>
39
- #else
40
- # include "win32/stdbool.h"
41
- #endif
42
38
 
43
39
  #include <ffi.h>
44
40
 
@@ -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>
@@ -33,12 +33,8 @@
33
33
  #endif
34
34
  #include <sys/types.h>
35
35
  #include <stdio.h>
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
  #include <errno.h>
43
39
  #include <ruby.h>
44
40
 
@@ -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 <stdbool.h>
33
- # include <stdint.h>
34
- #else
35
- # include "win32/stdbool.h"
36
- # include "win32/stdint.h"
37
- #endif
31
+ #include <stdbool.h>
32
+ #include <stdint.h>
38
33
  #include <limits.h>
39
34
  #include <ruby.h>
40
35
  #include "rbffi.h"
@@ -31,11 +31,7 @@
31
31
  #ifndef RBFFI_MEMORYPOINTER_H
32
32
  #define RBFFI_MEMORYPOINTER_H
33
33
 
34
- #ifndef _MSC_VER
35
34
  # include <stdbool.h>
36
- #else
37
- # include "win32/stdbool.h"
38
- #endif
39
35
  #include <ruby.h>
40
36
 
41
37
  #ifdef __cplusplus
@@ -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/stdint.h"
42
- # include "win32/stdbool.h"
43
- #endif
37
+ #include <stdint.h>
38
+ #include <stdbool.h>
44
39
  #ifndef _WIN32
45
40
  # include <unistd.h>
46
41
  #endif
@@ -117,6 +112,7 @@ rbffi_MethodHandle_Free(MethodHandle* handle)
117
112
  {
118
113
  if (handle != NULL) {
119
114
  rbffi_Closure_Free(handle->closure);
115
+ xfree(handle);
120
116
  }
121
117
  }
122
118
 
@@ -140,7 +136,7 @@ prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t er
140
136
  #if defined(USE_RAW)
141
137
  ffiStatus = ffi_prep_raw_closure(code, &mh_cif, attached_method_invoke, closure);
142
138
  #else
143
- ffiStatus = ffi_prep_closure_loc(code, &mh_cif, attached_method_invoke, closure, code);
139
+ ffiStatus = ffi_prep_closure_loc(closure->pcl, &mh_cif, attached_method_invoke, closure, code);
144
140
  #endif
145
141
  if (ffiStatus != FFI_OK) {
146
142
  snprintf(errmsg, errmsgsize, "ffi_prep_closure_loc failed. status=%#x", ffiStatus);
data/ext/ffi_c/Platform.c CHANGED
@@ -31,19 +31,14 @@
31
31
  # include <sys/param.h>
32
32
  #endif
33
33
  # include <sys/types.h>
34
- #ifndef _MSC_VER
35
- # include <stdint.h>
36
- # include <stdbool.h>
37
- #else
38
- # include "win32/stdint.h"
39
- # include "win32/stdbool.h"
40
- #endif
34
+ #include <stdint.h>
35
+ #include <stdbool.h>
41
36
  #include <ruby.h>
42
37
  #include <ctype.h>
43
38
  #include "rbffi_endian.h"
44
39
  #include "Platform.h"
45
40
 
46
- #if defined(__GNU__) || defined(__GLIBC__)
41
+ #if defined(__GNU__) || (defined(__GLIBC__) && !defined(__UCLIBC__))
47
42
  # include <gnu/lib-names.h>
48
43
  #endif
49
44
 
@@ -76,7 +71,7 @@ rbffi_Platform_Init(VALUE moduleFFI)
76
71
  rb_define_const(PlatformModule, "BYTE_ORDER", INT2FIX(BYTE_ORDER));
77
72
  rb_define_const(PlatformModule, "LITTLE_ENDIAN", INT2FIX(LITTLE_ENDIAN));
78
73
  rb_define_const(PlatformModule, "BIG_ENDIAN", INT2FIX(BIG_ENDIAN));
79
- #if defined(__GNU__) || defined(__GLIBC__)
74
+ #if defined(__GNU__) || (defined(__GLIBC__) && !defined(__UCLIBC__))
80
75
  rb_define_const(PlatformModule, "GNU_LIBC", rb_str_new2(LIBC_SO));
81
76
  #endif
82
77
  export_primitive_types(PlatformModule);
data/ext/ffi_c/Pointer.c CHANGED
@@ -27,13 +27,8 @@
27
27
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
28
  */
29
29
 
30
- #ifndef _MSC_VER
31
- # include <stdint.h>
32
- # include <stdbool.h>
33
- #else
34
- # include "win32/stdint.h"
35
- # include "win32/stdbool.h"
36
- #endif
30
+ #include <stdint.h>
31
+ #include <stdbool.h>
37
32
  #include <limits.h>
38
33
  #include <ruby.h>
39
34
  #include "rbffi.h"
@@ -157,14 +152,14 @@ ptr_initialize_copy(VALUE self, VALUE other)
157
152
  {
158
153
  AbstractMemory* src;
159
154
  Pointer* dst;
160
-
155
+
161
156
  Data_Get_Struct(self, Pointer, dst);
162
157
  src = POINTER(other);
163
158
  if (src->size == LONG_MAX) {
164
159
  rb_raise(rb_eRuntimeError, "cannot duplicate unbounded memory area");
165
160
  return Qnil;
166
161
  }
167
-
162
+
168
163
  if ((dst->memory.flags & (MEM_RD | MEM_WR)) != (MEM_RD | MEM_WR)) {
169
164
  rb_raise(rb_eRuntimeError, "cannot duplicate unreadable/unwritable memory area");
170
165
  return Qnil;
@@ -180,13 +175,13 @@ ptr_initialize_copy(VALUE self, VALUE other)
180
175
  rb_raise(rb_eNoMemError, "failed to allocate memory size=%lu bytes", src->size);
181
176
  return Qnil;
182
177
  }
183
-
178
+
184
179
  dst->allocated = true;
185
180
  dst->autorelease = true;
186
181
  dst->memory.address = (void *) (((uintptr_t) dst->storage + 0x7) & (uintptr_t) ~0x7ULL);
187
182
  dst->memory.size = src->size;
188
183
  dst->memory.typeSize = src->typeSize;
189
-
184
+
190
185
  /* finally, copy the actual memory contents */
191
186
  memcpy(dst->memory.address, src->address, src->size);
192
187
 
@@ -199,7 +194,7 @@ slice(VALUE self, long offset, long size)
199
194
  AbstractMemory* ptr;
200
195
  Pointer* p;
201
196
  VALUE retval;
202
-
197
+
203
198
  Data_Get_Struct(self, AbstractMemory, ptr);
204
199
  checkBounds(ptr, offset, size == LONG_MAX ? 1 : size);
205
200
 
@@ -214,7 +209,7 @@ slice(VALUE self, long offset, long size)
214
209
  return retval;
215
210
  }
216
211
 
217
- /*
212
+ /*
218
213
  * Document-method: +
219
214
  * call-seq: ptr + offset
220
215
  * @param [Numeric] offset
@@ -237,7 +232,7 @@ ptr_plus(VALUE self, VALUE offset)
237
232
  * @param [Numeric] offset
238
233
  * @param [Numeric] length
239
234
  * @return [Pointer]
240
- * Return a new {Pointer} from an existing one. This pointer points on same contents
235
+ * Return a new {Pointer} from an existing one. This pointer points on same contents
241
236
  * from +offset+ for a length +length+.
242
237
  */
243
238
  static VALUE
@@ -256,7 +251,7 @@ ptr_inspect(VALUE self)
256
251
  {
257
252
  char buf[100];
258
253
  Pointer* ptr;
259
-
254
+
260
255
  Data_Get_Struct(self, Pointer, ptr);
261
256
 
262
257
  if (ptr->memory.size != LONG_MAX) {
@@ -295,7 +290,7 @@ static VALUE
295
290
  ptr_equals(VALUE self, VALUE other)
296
291
  {
297
292
  Pointer* ptr;
298
-
293
+
299
294
  Data_Get_Struct(self, Pointer, ptr);
300
295
 
301
296
  if (NIL_P(other)) {
@@ -314,7 +309,7 @@ static VALUE
314
309
  ptr_address(VALUE self)
315
310
  {
316
311
  Pointer* ptr;
317
-
312
+
318
313
  Data_Get_Struct(self, Pointer, ptr);
319
314
 
320
315
  return ULL2NUM((uintptr_t) ptr->memory.address);
@@ -331,9 +326,9 @@ ptr_address(VALUE self)
331
326
  * @overload order
332
327
  * @return [:big, :little] endianness of +self+
333
328
  * @overload order(order)
334
- * @param [Symbol] order endianness to set (+:little+, +:big+ or +:network+). +:big+ and +:network+
329
+ * @param [Symbol] order endianness to set (+:little+, +:big+ or +:network+). +:big+ and +:network+
335
330
  * are synonymous.
336
- * @return [self]
331
+ * @return a new pointer with the new order
337
332
  */
338
333
  static VALUE
339
334
  ptr_order(int argc, VALUE* argv, VALUE self)
@@ -358,6 +353,8 @@ ptr_order(int argc, VALUE* argv, VALUE self)
358
353
 
359
354
  } else if (id == rb_intern("big") || id == rb_intern("network")) {
360
355
  order = BIG_ENDIAN;
356
+ } else {
357
+ rb_raise(rb_eArgError, "unknown byte order");
361
358
  }
362
359
  }
363
360
  if (order != BYTE_ORDER) {
@@ -395,7 +392,7 @@ ptr_free(VALUE self)
395
392
 
396
393
  } else {
397
394
  VALUE caller = rb_funcall(rb_funcall(Qnil, rb_intern("caller"), 0), rb_intern("first"), 0);
398
-
395
+
399
396
  rb_warn("calling free on non allocated pointer %s from %s", RSTRING_PTR(ptr_inspect(self)), RSTRING_PTR(rb_str_to_str(caller)));
400
397
  }
401
398
 
@@ -408,7 +405,7 @@ ptr_type_size(VALUE self)
408
405
  Pointer* ptr;
409
406
 
410
407
  Data_Get_Struct(self, Pointer, ptr);
411
-
408
+
412
409
  return INT2NUM(ptr->memory.typeSize);
413
410
  }
414
411
 
@@ -440,7 +437,7 @@ ptr_autorelease_p(VALUE self)
440
437
  Pointer* ptr;
441
438
 
442
439
  Data_Get_Struct(self, Pointer, ptr);
443
-
440
+
444
441
  return ptr->autorelease ? Qtrue : Qfalse;
445
442
  }
446
443
 
@@ -472,9 +469,11 @@ rbffi_Pointer_Init(VALUE moduleFFI)
472
469
  * Pointer class is used to manage C pointers with ease. A {Pointer} object is defined by his
473
470
  * {#address} (as a C pointer). It permits additions with an integer for pointer arithmetic.
474
471
  *
475
- * ==Autorelease
476
- * A pointer object may autorelease his contents when freed (by default). This behaviour may be
477
- * changed with {#autorelease=} method.
472
+ * == Autorelease
473
+ * By default a pointer object frees its content when it's garbage collected.
474
+ * Therefore it's usually not necessary to call {#free} explicit.
475
+ * This behaviour may be changed with {#autorelease=} method.
476
+ * If it's set to +false+, the memory isn't freed by the garbage collector, but stays valid until +free()+ is called on C level or when the process terminates.
478
477
  */
479
478
  rbffi_PointerClass = rb_define_class_under(moduleFFI, "Pointer", ffi_AbstractMemory);
480
479
  /*
data/ext/ffi_c/Pointer.h CHANGED
@@ -30,11 +30,7 @@
30
30
  #ifndef RBFFI_POINTER_H
31
31
  #define RBFFI_POINTER_H
32
32
 
33
- #ifndef _MSC_VER
34
33
  # include <stdbool.h>
35
- #else
36
- # include "win32/stdbool.h"
37
- #endif
38
34
 
39
35
  #ifdef __cplusplus
40
36
  extern "C" {
data/ext/ffi_c/Struct.c CHANGED
@@ -31,12 +31,9 @@
31
31
  #include <sys/types.h>
32
32
  #ifndef _MSC_VER
33
33
  # include <sys/param.h>
34
- # include <stdint.h>
35
- # include <stdbool.h>
36
- #else
37
- # include "win32/stdbool.h"
38
- # include "win32/stdint.h"
39
34
  #endif
35
+ #include <stdint.h>
36
+ #include <stdbool.h>
40
37
  #include <ruby.h>
41
38
  #include "rbffi.h"
42
39
  #include "compat.h"
@@ -290,7 +287,7 @@ struct_field(Struct* s, VALUE fieldName)
290
287
  VALUE rbField = rb_hash_aref(layout->rbFieldMap, fieldName);
291
288
  if (unlikely(NIL_P(rbField))) {
292
289
  VALUE str = rb_funcall2(fieldName, id_to_s, 0, NULL);
293
- rb_raise(rb_eArgError, "No such field '%s'", StringValuePtr(str));
290
+ rb_raise(rb_eArgError, "No such field '%s'", StringValueCStr(str));
294
291
  }
295
292
  /* Write the retrieved coder to the cache */
296
293
  p_ce->fieldName = fieldName;
@@ -32,13 +32,8 @@
32
32
  #endif
33
33
  #include <sys/types.h>
34
34
  #include <stdio.h>
35
- #ifndef _MSC_VER
36
- # include <stdint.h>
37
- # include <stdbool.h>
38
- #else
39
- # include "win32/stdbool.h"
40
- # include "win32/stdint.h"
41
- #endif
35
+ #include <stdint.h>
36
+ #include <stdbool.h>
42
37
  #include <errno.h>
43
38
  #include <ruby.h>
44
39
 
@@ -32,12 +32,9 @@
32
32
 
33
33
  #ifndef _MSC_VER
34
34
  # include <sys/param.h>
35
- # include <stdint.h>
36
- # include <stdbool.h>
37
- #else
38
- # include "win32/stdbool.h"
39
- # include "win32/stdint.h"
40
35
  #endif
36
+ #include <stdint.h>
37
+ #include <stdbool.h>
41
38
  #include <ruby.h>
42
39
  #include "rbffi.h"
43
40
  #include "compat.h"
@@ -126,7 +123,6 @@ struct_field_initialize(int argc, VALUE* argv, VALUE self)
126
123
 
127
124
  switch (field->type->nativeType == NATIVE_MAPPED ? ((MappedType *) field->type)->type->nativeType : field->type->nativeType) {
128
125
  case NATIVE_FUNCTION:
129
- case NATIVE_CALLBACK:
130
126
  case NATIVE_POINTER:
131
127
  field->referenceRequired = true;
132
128
  break;
data/ext/ffi_c/Thread.c CHANGED
@@ -28,12 +28,7 @@
28
28
  */
29
29
 
30
30
  #include <stddef.h>
31
- #ifndef _MSC_VER
32
31
  #include <stdbool.h>
33
- #else
34
- # include "win32/stdbool.h"
35
- # include "win32/stdint.h"
36
- #endif
37
32
 
38
33
  #if defined(__CYGWIN__) || !defined(_WIN32)
39
34
  # include <pthread.h>
data/ext/ffi_c/Thread.h CHANGED
@@ -30,12 +30,7 @@
30
30
  #ifndef RBFFI_THREAD_H
31
31
  #define RBFFI_THREAD_H
32
32
 
33
- #ifndef _MSC_VER
34
- # include <stdbool.h>
35
- #else
36
- # include "win32/stdbool.h"
37
- # include "win32/stdint.h"
38
- #endif
33
+ #include <stdbool.h>
39
34
  #include <ruby.h>
40
35
  #include "extconf.h"
41
36
 
data/ext/ffi_c/Type.c CHANGED
@@ -28,7 +28,7 @@
28
28
  */
29
29
 
30
30
  #ifndef _MSC_VER
31
- #include <sys/param.h>
31
+ # include <sys/param.h>
32
32
  #endif
33
33
 
34
34
  #include <sys/types.h>
data/ext/ffi_c/Types.c CHANGED
@@ -85,10 +85,9 @@ rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr)
85
85
  return rbffi_Pointer_NewInstance(*(void **) ptr);
86
86
  case NATIVE_BOOL:
87
87
  return ((unsigned char) *(ffi_arg *) ptr) ? Qtrue : Qfalse;
88
-
89
- case NATIVE_FUNCTION:
90
- case NATIVE_CALLBACK: {
91
- return *(void **) ptr != NULL
88
+
89
+ case NATIVE_FUNCTION: {
90
+ return *(void **) ptr != NULL
92
91
  ? rbffi_Function_NewInstance(rbType, rbffi_Pointer_NewInstance(*(void **) ptr))
93
92
  : Qnil;
94
93
  }
@@ -116,15 +115,15 @@ rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr)
116
115
 
117
116
  values[0] = rbffi_NativeValue_ToRuby(m->type, m->rbType, ptr);
118
117
  values[1] = Qnil;
119
-
118
+
120
119
 
121
120
  rbReturnValue = rb_funcall2(m->rbConverter, id_from_native, 2, values);
122
121
  RB_GC_GUARD(values[0]);
123
122
  RB_GC_GUARD(rbType);
124
-
123
+
125
124
  return rbReturnValue;
126
125
  }
127
-
126
+
128
127
  default:
129
128
  rb_raise(rb_eRuntimeError, "Unknown type: %d", type->nativeType);
130
129
  return Qnil;
data/ext/ffi_c/Types.h CHANGED
@@ -51,20 +51,19 @@ typedef enum {
51
51
  NATIVE_FLOAT64,
52
52
  NATIVE_LONGDOUBLE,
53
53
  NATIVE_POINTER,
54
- NATIVE_CALLBACK,
55
54
  NATIVE_FUNCTION,
56
55
  NATIVE_BUFFER_IN,
57
56
  NATIVE_BUFFER_OUT,
58
57
  NATIVE_BUFFER_INOUT,
59
58
  NATIVE_CHAR_ARRAY,
60
59
  NATIVE_BOOL,
61
-
60
+
62
61
  /** An immutable string. Nul terminated, but only copies in to the native function */
63
62
  NATIVE_STRING,
64
-
63
+
65
64
  /** The function takes a variable number of arguments */
66
65
  NATIVE_VARARGS,
67
-
66
+
68
67
  /** Struct-by-value param or result */
69
68
  NATIVE_STRUCT,
70
69
 
data/ext/ffi_c/Variadic.c CHANGED
@@ -33,13 +33,8 @@
33
33
  #include <sys/types.h>
34
34
 
35
35
  #include <stdio.h>
36
- #ifndef _MSC_VER
37
- # include <stdint.h>
38
- # include <stdbool.h>
39
- #else
40
- # include "win32/stdbool.h"
41
- # include "win32/stdint.h"
42
- #endif
36
+ #include <stdint.h>
37
+ #include <stdbool.h>
43
38
  #include <ruby.h>
44
39
 
45
40
  #include <ffi.h>
@@ -173,7 +168,8 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
173
168
  ffi_type* ffiReturnType;
174
169
  Type** paramTypes;
175
170
  VALUE* argv;
176
- int paramCount = 0, fixedCount = 0, i;
171
+ VALUE* callbackParameters;
172
+ int paramCount = 0, fixedCount = 0, callbackCount = 0, i;
177
173
  ffi_status ffiStatus;
178
174
  rbffi_frame_t frame = { 0 };
179
175
 
@@ -187,6 +183,7 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
187
183
  params = ALLOCA_N(FFIStorage, paramCount);
188
184
  ffiValues = ALLOCA_N(void*, paramCount);
189
185
  argv = ALLOCA_N(VALUE, paramCount);
186
+ callbackParameters = ALLOCA_N(VALUE, paramCount);
190
187
  retval = alloca(MAX(invoker->returnType->ffiType->size, FFI_SIZEOF_ARG));
191
188
 
192
189
  for (i = 0; i < paramCount; ++i) {
@@ -216,6 +213,14 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
216
213
  Data_Get_Struct(rbType, Type, paramTypes[i]);
217
214
  break;
218
215
 
216
+ case NATIVE_FUNCTION:
217
+ if (!rb_obj_is_kind_of(rbType, rbffi_FunctionTypeClass)) {
218
+ VALUE typeName = rb_funcall2(rbType, rb_intern("inspect"), 0, NULL);
219
+ rb_raise(rb_eTypeError, "Incorrect parameter type (%s)", RSTRING_PTR(typeName));
220
+ }
221
+ callbackParameters[callbackCount++] = rbType;
222
+ break;
223
+
219
224
  default:
220
225
  break;
221
226
  }
@@ -253,7 +258,7 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
253
258
  }
254
259
 
255
260
  rbffi_SetupCallParams(paramCount, argv, -1, paramTypes, params,
256
- ffiValues, NULL, 0, invoker->rbEnums);
261
+ ffiValues, callbackParameters, callbackCount, invoker->rbEnums);
257
262
 
258
263
  rbffi_frame_push(&frame);
259
264