ffi 1.13.1 → 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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -0
  3. data/README.md +10 -2
  4. data/Rakefile +7 -0
  5. data/ext/ffi_c/AbstractMemory.c +24 -25
  6. data/ext/ffi_c/Buffer.c +2 -7
  7. data/ext/ffi_c/Call.c +2 -7
  8. data/ext/ffi_c/ClosurePool.c +64 -11
  9. data/ext/ffi_c/ClosurePool.h +3 -1
  10. data/ext/ffi_c/DynamicLibrary.c +1 -6
  11. data/ext/ffi_c/Function.c +8 -13
  12. data/ext/ffi_c/FunctionInfo.c +2 -6
  13. data/ext/ffi_c/LastError.c +2 -6
  14. data/ext/ffi_c/MemoryPointer.c +2 -7
  15. data/ext/ffi_c/MethodHandle.c +4 -8
  16. data/ext/ffi_c/Platform.c +2 -7
  17. data/ext/ffi_c/Pointer.c +24 -25
  18. data/ext/ffi_c/Struct.c +3 -6
  19. data/ext/ffi_c/StructByValue.c +2 -7
  20. data/ext/ffi_c/StructLayout.c +2 -5
  21. data/ext/ffi_c/Thread.c +0 -5
  22. data/ext/ffi_c/Thread.h +1 -6
  23. data/ext/ffi_c/Type.c +1 -1
  24. data/ext/ffi_c/Variadic.c +2 -7
  25. data/ext/ffi_c/extconf.rb +17 -4
  26. data/ext/ffi_c/libffi/.travis/bfin-sim.exp +1 -1
  27. data/ext/ffi_c/libffi/.travis/m32r-sim.exp +1 -1
  28. data/ext/ffi_c/libffi/.travis/moxie-sim.exp +1 -1
  29. data/ext/ffi_c/libffi/.travis/or1k-sim.exp +1 -1
  30. data/ext/ffi_c/libffi/.travis/powerpc-eabisim.exp +1 -1
  31. data/ext/ffi_c/libffi/.travis/wine-sim.exp +1 -1
  32. data/ext/ffi_c/libffi/Makefile.am +48 -58
  33. data/ext/ffi_c/libffi/README.md +4 -0
  34. data/ext/ffi_c/libffi/config.guess +552 -331
  35. data/ext/ffi_c/libffi/config.sub +1321 -1306
  36. data/ext/ffi_c/libffi/configure.ac +6 -1
  37. data/ext/ffi_c/libffi/configure.host +32 -20
  38. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  39. data/ext/ffi_c/libffi/doc/libffi.texi +997 -0
  40. data/ext/ffi_c/libffi/doc/version.texi +4 -0
  41. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -1
  42. data/ext/ffi_c/libffi/msvcc.sh +11 -11
  43. data/ext/ffi_c/libffi/src/aarch64/ffi.c +45 -35
  44. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +10 -5
  45. data/ext/ffi_c/libffi/src/aarch64/internal.h +1 -0
  46. data/ext/ffi_c/libffi/src/aarch64/sysv.S +1 -1
  47. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +1 -1
  48. data/ext/ffi_c/libffi/src/arm/ffi.c +22 -0
  49. data/ext/ffi_c/libffi/src/arm/sysv.S +4 -4
  50. data/ext/ffi_c/libffi/src/closures.c +23 -6
  51. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  52. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  53. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  54. data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
  55. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  56. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  57. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  58. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  59. data/ext/ffi_c/libffi/src/mips/ffi.c +5 -1
  60. data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
  61. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +13 -1
  62. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +1 -1
  63. data/ext/ffi_c/libffi/src/powerpc/linux64.S +8 -0
  64. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +13 -1
  65. data/ext/ffi_c/libffi/src/prep_cif.c +1 -1
  66. data/ext/ffi_c/libffi/src/x86/ffi.c +8 -2
  67. data/ext/ffi_c/libffi/src/x86/ffi64.c +7 -0
  68. data/ext/ffi_c/libffi/src/x86/ffiw64.c +5 -0
  69. data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
  70. data/ext/ffi_c/libffi/src/x86/unix64.S +1 -2
  71. data/ext/ffi_c/libffi/src/x86/win64.S +3 -2
  72. data/ext/ffi_c/libffi/src/x86/win64_intel.S +3 -2
  73. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +22 -2
  74. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +4 -4
  75. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2 -2
  76. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +2 -0
  77. data/ffi.gemspec +1 -1
  78. data/lib/ffi.rb +2 -2
  79. data/lib/ffi/abstract_memory.rb +44 -0
  80. data/lib/ffi/autopointer.rb +1 -1
  81. data/lib/ffi/ffi.rb +1 -0
  82. data/lib/ffi/io.rb +3 -3
  83. data/lib/ffi/library.rb +1 -1
  84. data/lib/ffi/managedstruct.rb +2 -2
  85. data/lib/ffi/platform.rb +15 -6
  86. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  87. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  88. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  89. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  90. data/lib/ffi/pointer.rb +2 -2
  91. data/lib/ffi/variadic.rb +1 -1
  92. data/lib/ffi/version.rb +1 -1
  93. metadata +15 -11
  94. data/.appveyor.yml +0 -30
  95. data/.github/workflows/ci.yml +0 -64
  96. data/.gitignore +0 -25
  97. data/.gitmodules +0 -4
  98. data/.travis.yml +0 -58
  99. data/.yardopts +0 -5
  100. data/ext/ffi_c/win32/stdbool.h +0 -8
  101. data/ext/ffi_c/win32/stdint.h +0 -201
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c1ae7c590f7dd4d8d821c6faf31c66499a90c421ff25fe14ce4465cc058b83f
4
- data.tar.gz: e4c16035d46e13e752e215fdc87511c214db31cec9084cca3c2141a9d83469c7
3
+ metadata.gz: 353f17e7189b732ee142f0fdc41abd08c4fd452ff66c8a8ac8f6f73fea51af61
4
+ data.tar.gz: dffb5ad7b577e129155fc17a27510a8b59c47b581f35a23feaecb8db1a8045ed
5
5
  SHA512:
6
- metadata.gz: a4064371f99217b7b449c46915e4505b54a61785ec27a2b5cd51d798cc929ff58bef33ad9064ab93ca85ad2c5d5c07d515edb0ac5d673a468fb17abf18565627
7
- data.tar.gz: a545c796f0b36fb7cac6ac06a73094274d077e0e0f54f55f67c129e6bff27b7679886a3adc87e9b3c173f975864dc78ac3d6277d8a8d1352f974b697ace0f8b4
6
+ metadata.gz: 2ecd826778b07a85f78e85d029f7fddf3db2504662368e00dca0089eab598b0192327a9b32dde4219c2c74085a8df6b68c65e1b1f949cb958933dbef2c827fdd
7
+ data.tar.gz: 7eac3b6ba310ff47cc1fe4288a1efa9c0b4dda8f10be26c65d67d446cd83a4085cc99e60c965254165205d0345a03e56c39e8a2ab4e0cc48efbe1ba28c0c7bc2
@@ -1,3 +1,44 @@
1
+ 1.14.2 / 2020-12-21
2
+ -------------------
3
+
4
+ Fixed:
5
+ * Fix builtin libffi on newer Ubuntu caused by an outdated Makefile.in . #863
6
+
7
+
8
+ 1.14.1 / 2020-12-19
9
+ -------------------
10
+
11
+ Changed:
12
+ * Revert changes to FFI::Pointer#write_string made in ffi-1.14.0.
13
+ It breaks compatibilty in a way that can cause hard to find errors. #857
14
+
15
+
16
+ 1.14.0 / 2020-12-18
17
+ -------------------
18
+
19
+ Added:
20
+ * Add types.conf for x86_64-msys, x86_64-haiku, aarch64-openbsd and aarch64-darwin (alias arm64-darwin)
21
+ * Add method AbstractMemory#size_limit? . #829
22
+ * Add new extconf option --enable-libffi-alloc which is enabled per default on Apple M1 (arm64-darwin).
23
+
24
+ Changed:
25
+ * Do NULL pointer check only when array length > 0 . #305
26
+ * Raise an error on an unknown order argument. #830
27
+ * Change FFI::Pointer#write_string to terminate with a NUL byte like other string methods. #805
28
+ * Update bundled libffi to latest master.
29
+
30
+ Removed:
31
+ * Remove win32/stdint.h and stdbool.h because of copyright issue. #693
32
+
33
+ Fixed:
34
+ * Fix possible UTF-8 load error in loader script interpretation. #792
35
+ * Fix segfault on non-array argument to #write_array_of_*
36
+ * Fix memory leak in MethodHandle . #815
37
+ * Fix possible segfault in combination with fiddle or other libffi using gems . #835
38
+ * Fix possibility to use ffi ruby gem with JRuby-9.3 . #763
39
+ * Fix a GC issue, when a callback Proc is used on more than 2 callback signatures. #820
40
+
41
+
1
42
  1.13.1 / 2020-06-09
2
43
  -------------------
3
44
 
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Ruby-FFI https://github.com/ffi/ffi/wiki [![Build Status](https://travis-ci.org/ffi/ffi.svg?branch=master)](https://travis-ci.org/ffi/ffi) [![Build status Windows](https://ci.appveyor.com/api/projects/status/r8wxn1sd4s794gg1/branch/master?svg=true)](https://ci.appveyor.com/project/larskanis/ffi-aofqa/branch/master)
1
+ # Ruby-FFI https://github.com/ffi/ffi/wiki [![Build Status](https://travis-ci.com/ffi/ffi.svg?branch=master)](https://travis-ci.com/ffi/ffi) [![Build status Windows](https://ci.appveyor.com/api/projects/status/r8wxn1sd4s794gg1/branch/master?svg=true)](https://ci.appveyor.com/project/larskanis/ffi-aofqa/branch/master)
2
2
 
3
3
  ## Description
4
4
 
@@ -66,10 +66,18 @@ From rubygems:
66
66
  or from the git repository on github:
67
67
 
68
68
  git clone git://github.com/ffi/ffi.git
69
- git submodule update --init --recursive
70
69
  cd ffi
70
+ git submodule update --init --recursive
71
+ bundle install
71
72
  rake install
72
73
 
74
+ ### Install options:
75
+
76
+ * `--enable-system-libffi` : Force usage of system libffi
77
+ * `--disable-system-libffi` : Force usage of builtin libffi
78
+ * `--enable-libffi-alloc` : Force closure allocation by libffi
79
+ * `--disable-libffi-alloc` : Force closure allocation by builtin method
80
+
73
81
  ## License
74
82
 
75
83
  The ffi library is covered by the BSD license, also see the LICENSE file.
data/Rakefile CHANGED
@@ -37,6 +37,13 @@ CLEAN.include "pkg/ffi-*-{mingw32,java}"
37
37
  CLEAN.include 'lib/1.*'
38
38
  CLEAN.include 'lib/2.*'
39
39
 
40
+ # clean all shipped files, that are not in git
41
+ CLEAN.include(
42
+ gem_spec.files -
43
+ `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0").map { |f| File.join("ext/ffi_c/libffi", f) } -
44
+ `git ls-files -z`.split("\x0")
45
+ )
46
+
40
47
  task :distclean => :clobber
41
48
 
42
49
  desc "Test the extension"
@@ -32,12 +32,9 @@
32
32
  #include <sys/types.h>
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
 
42
39
  #include <limits.h>
43
40
  #include <ruby.h>
@@ -135,11 +132,13 @@ static VALUE memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary); \
135
132
  static VALUE \
136
133
  memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary) \
137
134
  { \
138
- long count = RARRAY_LEN(ary); \
135
+ long count; \
139
136
  long off = NUM2LONG(offset); \
140
137
  AbstractMemory* memory = MEMORY(self); \
141
138
  long i; \
142
- checkWrite(memory); \
139
+ Check_Type(ary, T_ARRAY); \
140
+ count = RARRAY_LEN(ary); \
141
+ if (likely(count > 0)) checkWrite(memory); \
143
142
  checkBounds(memory, off, count * sizeof(type)); \
144
143
  for (i = 0; i < count; i++) { \
145
144
  type tmp = (type) VAL(toNative(RARRAY_PTR(ary)[i]), swap); \
@@ -162,7 +161,7 @@ memory_get_array_of_##name(VALUE self, VALUE offset, VALUE length) \
162
161
  AbstractMemory* memory = MEMORY(self); \
163
162
  VALUE retVal = rb_ary_new2(count); \
164
163
  long i; \
165
- checkRead(memory); \
164
+ if (likely(count > 0)) checkRead(memory); \
166
165
  checkBounds(memory, off, count * sizeof(type)); \
167
166
  for (i = 0; i < count; ++i) { \
168
167
  type tmp; \
@@ -209,13 +208,13 @@ SWAPU16(uint16_t x)
209
208
  ((x >> 40) & 0x000000000000ff00ULL) | \
210
209
  ((x >> 56) & 0x00000000000000ffULL))
211
210
 
212
- static inline int32_t
211
+ static inline int32_t
213
212
  SWAPS32(int32_t x)
214
213
  {
215
214
  return bswap32(x);
216
215
  }
217
216
 
218
- static inline uint32_t
217
+ static inline uint32_t
219
218
  SWAPU32(uint32_t x)
220
219
  {
221
220
  return bswap32(x);
@@ -450,7 +449,7 @@ memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
450
449
  int i;
451
450
 
452
451
  checkBounds(ptr, off, count * sizeof (char*));
453
-
452
+
454
453
  for (i = 0; i < count; ++i) {
455
454
  const char* strptr = *((const char**) (ptr->address + off) + i);
456
455
  rb_ary_push(retVal, (strptr == NULL ? Qnil : rb_str_new2(strptr)));
@@ -477,7 +476,7 @@ memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
477
476
  * @param [Numeric] count number of strings to get. If nil, return all strings
478
477
  * @return [Array<String>]
479
478
  */
480
- static VALUE
479
+ static VALUE
481
480
  memory_read_array_of_string(int argc, VALUE* argv, VALUE self)
482
481
  {
483
482
  VALUE* rargv = ALLOCA_N(VALUE, argc + 1);
@@ -535,13 +534,13 @@ memory_get_bytes(VALUE self, VALUE offset, VALUE length)
535
534
  {
536
535
  AbstractMemory* ptr = MEMORY(self);
537
536
  long off, len;
538
-
537
+
539
538
  off = NUM2LONG(offset);
540
539
  len = NUM2LONG(length);
541
540
 
542
541
  checkRead(ptr);
543
542
  checkBounds(ptr, off, len);
544
-
543
+
545
544
  return rb_str_new((char *) ptr->address + off, len);
546
545
  }
547
546
 
@@ -595,7 +594,7 @@ memory_put_bytes(int argc, VALUE* argv, VALUE self)
595
594
  * equivalent to :
596
595
  * memory.get_bytes(0, length)
597
596
  */
598
- static VALUE
597
+ static VALUE
599
598
  memory_read_bytes(VALUE self, VALUE length)
600
599
  {
601
600
  return memory_get_bytes(self, INT2FIX(0), length);
@@ -610,7 +609,7 @@ memory_read_bytes(VALUE self, VALUE length)
610
609
  * equivalent to :
611
610
  * memory.put_bytes(0, str, index, length)
612
611
  */
613
- static VALUE
612
+ static VALUE
614
613
  memory_write_bytes(int argc, VALUE* argv, VALUE self)
615
614
  {
616
615
  VALUE* wargv = ALLOCA_N(VALUE, argc + 1);
@@ -643,7 +642,7 @@ memory_type_size(VALUE self)
643
642
  * Document-method: []
644
643
  * call-seq: memory[idx]
645
644
  * @param [Numeric] idx index to access in memory
646
- * @return
645
+ * @return
647
646
  * Memory read accessor.
648
647
  */
649
648
  static VALUE
@@ -748,9 +747,9 @@ MemoryOps rbffi_AbstractMemoryOps = {
748
747
  void
749
748
  rbffi_AbstractMemory_Init(VALUE moduleFFI)
750
749
  {
751
- /*
750
+ /*
752
751
  * Document-class: FFI::AbstractMemory
753
- *
752
+ *
754
753
  * {AbstractMemory} is the base class for many memory management classes such as {Buffer}.
755
754
  *
756
755
  * This class has a lot of methods to work with integers :
@@ -778,8 +777,8 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
778
777
  */
779
778
  VALUE classMemory = rb_define_class_under(moduleFFI, "AbstractMemory", rb_cObject);
780
779
  rbffi_AbstractMemoryClass = classMemory;
781
- /*
782
- * Document-variable: FFI::AbstractMemory
780
+ /*
781
+ * Document-variable: FFI::AbstractMemory
783
782
  */
784
783
  rb_global_variable(&rbffi_AbstractMemoryClass);
785
784
  rb_define_alloc_func(classMemory, memory_allocate);
@@ -807,13 +806,13 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
807
806
  rb_define_method(classMemory, "read_array_of_" #type, memory_read_array_of_##type, 1); \
808
807
  rb_define_method(classMemory, "write_array_of_u" #type, memory_write_array_of_u##type, 1); \
809
808
  rb_define_method(classMemory, "read_array_of_u" #type, memory_read_array_of_u##type, 1);
810
-
809
+
811
810
  INT(int8);
812
811
  INT(int16);
813
812
  INT(int32);
814
813
  INT(int64);
815
814
  INT(long);
816
-
815
+
817
816
  #define ALIAS(name, old) \
818
817
  rb_define_alias(classMemory, "put_" #name, "put_" #old); \
819
818
  rb_define_alias(classMemory, "get_" #name, "get_" #old); \
@@ -831,12 +830,12 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
831
830
  rb_define_alias(classMemory, "read_array_of_" #name, "read_array_of_" #old); \
832
831
  rb_define_alias(classMemory, "write_array_of_u" #name, "write_array_of_u" #old); \
833
832
  rb_define_alias(classMemory, "read_array_of_u" #name, "read_array_of_u" #old);
834
-
833
+
835
834
  ALIAS(char, int8);
836
835
  ALIAS(short, int16);
837
836
  ALIAS(int, int32);
838
837
  ALIAS(long_long, int64);
839
-
838
+
840
839
  /*
841
840
  * Document-method: put_float32
842
841
  * call-seq: memory.put_float32offset, value)
@@ -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"
@@ -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>
@@ -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