ffi 1.13.1 → 1.15.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +73 -0
  3. data/Gemfile +1 -4
  4. data/README.md +14 -2
  5. data/Rakefile +23 -23
  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 +2 -8
  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 +2 -7
  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 +20 -4
  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/README.md +4 -0
  40. data/ext/ffi_c/libffi/config.guess +552 -331
  41. data/ext/ffi_c/libffi/config.sub +1321 -1306
  42. data/ext/ffi_c/libffi/configure.ac +6 -1
  43. data/ext/ffi_c/libffi/configure.host +32 -20
  44. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  45. data/ext/ffi_c/libffi/doc/libffi.texi +997 -0
  46. data/ext/ffi_c/libffi/doc/version.texi +4 -0
  47. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -1
  48. data/ext/ffi_c/libffi/msvcc.sh +11 -11
  49. data/ext/ffi_c/libffi/src/aarch64/ffi.c +45 -35
  50. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +10 -5
  51. data/ext/ffi_c/libffi/src/aarch64/internal.h +1 -0
  52. data/ext/ffi_c/libffi/src/aarch64/sysv.S +1 -1
  53. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +1 -1
  54. data/ext/ffi_c/libffi/src/arm/ffi.c +22 -0
  55. data/ext/ffi_c/libffi/src/arm/sysv.S +4 -4
  56. data/ext/ffi_c/libffi/src/closures.c +23 -6
  57. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  58. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  59. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  60. data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
  61. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  62. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  63. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  64. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  65. data/ext/ffi_c/libffi/src/mips/ffi.c +5 -1
  66. data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
  67. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +13 -1
  68. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +1 -1
  69. data/ext/ffi_c/libffi/src/powerpc/linux64.S +8 -0
  70. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +13 -1
  71. data/ext/ffi_c/libffi/src/prep_cif.c +1 -1
  72. data/ext/ffi_c/libffi/src/x86/ffi.c +8 -2
  73. data/ext/ffi_c/libffi/src/x86/ffi64.c +7 -0
  74. data/ext/ffi_c/libffi/src/x86/ffiw64.c +5 -0
  75. data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
  76. data/ext/ffi_c/libffi/src/x86/unix64.S +1 -2
  77. data/ext/ffi_c/libffi/src/x86/win64.S +3 -2
  78. data/ext/ffi_c/libffi/src/x86/win64_intel.S +3 -2
  79. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +22 -2
  80. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +4 -4
  81. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2 -2
  82. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +2 -0
  83. data/ffi.gemspec +1 -1
  84. data/lib/ffi.rb +3 -4
  85. data/lib/ffi/abstract_memory.rb +44 -0
  86. data/lib/ffi/autopointer.rb +1 -1
  87. data/lib/ffi/ffi.rb +1 -0
  88. data/lib/ffi/io.rb +3 -3
  89. data/lib/ffi/library.rb +1 -1
  90. data/lib/ffi/managedstruct.rb +2 -2
  91. data/lib/ffi/platform.rb +15 -6
  92. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  93. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  94. data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
  95. data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
  96. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  97. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  98. data/lib/ffi/pointer.rb +2 -2
  99. data/lib/ffi/tools/const_generator.rb +2 -1
  100. data/lib/ffi/tools/struct_generator.rb +2 -1
  101. data/lib/ffi/variadic.rb +1 -10
  102. data/lib/ffi/version.rb +1 -1
  103. data/rakelib/ffi_gem_helper.rb +65 -0
  104. metadata +18 -11
  105. data/.appveyor.yml +0 -30
  106. data/.github/workflows/ci.yml +0 -64
  107. data/.gitignore +0 -25
  108. data/.gitmodules +0 -4
  109. data/.travis.yml +0 -58
  110. data/.yardopts +0 -5
  111. data/ext/ffi_c/win32/stdbool.h +0 -8
  112. data/ext/ffi_c/win32/stdint.h +0 -201
@@ -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,7 +58,6 @@
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
@@ -115,7 +106,11 @@ cleanup_closure_pool(ClosurePool* pool)
115
106
 
116
107
  for (memory = pool->blocks; memory != NULL; ) {
117
108
  Memory* next = memory->next;
109
+ #if !USE_FFI_ALLOC
118
110
  freePage(memory->code);
111
+ #else
112
+ ffi_closure_free(memory->code);
113
+ #endif
119
114
  free(memory->data);
120
115
  free(memory);
121
116
  memory = next;
@@ -134,6 +129,8 @@ rbffi_ClosurePool_Free(ClosurePool* pool)
134
129
  }
135
130
  }
136
131
 
132
+ #if !USE_FFI_ALLOC
133
+
137
134
  Closure*
138
135
  rbffi_Closure_Alloc(ClosurePool* pool)
139
136
  {
@@ -169,6 +166,7 @@ rbffi_Closure_Alloc(ClosurePool* pool)
169
166
  closure->next = &list[i + 1];
170
167
  closure->pool = pool;
171
168
  closure->code = ((char *)code + (i * trampolineSize));
169
+ closure->pcl = closure->code;
172
170
 
173
171
  if (!(*pool->prep)(pool->ctx, closure->code, closure, errmsg, sizeof(errmsg))) {
174
172
  goto error;
@@ -205,6 +203,57 @@ error:
205
203
  return NULL;
206
204
  }
207
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
+
208
257
  void
209
258
  rbffi_Closure_Free(Closure* closure)
210
259
  {
@@ -240,6 +289,8 @@ getPageSize()
240
289
  #endif
241
290
  }
242
291
 
292
+ #if !USE_FFI_ALLOC
293
+
243
294
  static void*
244
295
  allocatePage(void)
245
296
  {
@@ -272,6 +323,8 @@ protectPage(void* page)
272
323
  #endif
273
324
  }
274
325
 
326
+ #endif /* !USE_FFI_ALLOC */
327
+
275
328
  void
276
329
  rbffi_ClosurePool_Init(VALUE module)
277
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
 
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,13 +31,8 @@
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"
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
  /*