ffi 1.15.5 → 1.17.0

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 (343) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +118 -0
  4. data/Gemfile +10 -3
  5. data/README.md +4 -3
  6. data/Rakefile +25 -10
  7. data/ext/ffi_c/AbstractMemory.c +99 -74
  8. data/ext/ffi_c/AbstractMemory.h +3 -2
  9. data/ext/ffi_c/ArrayType.c +51 -15
  10. data/ext/ffi_c/ArrayType.h +1 -0
  11. data/ext/ffi_c/Buffer.c +90 -33
  12. data/ext/ffi_c/Call.c +29 -12
  13. data/ext/ffi_c/Call.h +3 -2
  14. data/ext/ffi_c/DynamicLibrary.c +90 -27
  15. data/ext/ffi_c/Function.c +244 -98
  16. data/ext/ffi_c/Function.h +1 -0
  17. data/ext/ffi_c/FunctionInfo.c +81 -25
  18. data/ext/ffi_c/LastError.c +29 -11
  19. data/ext/ffi_c/MappedType.c +66 -23
  20. data/ext/ffi_c/MappedType.h +0 -2
  21. data/ext/ffi_c/MemoryPointer.c +36 -9
  22. data/ext/ffi_c/MethodHandle.c +3 -1
  23. data/ext/ffi_c/Pointer.c +82 -40
  24. data/ext/ffi_c/Pointer.h +1 -0
  25. data/ext/ffi_c/Struct.c +166 -84
  26. data/ext/ffi_c/Struct.h +7 -4
  27. data/ext/ffi_c/StructByValue.c +48 -16
  28. data/ext/ffi_c/StructLayout.c +130 -61
  29. data/ext/ffi_c/Type.c +120 -51
  30. data/ext/ffi_c/Type.h +3 -1
  31. data/ext/ffi_c/Types.c +8 -2
  32. data/ext/ffi_c/Types.h +0 -1
  33. data/ext/ffi_c/Variadic.c +71 -26
  34. data/ext/ffi_c/compat.h +22 -22
  35. data/ext/ffi_c/extconf.rb +19 -2
  36. data/ext/ffi_c/ffi.c +4 -0
  37. data/ext/ffi_c/libffi/.allow-ai-service +0 -0
  38. data/ext/ffi_c/libffi/.appveyor/site.exp +16 -0
  39. data/ext/ffi_c/libffi/.appveyor/unix-noexec.exp +7 -0
  40. data/ext/ffi_c/libffi/.appveyor.yml +27 -9
  41. data/ext/ffi_c/libffi/.ci/build-cross-in-container.sh +18 -0
  42. data/ext/ffi_c/libffi/{.travis → .ci}/build-in-container.sh +4 -6
  43. data/ext/ffi_c/libffi/.ci/build.sh +124 -0
  44. data/ext/ffi_c/libffi/{.travis → .ci}/install.sh +14 -7
  45. data/ext/ffi_c/libffi/.ci/msvs-detect +1103 -0
  46. data/ext/ffi_c/libffi/{.travis → .ci}/site.exp +5 -3
  47. data/ext/ffi_c/libffi/.circleci/config.yml +156 -0
  48. data/ext/ffi_c/libffi/.github/workflows/build.yml +479 -0
  49. data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +172 -0
  50. data/ext/ffi_c/libffi/.gitignore +10 -2
  51. data/ext/ffi_c/libffi/LICENSE +1 -1
  52. data/ext/ffi_c/libffi/Makefile.am +12 -5
  53. data/ext/ffi_c/libffi/Makefile.in +118 -51
  54. data/ext/ffi_c/libffi/README.md +150 -105
  55. data/ext/ffi_c/libffi/acinclude.m4 +10 -112
  56. data/ext/ffi_c/libffi/compile +348 -0
  57. data/ext/ffi_c/libffi/config.guess +623 -556
  58. data/ext/ffi_c/libffi/config.sub +75 -34
  59. data/ext/ffi_c/libffi/configure +4571 -3830
  60. data/ext/ffi_c/libffi/configure.ac +64 -28
  61. data/ext/ffi_c/libffi/configure.host +26 -7
  62. data/ext/ffi_c/libffi/doc/Makefile.in +9 -6
  63. data/ext/ffi_c/libffi/doc/libffi.texi +82 -33
  64. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  65. data/ext/ffi_c/libffi/fficonfig.h.in +12 -47
  66. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +163 -52
  67. data/ext/ffi_c/libffi/include/Makefile.am +1 -1
  68. data/ext/ffi_c/libffi/include/Makefile.in +10 -9
  69. data/ext/ffi_c/libffi/include/ffi.h.in +55 -60
  70. data/ext/ffi_c/libffi/include/ffi_cfi.h +21 -0
  71. data/ext/ffi_c/libffi/include/ffi_common.h +33 -2
  72. data/ext/ffi_c/libffi/include/tramp.h +45 -0
  73. data/ext/ffi_c/libffi/install-sh +92 -69
  74. data/ext/ffi_c/libffi/libffi.map.in +5 -0
  75. data/ext/ffi_c/libffi/libtool-version +2 -2
  76. data/ext/ffi_c/libffi/ltmain.sh +518 -333
  77. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +18 -14
  78. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +108 -72
  79. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +76 -45
  80. data/ext/ffi_c/libffi/m4/ax_prepend_flag.m4 +51 -0
  81. data/ext/ffi_c/libffi/man/Makefile.in +9 -6
  82. data/ext/ffi_c/libffi/missing +1 -1
  83. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +2 -2
  84. data/ext/ffi_c/libffi/msvcc.sh +1 -1
  85. data/ext/ffi_c/libffi/src/aarch64/ffi.c +172 -55
  86. data/ext/ffi_c/libffi/src/aarch64/internal.h +32 -0
  87. data/ext/ffi_c/libffi/src/aarch64/sysv.S +331 -87
  88. data/ext/ffi_c/libffi/src/arc/arcompact.S +169 -94
  89. data/ext/ffi_c/libffi/src/arc/ffi.c +325 -148
  90. data/ext/ffi_c/libffi/src/arc/ffitarget.h +14 -0
  91. data/ext/ffi_c/libffi/src/arm/ffi.c +62 -17
  92. data/ext/ffi_c/libffi/src/arm/ffitarget.h +3 -3
  93. data/ext/ffi_c/libffi/src/arm/internal.h +10 -0
  94. data/ext/ffi_c/libffi/src/arm/sysv.S +113 -42
  95. data/ext/ffi_c/libffi/src/closures.c +136 -50
  96. data/ext/ffi_c/libffi/src/debug.c +2 -2
  97. data/ext/ffi_c/libffi/src/dlmalloc.c +6 -1
  98. data/ext/ffi_c/libffi/src/ia64/ffi.c +12 -0
  99. data/ext/ffi_c/libffi/src/ia64/unix.S +20 -2
  100. data/ext/ffi_c/libffi/src/loongarch64/ffi.c +624 -0
  101. data/ext/ffi_c/libffi/src/loongarch64/ffitarget.h +82 -0
  102. data/ext/ffi_c/libffi/src/loongarch64/sysv.S +327 -0
  103. data/ext/ffi_c/libffi/src/m32r/ffi.c +31 -14
  104. data/ext/ffi_c/libffi/src/mips/ffi.c +250 -67
  105. data/ext/ffi_c/libffi/src/mips/ffitarget.h +7 -0
  106. data/ext/ffi_c/libffi/src/mips/n32.S +193 -33
  107. data/ext/ffi_c/libffi/src/mips/o32.S +61 -4
  108. data/ext/ffi_c/libffi/src/moxie/ffi.c +47 -22
  109. data/ext/ffi_c/libffi/src/or1k/ffi.c +25 -12
  110. data/ext/ffi_c/libffi/src/pa/ffi.c +32 -33
  111. data/ext/ffi_c/libffi/src/pa/ffi64.c +614 -0
  112. data/ext/ffi_c/libffi/src/pa/ffitarget.h +22 -8
  113. data/ext/ffi_c/libffi/src/pa/hpux32.S +83 -36
  114. data/ext/ffi_c/libffi/src/pa/hpux64.S +681 -0
  115. data/ext/ffi_c/libffi/src/pa/linux.S +82 -35
  116. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +36 -24
  117. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +1 -1
  118. data/ext/ffi_c/libffi/src/powerpc/linux64.S +2 -0
  119. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +2 -0
  120. data/ext/ffi_c/libffi/src/powerpc/t-aix +5 -0
  121. data/ext/ffi_c/libffi/src/prep_cif.c +22 -2
  122. data/ext/ffi_c/libffi/src/riscv/ffi.c +37 -4
  123. data/ext/ffi_c/libffi/src/sparc/ffi64.c +23 -1
  124. data/ext/ffi_c/libffi/src/tramp.c +716 -0
  125. data/ext/ffi_c/libffi/src/types.c +4 -6
  126. data/ext/ffi_c/libffi/src/wasm32/ffi.c +947 -0
  127. data/ext/ffi_c/libffi/src/wasm32/ffitarget.h +62 -0
  128. data/ext/ffi_c/libffi/src/x86/ffi.c +99 -37
  129. data/ext/ffi_c/libffi/src/x86/ffi64.c +67 -12
  130. data/ext/ffi_c/libffi/src/x86/ffitarget.h +9 -5
  131. data/ext/ffi_c/libffi/src/x86/ffiw64.c +44 -1
  132. data/ext/ffi_c/libffi/src/x86/internal.h +14 -0
  133. data/ext/ffi_c/libffi/src/x86/internal64.h +14 -0
  134. data/ext/ffi_c/libffi/src/x86/sysv.S +172 -38
  135. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +91 -88
  136. data/ext/ffi_c/libffi/src/x86/unix64.S +96 -6
  137. data/ext/ffi_c/libffi/src/x86/win64.S +20 -7
  138. data/ext/ffi_c/libffi/src/xtensa/ffi.c +16 -8
  139. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +4 -0
  140. data/ext/ffi_c/libffi/src/xtensa/sysv.S +26 -16
  141. data/ext/ffi_c/libffi/testsuite/Makefile.am +79 -114
  142. data/ext/ffi_c/libffi/testsuite/Makefile.in +89 -121
  143. data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +54 -0
  144. data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +63 -0
  145. data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +86 -0
  146. data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +48 -0
  147. data/ext/ffi_c/libffi/testsuite/emscripten/test.html +7 -0
  148. data/ext/ffi_c/libffi/testsuite/emscripten/test_libffi.py +51 -0
  149. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +43 -21
  150. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +2 -2
  151. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +1 -0
  152. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +5 -1
  153. data/ext/ffi_c/libffi/testsuite/libffi.call/bpo_38748.c +41 -0
  154. data/ext/ffi_c/libffi/testsuite/libffi.call/callback.c +99 -0
  155. data/ext/ffi_c/libffi/testsuite/libffi.call/callback2.c +108 -0
  156. data/ext/ffi_c/libffi/testsuite/libffi.call/callback3.c +114 -0
  157. data/ext/ffi_c/libffi/testsuite/libffi.call/callback4.c +119 -0
  158. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +28 -3
  159. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +3 -0
  160. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +5 -0
  161. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +4 -0
  162. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +4 -0
  163. data/ext/ffi_c/libffi/testsuite/libffi.call/s55.c +60 -0
  164. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +8 -9
  165. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +2 -2
  166. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +2 -2
  167. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +2 -2
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +1 -1
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_2.c +63 -0
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3.c +65 -0
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3f.c +65 -0
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4.c +67 -0
  173. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4f.c +67 -0
  174. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_big.c +93 -0
  175. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_small.c +61 -0
  176. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_2H.c +63 -0
  177. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_8H.c +90 -0
  178. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +1 -119
  179. data/ext/ffi_c/libffi/testsuite/libffi.call/va_2.c +220 -0
  180. data/ext/ffi_c/libffi/testsuite/libffi.call/va_3.c +154 -0
  181. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +13 -0
  182. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +11 -0
  183. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +15 -0
  184. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn0.c +3 -2
  185. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn1.c +2 -0
  186. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn2.c +2 -0
  187. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn3.c +21 -1
  188. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn4.c +2 -0
  189. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn5.c +2 -0
  190. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn6.c +2 -0
  191. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_loc_fn0.c +7 -6
  192. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_simple.c +6 -0
  193. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_12byte.c +18 -0
  194. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_16byte.c +22 -0
  195. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_18byte.c +24 -0
  196. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_19byte.c +29 -0
  197. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_1_1byte.c +4 -0
  198. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_20byte.c +19 -1
  199. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_20byte1.c +21 -1
  200. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_24byte.c +35 -3
  201. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_2byte.c +13 -0
  202. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3_1byte.c +19 -0
  203. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3byte1.c +13 -0
  204. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3byte2.c +13 -0
  205. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3float.c +18 -0
  206. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_4_1byte.c +22 -0
  207. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_4byte.c +13 -0
  208. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_5_1_byte.c +29 -1
  209. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_5byte.c +19 -1
  210. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_64byte.c +24 -0
  211. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_6_1_byte.c +28 -1
  212. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_6byte.c +24 -2
  213. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_7_1_byte.c +39 -1
  214. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_7byte.c +25 -1
  215. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_8byte.c +14 -0
  216. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_9byte1.c +14 -1
  217. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_9byte2.c +14 -2
  218. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_double.c +19 -1
  219. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_float.c +19 -1
  220. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble.c +20 -1
  221. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble_split.c +40 -25
  222. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble_split2.c +40 -3
  223. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_pointer.c +19 -1
  224. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint16.c +18 -1
  225. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint32.c +18 -3
  226. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint64.c +18 -1
  227. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint16.c +18 -1
  228. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint32.c +19 -1
  229. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint64.c +19 -1
  230. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_dbls_struct.c +3 -1
  231. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_double_va.c +9 -1
  232. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_float.c +4 -0
  233. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_longdouble.c +11 -1
  234. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_longdouble_va.c +22 -3
  235. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_schar.c +5 -1
  236. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshort.c +6 -1
  237. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c +9 -1
  238. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_uchar.c +9 -1
  239. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushort.c +6 -2
  240. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c +9 -1
  241. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_pointer.c +5 -0
  242. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_pointer_stack.c +10 -0
  243. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_schar.c +3 -0
  244. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_sint.c +2 -0
  245. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_sshort.c +3 -0
  246. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_struct_va1.c +11 -0
  247. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uchar.c +3 -0
  248. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint.c +4 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint_va.c +4 -0
  250. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulong_va.c +4 -0
  251. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulonglong.c +2 -0
  252. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ushort.c +3 -0
  253. data/ext/ffi_c/libffi/testsuite/libffi.closures/ffitest.h +1 -138
  254. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +21 -21
  255. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct.c +32 -9
  256. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct1.c +1 -1
  257. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct10.c +12 -0
  258. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct11.c +21 -5
  259. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct12.c +86 -0
  260. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct13.c +115 -0
  261. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct2.c +10 -1
  262. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct3.c +10 -1
  263. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct4.c +9 -0
  264. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct5.c +9 -0
  265. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct6.c +11 -0
  266. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct7.c +9 -0
  267. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct8.c +11 -0
  268. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct9.c +11 -0
  269. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs1.c +86 -0
  270. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs2.c +102 -0
  271. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs3.c +101 -0
  272. data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_medium.c +1 -1
  273. data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_medium2.c +1 -1
  274. data/ext/ffi_c/libffi/testsuite/libffi.closures/testclosure.c +6 -1
  275. data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest.cc +2 -1
  276. data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc +1 -0
  277. data/ext/ffi_c/libffi.bsd.mk +2 -2
  278. data/ext/ffi_c/libffi.darwin.mk +2 -2
  279. data/ext/ffi_c/libffi.gnu.mk +2 -2
  280. data/ext/ffi_c/rbffi.h +1 -1
  281. data/ffi.gemspec +3 -3
  282. data/lib/ffi/autopointer.rb +8 -31
  283. data/lib/ffi/compat.rb +43 -0
  284. data/lib/ffi/data_converter.rb +2 -2
  285. data/lib/ffi/dynamic_library.rb +118 -0
  286. data/lib/ffi/enum.rb +18 -12
  287. data/lib/ffi/ffi.rb +3 -0
  288. data/lib/ffi/function.rb +71 -0
  289. data/lib/ffi/io.rb +2 -2
  290. data/lib/ffi/library.rb +72 -88
  291. data/lib/ffi/library_path.rb +109 -0
  292. data/lib/ffi/managedstruct.rb +1 -1
  293. data/lib/ffi/platform/aarch64-linux/types.conf +74 -3
  294. data/lib/ffi/platform/aarch64-windows/types.conf +52 -0
  295. data/lib/ffi/platform/hppa1.1-linux/types.conf +178 -0
  296. data/lib/ffi/platform/hppa2.0-linux/types.conf +178 -0
  297. data/lib/ffi/platform/loongarch64-linux/types.conf +141 -0
  298. data/lib/ffi/platform/sw_64-linux/types.conf +141 -0
  299. data/lib/ffi/platform.rb +15 -13
  300. data/lib/ffi/pointer.rb +6 -6
  301. data/lib/ffi/struct.rb +6 -5
  302. data/lib/ffi/struct_layout.rb +3 -3
  303. data/lib/ffi/struct_layout_builder.rb +9 -9
  304. data/lib/ffi/types.rb +65 -37
  305. data/lib/ffi/variadic.rb +19 -8
  306. data/lib/ffi/version.rb +1 -1
  307. data/samples/hello_ractor.rb +11 -0
  308. data/samples/qsort_ractor.rb +28 -0
  309. data/sig/ffi/abstract_memory.rbs +165 -0
  310. data/sig/ffi/auto_pointer.rbs +27 -0
  311. data/sig/ffi/buffer.rbs +18 -0
  312. data/sig/ffi/data_converter.rbs +10 -0
  313. data/sig/ffi/dynamic_library.rbs +9 -0
  314. data/sig/ffi/enum.rbs +38 -0
  315. data/sig/ffi/function.rbs +39 -0
  316. data/sig/ffi/library.rbs +42 -0
  317. data/sig/ffi/native_type.rbs +86 -0
  318. data/sig/ffi/pointer.rbs +42 -0
  319. data/sig/ffi/struct.rbs +76 -0
  320. data/sig/ffi/struct_by_reference.rbs +11 -0
  321. data/sig/ffi/struct_by_value.rbs +7 -0
  322. data/sig/ffi/struct_layout.rbs +9 -0
  323. data/sig/ffi/struct_layout_builder.rbs +5 -0
  324. data/sig/ffi/type.rbs +39 -0
  325. data/sig/ffi.rbs +26 -0
  326. data.tar.gz.sig +0 -0
  327. metadata +122 -28
  328. metadata.gz.sig +1 -0
  329. data/ext/ffi_c/libffi/.travis/build-cross-in-container.sh +0 -14
  330. data/ext/ffi_c/libffi/.travis/build.sh +0 -142
  331. data/ext/ffi_c/libffi/.travis.yml +0 -83
  332. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uchar_va.c +0 -44
  333. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ushort_va.c +0 -44
  334. /data/ext/ffi_c/libffi/{.travis → .ci}/ar-lib +0 -0
  335. /data/ext/ffi_c/libffi/{.travis → .ci}/bfin-sim.exp +0 -0
  336. /data/ext/ffi_c/libffi/{.travis → .ci}/compile +0 -0
  337. /data/ext/ffi_c/libffi/{.travis → .ci}/m32r-sim.exp +0 -0
  338. /data/ext/ffi_c/libffi/{.travis → .ci}/moxie-sim.exp +0 -0
  339. /data/ext/ffi_c/libffi/{.travis → .ci}/or1k-sim.exp +0 -0
  340. /data/ext/ffi_c/libffi/{.travis → .ci}/powerpc-eabisim.exp +0 -0
  341. /data/ext/ffi_c/libffi/{.travis → .ci}/wine-sim.exp +0 -0
  342. /data/ext/ffi_c/libffi/testsuite/libffi.call/{pyobjc-tc.c → pyobjc_tc.c} +0 -0
  343. /data/lib/ffi/platform/{sparc64-linux → sparcv9-linux}/types.conf +0 -0
data/ext/ffi_c/Struct.c CHANGED
@@ -61,13 +61,29 @@ typedef struct InlineArray_ {
61
61
  } InlineArray;
62
62
 
63
63
 
64
- static void struct_mark(Struct *);
65
- static void struct_free(Struct *);
64
+ static void struct_mark(void *data);
65
+ static void struct_compact(void *data);
66
+ static void struct_free(void *data);
67
+ static size_t struct_memsize(const void *);
66
68
  static VALUE struct_class_layout(VALUE klass);
67
- static void struct_malloc(Struct* s);
68
- static void inline_array_mark(InlineArray *);
69
- static void store_reference_value(StructField* f, Struct* s, VALUE value);
70
-
69
+ static void struct_malloc(VALUE self, Struct* s);
70
+ static void inline_array_mark(void *);
71
+ static void inline_array_compact(void *);
72
+ static size_t inline_array_memsize(const void *);
73
+ static void store_reference_value(VALUE self, StructField* f, Struct* s, VALUE value);
74
+
75
+ const rb_data_type_t rbffi_struct_data_type = { /* extern */
76
+ .wrap_struct_name = "FFI::Struct",
77
+ .function = {
78
+ .dmark = struct_mark,
79
+ .dfree = struct_free,
80
+ .dsize = struct_memsize,
81
+ ffi_compact_callback( struct_compact )
82
+ },
83
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
84
+ // macro to update VALUE references, as to trigger write barriers.
85
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
86
+ };
71
87
  VALUE rbffi_StructClass = Qnil;
72
88
 
73
89
  VALUE rbffi_StructInlineArrayClass = Qnil;
@@ -75,27 +91,31 @@ VALUE rbffi_StructLayoutCharArrayClass = Qnil;
75
91
 
76
92
  static ID id_pointer_ivar = 0, id_layout_ivar = 0;
77
93
  static ID id_get = 0, id_put = 0, id_to_ptr = 0, id_to_s = 0, id_layout = 0;
94
+ static ID id_initialize = 0;
78
95
 
79
96
  static inline char*
80
97
  memory_address(VALUE self)
81
98
  {
82
- return ((AbstractMemory *)DATA_PTR((self)))->address;
99
+ AbstractMemory *mem;
100
+ TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, mem);
101
+ return mem->address;
83
102
  }
84
103
 
85
104
  static VALUE
86
105
  struct_allocate(VALUE klass)
87
106
  {
88
107
  Struct* s;
89
- VALUE obj = Data_Make_Struct(klass, Struct, struct_mark, struct_free, s);
108
+ VALUE obj = TypedData_Make_Struct(klass, Struct, &rbffi_struct_data_type, s);
90
109
 
91
- s->rbPointer = Qnil;
92
- s->rbLayout = Qnil;
110
+ RB_OBJ_WRITE(obj, &s->rbPointer, Qnil);
111
+ RB_OBJ_WRITE(obj, &s->rbLayout, Qnil);
93
112
 
94
113
  return obj;
95
114
  }
96
115
 
97
116
  /*
98
117
  * call-seq: initialize
118
+ * @overload initialize
99
119
  * @overload initialize(pointer, *args)
100
120
  * @param [AbstractMemory] pointer
101
121
  * @param [Array] args
@@ -108,28 +128,29 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
108
128
  VALUE rbPointer = Qnil, rest = Qnil, klass = CLASS_OF(self);
109
129
  int nargs;
110
130
 
111
- Data_Get_Struct(self, Struct, s);
131
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
112
132
 
113
133
  nargs = rb_scan_args(argc, argv, "01*", &rbPointer, &rest);
114
134
 
115
135
  /* Call up into ruby code to adjust the layout */
116
136
  if (nargs > 1) {
117
- s->rbLayout = rb_funcall2(CLASS_OF(self), id_layout, (int) RARRAY_LEN(rest), RARRAY_PTR(rest));
137
+ VALUE rbLayout = rb_apply(CLASS_OF(self), id_layout, rest);
138
+ RB_OBJ_WRITE(self, &s->rbLayout, rbLayout);
118
139
  } else {
119
- s->rbLayout = struct_class_layout(klass);
140
+ RB_OBJ_WRITE(self, &s->rbLayout, struct_class_layout(klass));
120
141
  }
121
142
 
122
143
  if (!rb_obj_is_kind_of(s->rbLayout, rbffi_StructLayoutClass)) {
123
144
  rb_raise(rb_eRuntimeError, "Invalid Struct layout");
124
145
  }
125
146
 
126
- Data_Get_Struct(s->rbLayout, StructLayout, s->layout);
147
+ TypedData_Get_Struct(s->rbLayout, StructLayout, &rbffi_struct_layout_data_type, s->layout);
127
148
 
128
149
  if (rbPointer != Qnil) {
129
150
  s->pointer = MEMORY(rbPointer);
130
- s->rbPointer = rbPointer;
151
+ RB_OBJ_WRITE(self, &s->rbPointer, rbPointer);
131
152
  } else {
132
- struct_malloc(s);
153
+ struct_malloc(self, s);
133
154
  }
134
155
 
135
156
  return self;
@@ -146,13 +167,13 @@ struct_initialize_copy(VALUE self, VALUE other)
146
167
  Struct* src;
147
168
  Struct* dst;
148
169
 
149
- Data_Get_Struct(self, Struct, dst);
150
- Data_Get_Struct(other, Struct, src);
170
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, dst);
171
+ TypedData_Get_Struct(other, Struct, &rbffi_struct_data_type, src);
151
172
  if (dst == src) {
152
173
  return self;
153
174
  }
154
175
 
155
- dst->rbLayout = src->rbLayout;
176
+ RB_OBJ_WRITE(self, &dst->rbLayout, src->rbLayout);
156
177
  dst->layout = src->layout;
157
178
 
158
179
  /*
@@ -161,17 +182,22 @@ struct_initialize_copy(VALUE self, VALUE other)
161
182
  * be longer than just this struct.
162
183
  */
163
184
  if (src->pointer->address != NULL) {
164
- dst->rbPointer = rbffi_MemoryPointer_NewInstance(1, src->layout->size, false);
185
+ RB_OBJ_WRITE(self, &dst->rbPointer, rbffi_MemoryPointer_NewInstance(1, src->layout->size, false));
165
186
  dst->pointer = MEMORY(dst->rbPointer);
166
187
  memcpy(dst->pointer->address, src->pointer->address, src->layout->size);
167
188
  } else {
168
- dst->rbPointer = src->rbPointer;
189
+ RB_OBJ_WRITE(self, &dst->rbPointer, src->rbPointer);
169
190
  dst->pointer = src->pointer;
170
191
  }
171
192
 
172
193
  if (src->layout->referenceFieldCount > 0) {
194
+ size_t index;
195
+
173
196
  dst->rbReferences = ALLOC_N(VALUE, dst->layout->referenceFieldCount);
174
197
  memcpy(dst->rbReferences, src->rbReferences, dst->layout->referenceFieldCount * sizeof(VALUE));
198
+ for ( index = 0; index < dst->layout->referenceFieldCount; index++) {
199
+ RB_OBJ_WRITTEN(self, Qundef, &dst->rbReferences[index]);
200
+ }
175
201
  }
176
202
 
177
203
  return self;
@@ -196,14 +222,15 @@ struct_class_layout(VALUE klass)
196
222
  static StructLayout*
197
223
  struct_layout(VALUE self)
198
224
  {
199
- Struct* s = (Struct *) DATA_PTR(self);
225
+ Struct* s;
226
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
200
227
  if (s->layout != NULL) {
201
228
  return s->layout;
202
229
  }
203
230
 
204
231
  if (s->layout == NULL) {
205
- s->rbLayout = struct_class_layout(CLASS_OF(self));
206
- Data_Get_Struct(s->rbLayout, StructLayout, s->layout);
232
+ RB_OBJ_WRITE(self, &s->rbLayout, struct_class_layout(CLASS_OF(self)));
233
+ TypedData_Get_Struct(s->rbLayout, StructLayout, &rbffi_struct_layout_data_type, s->layout);
207
234
  }
208
235
 
209
236
  return s->layout;
@@ -213,52 +240,76 @@ static Struct*
213
240
  struct_validate(VALUE self)
214
241
  {
215
242
  Struct* s;
216
- Data_Get_Struct(self, Struct, s);
243
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
217
244
 
218
245
  if (struct_layout(self) == NULL) {
219
246
  rb_raise(rb_eRuntimeError, "struct layout == null");
220
247
  }
221
248
 
222
249
  if (s->pointer == NULL) {
223
- struct_malloc(s);
250
+ struct_malloc(self, s);
224
251
  }
225
252
 
226
253
  return s;
227
254
  }
228
255
 
229
256
  static void
230
- struct_malloc(Struct* s)
257
+ struct_malloc(VALUE self, Struct* s)
231
258
  {
232
259
  if (s->rbPointer == Qnil) {
233
- s->rbPointer = rbffi_MemoryPointer_NewInstance(s->layout->size, 1, true);
234
-
260
+ RB_OBJ_WRITE(self, &s->rbPointer, rbffi_MemoryPointer_NewInstance(s->layout->size, 1, true));
235
261
  } else if (!rb_obj_is_kind_of(s->rbPointer, rbffi_AbstractMemoryClass)) {
236
262
  rb_raise(rb_eRuntimeError, "invalid pointer in struct");
237
263
  }
238
264
 
239
- s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer);
265
+ TypedData_Get_Struct(s->rbPointer, AbstractMemory, &rbffi_abstract_memory_data_type, s->pointer);
240
266
  }
241
267
 
242
268
  static void
243
- struct_mark(Struct *s)
269
+ struct_mark(void *data)
244
270
  {
245
- rb_gc_mark(s->rbPointer);
246
- rb_gc_mark(s->rbLayout);
271
+ Struct *s = (Struct *)data;
272
+ rb_gc_mark_movable(s->rbPointer);
273
+ rb_gc_mark_movable(s->rbLayout);
247
274
  if (s->rbReferences != NULL) {
248
- rb_gc_mark_locations(&s->rbReferences[0], &s->rbReferences[s->layout->referenceFieldCount]);
275
+ size_t index;
276
+ for (index = 0; index < s->layout->referenceFieldCount; index++) {
277
+ rb_gc_mark_movable(s->rbReferences[index]);
278
+ }
279
+ }
280
+ }
281
+
282
+ static void
283
+ struct_compact(void *data)
284
+ {
285
+ Struct *s = (Struct *)data;
286
+ ffi_gc_location(s->rbPointer);
287
+ ffi_gc_location(s->rbLayout);
288
+ if (s->rbReferences != NULL) {
289
+ size_t index;
290
+ for (index = 0; index < s->layout->referenceFieldCount; index++) {
291
+ ffi_gc_location(s->rbReferences[index]);
292
+ }
249
293
  }
250
294
  }
251
295
 
252
296
  static void
253
- struct_free(Struct* s)
297
+ struct_free(void *data)
254
298
  {
299
+ Struct *s = (Struct *)data;
255
300
  xfree(s->rbReferences);
256
301
  xfree(s);
257
302
  }
258
303
 
304
+ static size_t
305
+ struct_memsize(const void *data)
306
+ {
307
+ const Struct *s = (const Struct *)data;
308
+ return sizeof(Struct) + (s->layout->referenceFieldCount * sizeof(VALUE));
309
+ }
259
310
 
260
311
  static void
261
- store_reference_value(StructField* f, Struct* s, VALUE value)
312
+ store_reference_value(VALUE self, StructField* f, Struct* s, VALUE value)
262
313
  {
263
314
  if (unlikely(f->referenceIndex == -1)) {
264
315
  rb_raise(rb_eRuntimeError, "put_reference_value called for non-reference type");
@@ -268,11 +319,11 @@ store_reference_value(StructField* f, Struct* s, VALUE value)
268
319
  int i;
269
320
  s->rbReferences = ALLOC_N(VALUE, s->layout->referenceFieldCount);
270
321
  for (i = 0; i < s->layout->referenceFieldCount; ++i) {
271
- s->rbReferences[i] = Qnil;
322
+ RB_OBJ_WRITE(self, &s->rbReferences[i], Qnil);
272
323
  }
273
324
  }
274
325
 
275
- s->rbReferences[f->referenceIndex] = value;
326
+ RB_OBJ_WRITE(self, &s->rbReferences[f->referenceIndex], value);
276
327
  }
277
328
 
278
329
 
@@ -290,8 +341,8 @@ struct_field(Struct* s, VALUE fieldName)
290
341
  rb_raise(rb_eArgError, "No such field '%s'", StringValueCStr(str));
291
342
  }
292
343
  /* Write the retrieved coder to the cache */
293
- p_ce->fieldName = fieldName;
294
- p_ce->field = (StructField *) DATA_PTR(rbField);
344
+ RB_OBJ_WRITE(s->rbLayout, &p_ce->fieldName, fieldName);
345
+ TypedData_Get_Struct(rbField, StructField, &rbffi_struct_field_data_type, p_ce->field);
295
346
  }
296
347
 
297
348
  return p_ce->field;
@@ -311,10 +362,7 @@ struct_aref(VALUE self, VALUE fieldName)
311
362
  s = struct_validate(self);
312
363
 
313
364
  f = struct_field(s, fieldName);
314
- if (f->get != NULL) {
315
- return (*f->get)(f, s);
316
-
317
- } else if (f->memoryOp != NULL) {
365
+ if (f->memoryOp != NULL) {
318
366
  return (*f->memoryOp->get)(s->pointer, f->offset);
319
367
 
320
368
  } else {
@@ -337,13 +385,11 @@ struct_aset(VALUE self, VALUE fieldName, VALUE value)
337
385
  Struct* s;
338
386
  StructField* f;
339
387
 
388
+ rb_check_frozen(self);
340
389
  s = struct_validate(self);
341
390
 
342
391
  f = struct_field(s, fieldName);
343
- if (f->put != NULL) {
344
- (*f->put)(f, s, value);
345
-
346
- } else if (f->memoryOp != NULL) {
392
+ if (f->memoryOp != NULL) {
347
393
 
348
394
  (*f->memoryOp->put)(s->pointer, f->offset, value);
349
395
 
@@ -357,7 +403,7 @@ struct_aset(VALUE self, VALUE fieldName, VALUE value)
357
403
  }
358
404
 
359
405
  if (f->referenceRequired) {
360
- store_reference_value(f, s, value);
406
+ store_reference_value(self, f, s, value);
361
407
  }
362
408
 
363
409
  return value;
@@ -376,6 +422,7 @@ struct_set_pointer(VALUE self, VALUE pointer)
376
422
  StructLayout* layout;
377
423
  AbstractMemory* memory;
378
424
 
425
+ rb_check_frozen(self);
379
426
  if (!rb_obj_is_kind_of(pointer, rbffi_AbstractMemoryClass)) {
380
427
  rb_raise(rb_eTypeError, "wrong argument type %s (expected Pointer or Buffer)",
381
428
  rb_obj_classname(pointer));
@@ -383,8 +430,8 @@ struct_set_pointer(VALUE self, VALUE pointer)
383
430
  }
384
431
 
385
432
 
386
- Data_Get_Struct(self, Struct, s);
387
- Data_Get_Struct(pointer, AbstractMemory, memory);
433
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
434
+ TypedData_Get_Struct(pointer, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
388
435
  layout = struct_layout(self);
389
436
 
390
437
  if ((int) layout->base.ffiType->size > memory->size) {
@@ -393,7 +440,7 @@ struct_set_pointer(VALUE self, VALUE pointer)
393
440
  }
394
441
 
395
442
  s->pointer = MEMORY(pointer);
396
- s->rbPointer = pointer;
443
+ RB_OBJ_WRITE(self, &s->rbPointer, pointer);
397
444
  rb_ivar_set(self, id_pointer_ivar, pointer);
398
445
 
399
446
  return self;
@@ -409,7 +456,7 @@ struct_get_pointer(VALUE self)
409
456
  {
410
457
  Struct* s;
411
458
 
412
- Data_Get_Struct(self, Struct, s);
459
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
413
460
 
414
461
  return s->rbPointer;
415
462
  }
@@ -424,15 +471,16 @@ static VALUE
424
471
  struct_set_layout(VALUE self, VALUE layout)
425
472
  {
426
473
  Struct* s;
427
- Data_Get_Struct(self, Struct, s);
474
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
428
475
 
476
+ rb_check_frozen(self);
429
477
  if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
430
478
  rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
431
479
  rb_obj_classname(layout), rb_class2name(rbffi_StructLayoutClass));
432
480
  return Qnil;
433
481
  }
434
482
 
435
- Data_Get_Struct(layout, StructLayout, s->layout);
483
+ TypedData_Get_Struct(layout, StructLayout, &rbffi_struct_layout_data_type, s->layout);
436
484
  rb_ivar_set(self, id_layout_ivar, layout);
437
485
 
438
486
  return self;
@@ -448,7 +496,7 @@ struct_get_layout(VALUE self)
448
496
  {
449
497
  Struct* s;
450
498
 
451
- Data_Get_Struct(self, Struct, s);
499
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
452
500
 
453
501
  return s->rbLayout;
454
502
  }
@@ -463,7 +511,7 @@ struct_null_p(VALUE self)
463
511
  {
464
512
  Struct* s;
465
513
 
466
- Data_Get_Struct(self, Struct, s);
514
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
467
515
 
468
516
  return s->pointer->address == NULL ? Qtrue : Qfalse;
469
517
  }
@@ -476,7 +524,7 @@ struct_order(int argc, VALUE* argv, VALUE self)
476
524
  {
477
525
  Struct* s;
478
526
 
479
- Data_Get_Struct(self, Struct, s);
527
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
480
528
  if (argc == 0) {
481
529
  return rb_funcall(s->rbPointer, rb_intern("order"), 0);
482
530
 
@@ -489,24 +537,52 @@ struct_order(int argc, VALUE* argv, VALUE self)
489
537
  }
490
538
  }
491
539
 
540
+ static const rb_data_type_t inline_array_data_type = {
541
+ .wrap_struct_name = "FFI::Struct::InlineArray",
542
+ .function = {
543
+ .dmark = inline_array_mark,
544
+ .dfree = RUBY_TYPED_DEFAULT_FREE,
545
+ .dsize = inline_array_memsize,
546
+ ffi_compact_callback( inline_array_compact )
547
+ },
548
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
549
+ // macro to update VALUE references, as to trigger write barriers.
550
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
551
+ };
552
+
492
553
  static VALUE
493
554
  inline_array_allocate(VALUE klass)
494
555
  {
495
556
  InlineArray* array;
496
557
  VALUE obj;
497
558
 
498
- obj = Data_Make_Struct(klass, InlineArray, inline_array_mark, -1, array);
499
- array->rbField = Qnil;
500
- array->rbMemory = Qnil;
559
+ obj = TypedData_Make_Struct(klass, InlineArray, &inline_array_data_type, array);
560
+ RB_OBJ_WRITE(obj, &array->rbMemory, Qnil);
561
+ RB_OBJ_WRITE(obj, &array->rbField, Qnil);
501
562
 
502
563
  return obj;
503
564
  }
504
565
 
505
566
  static void
506
- inline_array_mark(InlineArray* array)
567
+ inline_array_mark(void *data)
568
+ {
569
+ InlineArray *array = (InlineArray *)data;
570
+ rb_gc_mark_movable(array->rbField);
571
+ rb_gc_mark_movable(array->rbMemory);
572
+ }
573
+
574
+ static void
575
+ inline_array_compact(void *data)
576
+ {
577
+ InlineArray *array = (InlineArray *)data;
578
+ ffi_gc_location(array->rbField);
579
+ ffi_gc_location(array->rbMemory);
580
+ }
581
+
582
+ static size_t
583
+ inline_array_memsize(const void *data)
507
584
  {
508
- rb_gc_mark(array->rbField);
509
- rb_gc_mark(array->rbMemory);
585
+ return sizeof(InlineArray);
510
586
  }
511
587
 
512
588
  /*
@@ -521,14 +597,14 @@ inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField)
521
597
  {
522
598
  InlineArray* array;
523
599
 
524
- Data_Get_Struct(self, InlineArray, array);
525
- array->rbMemory = rbMemory;
526
- array->rbField = rbField;
600
+ TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
601
+ RB_OBJ_WRITE(self, &array->rbMemory, rbMemory);
602
+ RB_OBJ_WRITE(self, &array->rbField, rbField);
527
603
 
528
- Data_Get_Struct(rbMemory, AbstractMemory, array->memory);
529
- Data_Get_Struct(rbField, StructField, array->field);
530
- Data_Get_Struct(array->field->rbType, ArrayType, array->arrayType);
531
- Data_Get_Struct(array->arrayType->rbComponentType, Type, array->componentType);
604
+ TypedData_Get_Struct(rbMemory, AbstractMemory, &rbffi_abstract_memory_data_type, array->memory);
605
+ TypedData_Get_Struct(rbField, StructField, &rbffi_struct_field_data_type, array->field);
606
+ TypedData_Get_Struct(array->field->rbType, ArrayType, &rbffi_array_type_data_type, array->arrayType);
607
+ TypedData_Get_Struct(array->arrayType->rbComponentType, Type, &rbffi_type_data_type, array->componentType);
532
608
 
533
609
  array->op = get_memory_op(array->componentType);
534
610
  if (array->op == NULL && array->componentType->nativeType == NATIVE_MAPPED) {
@@ -542,7 +618,7 @@ inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField)
542
618
 
543
619
  /*
544
620
  * call-seq: size
545
- * @return [Numeric]
621
+ * @return [Integer]
546
622
  * Get size
547
623
  */
548
624
  static VALUE
@@ -550,7 +626,7 @@ inline_array_size(VALUE self)
550
626
  {
551
627
  InlineArray* array;
552
628
 
553
- Data_Get_Struct(self, InlineArray, array);
629
+ TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
554
630
 
555
631
  return UINT2NUM(((ArrayType *) array->field->type)->length);
556
632
  }
@@ -567,7 +643,7 @@ inline_array_offset(InlineArray* array, int index)
567
643
 
568
644
  /*
569
645
  * call-seq: [](index)
570
- * @param [Numeric] index
646
+ * @param [Integer] index
571
647
  * @return [Type, Struct]
572
648
  */
573
649
  static VALUE
@@ -575,7 +651,7 @@ inline_array_aref(VALUE self, VALUE rbIndex)
575
651
  {
576
652
  InlineArray* array;
577
653
 
578
- Data_Get_Struct(self, InlineArray, array);
654
+ TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
579
655
 
580
656
  if (array->op != NULL) {
581
657
  VALUE rbNativeValue = array->op->get(array->memory,
@@ -591,8 +667,12 @@ inline_array_aref(VALUE self, VALUE rbIndex)
591
667
  VALUE rbOffset = INT2NUM(inline_array_offset(array, NUM2INT(rbIndex)));
592
668
  VALUE rbLength = INT2NUM(array->componentType->ffiType->size);
593
669
  VALUE rbPointer = rb_funcall(array->rbMemory, rb_intern("slice"), 2, rbOffset, rbLength);
670
+ VALUE obj;
594
671
 
595
- return rb_class_new_instance(1, &rbPointer, ((StructByValue *) array->componentType)->rbStructClass);
672
+ /* We avoid rb_class_new_instance here, to avoid passing the method block */
673
+ obj = rb_obj_alloc(((StructByValue *) array->componentType)->rbStructClass);
674
+ rb_funcallv(obj, id_initialize, 1, &rbPointer);
675
+ return obj;
596
676
  } else {
597
677
 
598
678
  rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(array->arrayType->rbComponentType));
@@ -602,7 +682,7 @@ inline_array_aref(VALUE self, VALUE rbIndex)
602
682
 
603
683
  /*
604
684
  * call-seq: []=(index, value)
605
- * @param [Numeric] index
685
+ * @param [Integer] index
606
686
  * @param [Type, Struct]
607
687
  * @return [value]
608
688
  */
@@ -611,7 +691,8 @@ inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
611
691
  {
612
692
  InlineArray* array;
613
693
 
614
- Data_Get_Struct(self, InlineArray, array);
694
+ rb_check_frozen(self);
695
+ TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
615
696
 
616
697
  if (array->op != NULL) {
617
698
  if (unlikely(array->componentType->nativeType == NATIVE_MAPPED)) {
@@ -633,7 +714,7 @@ inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
633
714
  checkWrite(array->memory);
634
715
  checkBounds(array->memory, offset, array->componentType->ffiType->size);
635
716
 
636
- Data_Get_Struct(rbValue, Struct, s);
717
+ TypedData_Get_Struct(rbValue, Struct, &rbffi_struct_data_type, s);
637
718
  checkRead(s->pointer);
638
719
  checkBounds(s->pointer, 0, array->componentType->ffiType->size);
639
720
 
@@ -641,7 +722,7 @@ inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
641
722
 
642
723
  } else {
643
724
  ArrayType* arrayType;
644
- Data_Get_Struct(array->field->rbType, ArrayType, arrayType);
725
+ TypedData_Get_Struct(array->field->rbType, ArrayType, &rbffi_array_type_data_type, arrayType);
645
726
 
646
727
  rb_raise(rb_eArgError, "set not supported for %s", rb_obj_classname(arrayType->rbComponentType));
647
728
  return Qnil;
@@ -661,7 +742,7 @@ inline_array_each(VALUE self)
661
742
 
662
743
  int i;
663
744
 
664
- Data_Get_Struct(self, InlineArray, array);
745
+ TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
665
746
 
666
747
  for (i = 0; i < array->length; ++i) {
667
748
  rb_yield(inline_array_aref(self, INT2FIX(i)));
@@ -682,7 +763,7 @@ inline_array_to_a(VALUE self)
682
763
  VALUE obj;
683
764
  int i;
684
765
 
685
- Data_Get_Struct(self, InlineArray, array);
766
+ TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
686
767
  obj = rb_ary_new2(array->length);
687
768
 
688
769
 
@@ -705,7 +786,7 @@ inline_array_to_s(VALUE self)
705
786
  InlineArray* array;
706
787
  VALUE argv[2];
707
788
 
708
- Data_Get_Struct(self, InlineArray, array);
789
+ TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
709
790
 
710
791
  if (array->componentType->nativeType != NATIVE_INT8 && array->componentType->nativeType != NATIVE_UINT8) {
711
792
  VALUE dummy = Qnil;
@@ -728,7 +809,7 @@ inline_array_to_ptr(VALUE self)
728
809
  {
729
810
  InlineArray* array;
730
811
 
731
- Data_Get_Struct(self, InlineArray, array);
812
+ TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
732
813
 
733
814
  return rb_funcall(array->rbMemory, rb_intern("slice"), 2,
734
815
  UINT2NUM(array->field->offset), UINT2NUM(array->arrayType->base.ffiType->size));
@@ -818,5 +899,6 @@ rbffi_Struct_Init(VALUE moduleFFI)
818
899
  id_put = rb_intern("put");
819
900
  id_to_ptr = rb_intern("to_ptr");
820
901
  id_to_s = rb_intern("to_s");
902
+ id_initialize = rb_intern("initialize");
821
903
  }
822
904
 
data/ext/ffi_c/Struct.h CHANGED
@@ -42,6 +42,9 @@ extern "C" {
42
42
 
43
43
  extern void rbffi_Struct_Init(VALUE ffiModule);
44
44
  extern void rbffi_StructLayout_Init(VALUE ffiModule);
45
+ extern const rb_data_type_t rbffi_struct_layout_data_type;
46
+ extern const rb_data_type_t rbffi_struct_field_data_type;
47
+
45
48
  typedef struct StructField_ StructField;
46
49
  typedef struct StructLayout_ StructLayout;
47
50
  typedef struct Struct_ Struct;
@@ -56,9 +59,6 @@ extern "C" {
56
59
  VALUE rbType;
57
60
  VALUE rbName;
58
61
 
59
- VALUE (*get)(StructField* field, Struct* s);
60
- void (*put)(StructField* field, Struct* s, VALUE value);
61
-
62
62
  MemoryOp* memoryOp;
63
63
  };
64
64
 
@@ -75,11 +75,12 @@ extern "C" {
75
75
  * This avoids full ruby hash lookups for repeated lookups.
76
76
  */
77
77
  #define FIELD_CACHE_LOOKUP(this, sym) ( &(this)->cache_row[((sym) >> 8) & 0xff] )
78
+ #define FIELD_CACHE_ROWS 0x100
78
79
 
79
80
  struct field_cache_entry {
80
81
  VALUE fieldName;
81
82
  StructField *field;
82
- } cache_row[0x100];
83
+ } cache_row[FIELD_CACHE_ROWS];
83
84
 
84
85
  /** The number of reference tracking fields in this struct */
85
86
  int referenceFieldCount;
@@ -98,6 +99,8 @@ extern "C" {
98
99
  VALUE rbPointer;
99
100
  };
100
101
 
102
+ extern const rb_data_type_t rbffi_struct_data_type;
103
+ extern const rb_data_type_t rbffi_struct_field_data_type;
101
104
  extern VALUE rbffi_StructClass, rbffi_StructLayoutClass;
102
105
  extern VALUE rbffi_StructLayoutFieldClass, rbffi_StructLayoutFunctionFieldClass;
103
106
  extern VALUE rbffi_StructLayoutArrayFieldClass;