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/Type.c CHANGED
@@ -14,7 +14,7 @@
14
14
  * * Neither the name of the Ruby FFI project nor the
15
15
  * names of its contributors may be used to endorse or promote products
16
16
  * derived from this software without specific prior written permission.
17
- *
17
+ *
18
18
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
19
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
20
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -33,43 +33,81 @@
33
33
 
34
34
  #include <sys/types.h>
35
35
  #include <ruby.h>
36
+ #if HAVE_RB_EXT_RACTOR_SAFE
37
+ #include <ruby/ractor.h>
38
+ #endif
36
39
  #include <ffi.h>
37
40
  #include "rbffi.h"
38
41
  #include "compat.h"
39
42
  #include "Types.h"
40
43
  #include "Type.h"
41
44
 
45
+ static size_t type_memsize(const void *);
42
46
 
43
47
  typedef struct BuiltinType_ {
44
48
  Type type;
45
- char* name;
49
+ const char* name;
46
50
  } BuiltinType;
47
51
 
48
- static void builtin_type_free(BuiltinType *);
52
+ static size_t builtin_type_memsize(const void *);
49
53
 
50
54
  VALUE rbffi_TypeClass = Qnil;
51
55
 
52
56
  static VALUE classBuiltinType = Qnil;
53
57
  static VALUE moduleNativeType = Qnil;
54
- static VALUE typeMap = Qnil, sizeMap = Qnil;
55
- static ID id_find_type = 0, id_type_size = 0, id_size = 0;
58
+ static VALUE typeMap = Qnil;
59
+ static ID id_type_size = 0, id_size = 0;
60
+ #if HAVE_RB_EXT_RACTOR_SAFE
61
+ static rb_ractor_local_key_t custom_typedefs_key;
62
+ #endif
63
+
64
+ const rb_data_type_t rbffi_type_data_type = { /* extern */
65
+ .wrap_struct_name = "FFI::Type",
66
+ .function = {
67
+ .dmark = NULL,
68
+ .dfree = RUBY_TYPED_DEFAULT_FREE,
69
+ .dsize = type_memsize,
70
+ },
71
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
72
+ // macro to update VALUE references, as to trigger write barriers.
73
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
74
+ };
75
+
76
+ static const rb_data_type_t builtin_type_data_type = {
77
+ .wrap_struct_name = "FFI::Type::Builtin",
78
+ .function = {
79
+ .dmark = NULL,
80
+ .dfree = RUBY_TYPED_DEFAULT_FREE,
81
+ .dsize = builtin_type_memsize,
82
+ },
83
+ .parent = &rbffi_type_data_type,
84
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
85
+ // macro to update VALUE references, as to trigger write barriers.
86
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
87
+ };
88
+
89
+ static size_t
90
+ type_memsize(const void *data)
91
+ {
92
+ return sizeof(Type);
93
+ }
56
94
 
57
95
  static VALUE
58
96
  type_allocate(VALUE klass)
59
97
  {
60
98
  Type* type;
61
- VALUE obj = Data_Make_Struct(klass, Type, NULL, -1, type);
99
+ VALUE obj = TypedData_Make_Struct(klass, Type, &rbffi_type_data_type, type);
62
100
 
63
101
  type->nativeType = -1;
64
102
  type->ffiType = &ffi_type_void;
65
-
103
+
66
104
  return obj;
67
105
  }
68
106
 
69
107
  /*
70
108
  * Document-method: initialize
71
109
  * call-seq: initialize(value)
72
- * @param [Fixnum,Type] value
110
+ * @param [Integer,Type] value
73
111
  * @return [self]
74
112
  */
75
113
  static VALUE
@@ -78,24 +116,26 @@ type_initialize(VALUE self, VALUE value)
78
116
  Type* type;
79
117
  Type* other;
80
118
 
81
- Data_Get_Struct(self, Type, type);
119
+ TypedData_Get_Struct(self, Type, &rbffi_type_data_type, type);
82
120
 
83
121
  if (FIXNUM_P(value)) {
84
122
  type->nativeType = FIX2INT(value);
85
123
  } else if (rb_obj_is_kind_of(value, rbffi_TypeClass)) {
86
- Data_Get_Struct(value, Type, other);
124
+ TypedData_Get_Struct(value, Type, &rbffi_type_data_type, other);
87
125
  type->nativeType = other->nativeType;
88
126
  type->ffiType = other->ffiType;
89
127
  } else {
90
128
  rb_raise(rb_eArgError, "wrong type");
91
129
  }
92
-
130
+
131
+ rb_obj_freeze(self);
132
+
93
133
  return self;
94
134
  }
95
135
 
96
136
  /*
97
137
  * call-seq: type.size
98
- * @return [Fixnum]
138
+ * @return [Integer]
99
139
  * Return type's size, in bytes.
100
140
  */
101
141
  static VALUE
@@ -103,14 +143,14 @@ type_size(VALUE self)
103
143
  {
104
144
  Type *type;
105
145
 
106
- Data_Get_Struct(self, Type, type);
146
+ TypedData_Get_Struct(self, Type, &rbffi_type_data_type, type);
107
147
 
108
148
  return INT2FIX(type->ffiType->size);
109
149
  }
110
150
 
111
151
  /*
112
152
  * call-seq: type.alignment
113
- * @return [Fixnum]
153
+ * @return [Integer]
114
154
  * Get Type alignment.
115
155
  */
116
156
  static VALUE
@@ -118,7 +158,7 @@ type_alignment(VALUE self)
118
158
  {
119
159
  Type *type;
120
160
 
121
- Data_Get_Struct(self, Type, type);
161
+ TypedData_Get_Struct(self, Type, &rbffi_type_data_type, type);
122
162
 
123
163
  return INT2FIX(type->ffiType->alignment);
124
164
  }
@@ -134,9 +174,9 @@ type_inspect(VALUE self)
134
174
  char buf[100];
135
175
  Type *type;
136
176
 
137
- Data_Get_Struct(self, Type, type);
177
+ TypedData_Get_Struct(self, Type, &rbffi_type_data_type, type);
138
178
 
139
- snprintf(buf, sizeof(buf), "#<%s:%p size=%d alignment=%d>",
179
+ snprintf(buf, sizeof(buf), "#<%s::%p size=%d alignment=%d>",
140
180
  rb_obj_classname(self), type, (int) type->ffiType->size, (int) type->ffiType->alignment);
141
181
 
142
182
  return rb_str_new2(buf);
@@ -148,20 +188,21 @@ builtin_type_new(VALUE klass, int nativeType, ffi_type* ffiType, const char* nam
148
188
  BuiltinType* type;
149
189
  VALUE obj = Qnil;
150
190
 
151
- obj = Data_Make_Struct(klass, BuiltinType, NULL, builtin_type_free, type);
152
-
153
- type->name = strdup(name);
191
+ obj = TypedData_Make_Struct(klass, BuiltinType, &builtin_type_data_type, type);
192
+
193
+ type->name = name;
154
194
  type->type.nativeType = nativeType;
155
195
  type->type.ffiType = ffiType;
156
196
 
197
+ rb_obj_freeze(obj);
198
+
157
199
  return obj;
158
200
  }
159
201
 
160
- static void
161
- builtin_type_free(BuiltinType *type)
202
+ static size_t
203
+ builtin_type_memsize(const void *data)
162
204
  {
163
- free(type->name);
164
- xfree(type);
205
+ return sizeof(BuiltinType) + sizeof(ffi_type);
165
206
  }
166
207
 
167
208
  /*
@@ -175,8 +216,8 @@ builtin_type_inspect(VALUE self)
175
216
  char buf[100];
176
217
  BuiltinType *type;
177
218
 
178
- Data_Get_Struct(self, BuiltinType, type);
179
- snprintf(buf, sizeof(buf), "#<%s:%s size=%d alignment=%d>",
219
+ TypedData_Get_Struct(self, BuiltinType, &builtin_type_data_type, type);
220
+ snprintf(buf, sizeof(buf), "#<%s::%s size=%d alignment=%d>",
180
221
  rb_obj_classname(self), type->name, (int) type->type.ffiType->size, type->type.ffiType->alignment);
181
222
 
182
223
  return rb_str_new2(buf);
@@ -186,21 +227,21 @@ int
186
227
  rbffi_type_size(VALUE type)
187
228
  {
188
229
  int t = TYPE(type);
189
-
230
+
190
231
  if (t == T_FIXNUM || t == T_BIGNUM) {
191
232
  return NUM2INT(type);
192
-
233
+
193
234
  } else if (t == T_SYMBOL) {
194
235
  /*
195
- * Try looking up directly in the type and size maps
236
+ * Try looking up directly in the type map
196
237
  */
197
238
  VALUE nType;
198
239
  if ((nType = rb_hash_lookup(typeMap, type)) != Qnil) {
199
240
  if (rb_obj_is_kind_of(nType, rbffi_TypeClass)) {
200
241
  Type* type;
201
- Data_Get_Struct(nType, Type, type);
242
+ TypedData_Get_Struct(nType, Type, &rbffi_type_data_type, type);
202
243
  return (int) type->ffiType->size;
203
-
244
+
204
245
  } else if (rb_respond_to(nType, id_size)) {
205
246
  return NUM2INT(rb_funcall2(nType, id_size, 0, NULL));
206
247
  }
@@ -208,26 +249,51 @@ rbffi_type_size(VALUE type)
208
249
 
209
250
  /* Not found - call up to the ruby version to resolve */
210
251
  return NUM2INT(rb_funcall2(rbffi_FFIModule, id_type_size, 1, &type));
211
-
252
+
212
253
  } else {
213
254
  return NUM2INT(rb_funcall2(type, id_size, 0, NULL));
214
255
  }
215
256
  }
216
257
 
258
+ static VALUE
259
+ custom_typedefs(VALUE self)
260
+ {
261
+ #if HAVE_RB_EXT_RACTOR_SAFE
262
+ VALUE hash = rb_ractor_local_storage_value(custom_typedefs_key);
263
+ if (hash == Qnil) {
264
+ hash = rb_hash_new();
265
+ rb_ractor_local_storage_value_set(custom_typedefs_key, hash);
266
+ }
267
+ #else
268
+ static VALUE hash = Qundef;
269
+ if (hash == Qundef) {
270
+ rb_global_variable(&hash);
271
+ hash = rb_hash_new();
272
+ }
273
+ #endif
274
+ return hash;
275
+ }
276
+
217
277
  VALUE
218
278
  rbffi_Type_Lookup(VALUE name)
219
279
  {
220
280
  int t = TYPE(name);
221
281
  if (t == T_SYMBOL || t == T_STRING) {
222
282
  /*
223
- * Try looking up directly in the type Map
283
+ * Try looking up directly in the type map
224
284
  */
225
285
  VALUE nType;
286
+ VALUE cust = custom_typedefs(Qnil);
287
+
288
+ if ((nType = rb_hash_lookup(cust, name)) != Qnil && rb_obj_is_kind_of(nType, rbffi_TypeClass)) {
289
+ return nType;
290
+ }
291
+
226
292
  if ((nType = rb_hash_lookup(typeMap, name)) != Qnil && rb_obj_is_kind_of(nType, rbffi_TypeClass)) {
227
293
  return nType;
228
294
  }
229
295
  } else if (rb_obj_is_kind_of(name, rbffi_TypeClass)) {
230
-
296
+
231
297
  return name;
232
298
  }
233
299
 
@@ -251,13 +317,15 @@ rbffi_Type_Init(VALUE moduleFFI)
251
317
  * Document-constant: FFI::TypeDefs
252
318
  */
253
319
  rb_define_const(moduleFFI, "TypeDefs", typeMap = rb_hash_new());
254
- rb_define_const(moduleFFI, "SizeTypes", sizeMap = rb_hash_new());
255
320
  rb_global_variable(&typeMap);
256
- rb_global_variable(&sizeMap);
257
- id_find_type = rb_intern("find_type");
258
321
  id_type_size = rb_intern("type_size");
259
322
  id_size = rb_intern("size");
260
323
 
324
+ #if HAVE_RB_EXT_RACTOR_SAFE
325
+ custom_typedefs_key = rb_ractor_local_storage_value_newkey();
326
+ #endif
327
+ rb_define_module_function(moduleFFI, "custom_typedefs", custom_typedefs, 0);
328
+
261
329
  /*
262
330
  * Document-class: FFI::Type::Builtin
263
331
  * Class for Built-in types.
@@ -265,10 +333,10 @@ rbffi_Type_Init(VALUE moduleFFI)
265
333
  classBuiltinType = rb_define_class_under(rbffi_TypeClass, "Builtin", rbffi_TypeClass);
266
334
  /*
267
335
  * Document-module: FFI::NativeType
268
- * This module defines constants for native (C) types.
336
+ * This module defines constants for C native types.
269
337
  *
270
338
  * ==Native type constants
271
- * Native types are defined by constants :
339
+ * Native types are defined by constants and aliases:
272
340
  * * INT8, SCHAR, CHAR
273
341
  * * UINT8, UCHAR
274
342
  * * INT16, SHORT, SSHORT
@@ -281,24 +349,25 @@ rbffi_Type_Init(VALUE moduleFFI)
281
349
  * * ULONG
282
350
  * * FLOAT32, FLOAT
283
351
  * * FLOAT64, DOUBLE
352
+ * * LONGDOUBLE (if the native platform has `long double`)
284
353
  * * POINTER
285
- * * CALLBACK
286
- * * FUNCTION
287
- * * CHAR_ARRAY
288
354
  * * BOOL
289
- * * STRING (immutable string, nul terminated)
290
- * * STRUCT (struct-b-value param or result)
291
- * * ARRAY (array type definition)
292
- * * MAPPED (custom native type)
293
- * For function return type only :
355
+ * * STRING (immutable string, null terminated)
356
+ * For function return type only:
294
357
  * * VOID
295
- * For function argument type only :
358
+ * For function argument type only:
296
359
  * * BUFFER_IN
297
360
  * * BUFFER_OUT
361
+ * * BUFFER_INOUT
298
362
  * * VARARGS (function takes a variable number of arguments)
299
363
  *
300
- * All these constants are exported to {FFI} module prefixed with "TYPE_".
301
- * They are objets from {FFI::Type::Builtin} class.
364
+ * They are objects of the class {FFI::Type::Builtin}.
365
+ *
366
+ * Non-alias (the first name in each bullet point) constants are also exported to modules +FFI::NativeType+ and (prefixed with +TYPE_+) {FFI}.
367
+ * All constants and aliases above are exported to the {FFI::Type} class, as well as the following aliases:
368
+ * * Array ({FFI::ArrayType})
369
+ * * Function ({FFI::FunctionType})
370
+ * * Struct ({FFI::StructByValue})
302
371
  */
303
372
  moduleNativeType = rb_define_module_under(moduleFFI, "NativeType");
304
373
 
@@ -318,7 +387,7 @@ rbffi_Type_Init(VALUE moduleFFI)
318
387
  /* Make Type::Builtin non-allocatable */
319
388
  rb_undef_method(CLASS_OF(classBuiltinType), "new");
320
389
  rb_define_method(classBuiltinType, "inspect", builtin_type_inspect, 0);
321
-
390
+
322
391
  rb_global_variable(&rbffi_TypeClass);
323
392
  rb_global_variable(&classBuiltinType);
324
393
 
data/ext/ffi_c/Type.h CHANGED
@@ -44,7 +44,7 @@ extern "C" {
44
44
  typedef struct Type_ Type;
45
45
 
46
46
  #include "Types.h"
47
-
47
+
48
48
  struct Type_ {
49
49
  NativeType nativeType;
50
50
  ffi_type* ffiType;
@@ -53,6 +53,8 @@ struct Type_ {
53
53
  extern VALUE rbffi_TypeClass;
54
54
  extern VALUE rbffi_Type_Lookup(VALUE type);
55
55
 
56
+ extern const rb_data_type_t rbffi_type_data_type;
57
+
56
58
  #ifdef __cplusplus
57
59
  }
58
60
  #endif
data/ext/ffi_c/Types.c CHANGED
@@ -41,6 +41,7 @@
41
41
  #include "LongDouble.h"
42
42
 
43
43
  static ID id_from_native = 0;
44
+ static ID id_initialize = 0;
44
45
 
45
46
 
46
47
  VALUE
@@ -95,14 +96,18 @@ rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr)
95
96
  case NATIVE_STRUCT: {
96
97
  StructByValue* sbv = (StructByValue *)type;
97
98
  AbstractMemory* mem;
99
+ VALUE obj;
98
100
  VALUE rbMemory = rbffi_MemoryPointer_NewInstance(1, sbv->base.ffiType->size, false);
99
101
 
100
- Data_Get_Struct(rbMemory, AbstractMemory, mem);
102
+ TypedData_Get_Struct(rbMemory, AbstractMemory, &rbffi_abstract_memory_data_type, mem);
101
103
  memcpy(mem->address, ptr, sbv->base.ffiType->size);
102
104
  RB_GC_GUARD(rbMemory);
103
105
  RB_GC_GUARD(rbType);
104
106
 
105
- return rb_class_new_instance(1, &rbMemory, sbv->rbStructClass);
107
+ /* We avoid rb_class_new_instance here, to avoid passing the method block */
108
+ obj = rb_obj_alloc(sbv->rbStructClass);
109
+ rb_funcallv(obj, id_initialize, 1, &rbMemory);
110
+ return obj;
106
111
  }
107
112
 
108
113
  case NATIVE_MAPPED: {
@@ -134,5 +139,6 @@ void
134
139
  rbffi_Types_Init(VALUE moduleFFI)
135
140
  {
136
141
  id_from_native = rb_intern("from_native");
142
+ id_initialize = rb_intern("initialize");
137
143
  }
138
144
 
data/ext/ffi_c/Types.h CHANGED
@@ -55,7 +55,6 @@ typedef enum {
55
55
  NATIVE_BUFFER_IN,
56
56
  NATIVE_BUFFER_OUT,
57
57
  NATIVE_BUFFER_INOUT,
58
- NATIVE_CHAR_ARRAY,
59
58
  NATIVE_BOOL,
60
59
 
61
60
  /** An immutable string. Nul terminated, but only copies in to the native function */
data/ext/ffi_c/Variadic.c CHANGED
@@ -36,6 +36,9 @@
36
36
  #include <stdint.h>
37
37
  #include <stdbool.h>
38
38
  #include <ruby.h>
39
+ #if HAVE_RB_EXT_RACTOR_SAFE
40
+ #include <ruby/ractor.h>
41
+ #endif
39
42
 
40
43
  #include <ffi.h>
41
44
  #include "rbffi.h"
@@ -62,35 +65,65 @@ typedef struct VariadicInvoker_ {
62
65
  bool blocking;
63
66
  } VariadicInvoker;
64
67
 
65
-
66
68
  static VALUE variadic_allocate(VALUE klass);
67
69
  static VALUE variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes,
68
70
  VALUE rbReturnType, VALUE options);
69
- static void variadic_mark(VariadicInvoker *);
71
+ static void variadic_mark(void *);
72
+ static void variadic_compact(void *);
73
+ static size_t variadic_memsize(const void *);
70
74
 
71
75
  static VALUE classVariadicInvoker = Qnil;
72
76
 
77
+ static const rb_data_type_t variadic_data_type = {
78
+ .wrap_struct_name = "FFI::VariadicInvoker",
79
+ .function = {
80
+ .dmark = variadic_mark,
81
+ .dfree = RUBY_TYPED_DEFAULT_FREE,
82
+ .dsize = variadic_memsize,
83
+ ffi_compact_callback( variadic_compact )
84
+ },
85
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
86
+ // macro to update VALUE references, as to trigger write barriers.
87
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
88
+ };
89
+
73
90
 
74
91
  static VALUE
75
92
  variadic_allocate(VALUE klass)
76
93
  {
77
94
  VariadicInvoker *invoker;
78
- VALUE obj = Data_Make_Struct(klass, VariadicInvoker, variadic_mark, -1, invoker);
95
+ VALUE obj = TypedData_Make_Struct(klass, VariadicInvoker, &variadic_data_type, invoker);
79
96
 
80
- invoker->rbAddress = Qnil;
81
- invoker->rbEnums = Qnil;
82
- invoker->rbReturnType = Qnil;
97
+ RB_OBJ_WRITE(obj, &invoker->rbAddress, Qnil);
98
+ RB_OBJ_WRITE(obj, &invoker->rbEnums, Qnil);
99
+ RB_OBJ_WRITE(obj, &invoker->rbReturnType, Qnil);
83
100
  invoker->blocking = false;
84
101
 
85
102
  return obj;
86
103
  }
87
104
 
88
105
  static void
89
- variadic_mark(VariadicInvoker *invoker)
106
+ variadic_mark(void *data)
107
+ {
108
+ VariadicInvoker *invoker = (VariadicInvoker *)data;
109
+ rb_gc_mark_movable(invoker->rbEnums);
110
+ rb_gc_mark_movable(invoker->rbAddress);
111
+ rb_gc_mark_movable(invoker->rbReturnType);
112
+ }
113
+
114
+ static void
115
+ variadic_compact(void *data)
90
116
  {
91
- rb_gc_mark(invoker->rbEnums);
92
- rb_gc_mark(invoker->rbAddress);
93
- rb_gc_mark(invoker->rbReturnType);
117
+ VariadicInvoker *invoker = (VariadicInvoker *)data;
118
+ ffi_gc_location(invoker->rbEnums);
119
+ ffi_gc_location(invoker->rbAddress);
120
+ ffi_gc_location(invoker->rbReturnType);
121
+ }
122
+
123
+ static size_t
124
+ variadic_memsize(const void *data)
125
+ {
126
+ return sizeof(VariadicInvoker);
94
127
  }
95
128
 
96
129
  static VALUE
@@ -108,10 +141,10 @@ variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE
108
141
  Check_Type(options, T_HASH);
109
142
  convention = rb_hash_aref(options, ID2SYM(rb_intern("convention")));
110
143
 
111
- Data_Get_Struct(self, VariadicInvoker, invoker);
112
- invoker->rbEnums = rb_hash_aref(options, ID2SYM(rb_intern("enums")));
113
- invoker->rbAddress = rbFunction;
114
- invoker->function = rbffi_AbstractMemory_Cast(rbFunction, rbffi_PointerClass)->address;
144
+ TypedData_Get_Struct(self, VariadicInvoker, &variadic_data_type, invoker);
145
+ RB_OBJ_WRITE(self, &invoker->rbEnums, rb_hash_aref(options, ID2SYM(rb_intern("enums"))));
146
+ RB_OBJ_WRITE(self, &invoker->rbAddress, rbFunction);
147
+ invoker->function = rbffi_AbstractMemory_Cast(rbFunction, &rbffi_pointer_data_type)->address;
115
148
  invoker->blocking = RTEST(rb_hash_aref(options, ID2SYM(rb_intern("blocking"))));
116
149
 
117
150
  #if defined(X86_WIN32)
@@ -122,13 +155,13 @@ variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE
122
155
  invoker->abi = FFI_DEFAULT_ABI;
123
156
  #endif
124
157
 
125
- invoker->rbReturnType = rbffi_Type_Lookup(rbReturnType);
158
+ RB_OBJ_WRITE(self, &invoker->rbReturnType, rbffi_Type_Lookup(rbReturnType));
126
159
  if (!RTEST(invoker->rbReturnType)) {
127
160
  VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
128
161
  rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
129
162
  }
130
163
 
131
- Data_Get_Struct(rbReturnType, Type, invoker->returnType);
164
+ TypedData_Get_Struct(rbReturnType, Type, &rbffi_type_data_type, invoker->returnType);
132
165
 
133
166
  invoker->paramCount = -1;
134
167
 
@@ -142,7 +175,7 @@ variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE
142
175
  VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL);
143
176
  rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName));
144
177
  }
145
- Data_Get_Struct(rbType, Type, type);
178
+ TypedData_Get_Struct(rbType, Type, &rbffi_type_data_type, type);
146
179
  if (type->nativeType != NATIVE_VARARGS) {
147
180
  rb_ary_push(fixed, entry);
148
181
  }
@@ -150,7 +183,7 @@ variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE
150
183
  /*
151
184
  * @fixed and @type_map are used by the parameter mangling ruby code
152
185
  */
153
- rb_iv_set(self, "@fixed", fixed);
186
+ rb_iv_set(self, "@fixed", rb_obj_freeze(fixed));
154
187
  rb_iv_set(self, "@type_map", rb_hash_aref(options, ID2SYM(rb_intern("type_map"))));
155
188
 
156
189
  return retval;
@@ -169,6 +202,7 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
169
202
  Type** paramTypes;
170
203
  VALUE* argv;
171
204
  VALUE* callbackParameters;
205
+ VALUE callbackProc;
172
206
  int paramCount = 0, fixedCount = 0, callbackCount = 0, i;
173
207
  ffi_status ffiStatus;
174
208
  rbffi_frame_t frame = { 0 };
@@ -176,8 +210,8 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
176
210
  Check_Type(parameterTypes, T_ARRAY);
177
211
  Check_Type(parameterValues, T_ARRAY);
178
212
 
179
- Data_Get_Struct(self, VariadicInvoker, invoker);
180
- paramCount = (int) RARRAY_LEN(parameterTypes);
213
+ TypedData_Get_Struct(self, VariadicInvoker, &variadic_data_type, invoker);
214
+ paramCount = RARRAY_LENINT(parameterTypes);
181
215
  paramTypes = ALLOCA_N(Type *, paramCount);
182
216
  ffiParamTypes = ALLOCA_N(ffi_type *, paramCount);
183
217
  params = ALLOCA_N(FFIStorage, paramCount);
@@ -192,25 +226,25 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
192
226
  if (!rb_obj_is_kind_of(rbType, rbffi_TypeClass)) {
193
227
  rb_raise(rb_eTypeError, "wrong type. Expected (FFI::Type)");
194
228
  }
195
- Data_Get_Struct(rbType, Type, paramTypes[i]);
229
+ TypedData_Get_Struct(rbType, Type, &rbffi_type_data_type, paramTypes[i]);
196
230
 
197
231
  switch (paramTypes[i]->nativeType) {
198
232
  case NATIVE_INT8:
199
233
  case NATIVE_INT16:
200
234
  case NATIVE_INT32:
201
235
  rbType = rb_const_get(rbffi_TypeClass, rb_intern("INT32"));
202
- Data_Get_Struct(rbType, Type, paramTypes[i]);
236
+ TypedData_Get_Struct(rbType, Type, &rbffi_type_data_type, paramTypes[i]);
203
237
  break;
204
238
  case NATIVE_UINT8:
205
239
  case NATIVE_UINT16:
206
240
  case NATIVE_UINT32:
207
241
  rbType = rb_const_get(rbffi_TypeClass, rb_intern("UINT32"));
208
- Data_Get_Struct(rbType, Type, paramTypes[i]);
242
+ TypedData_Get_Struct(rbType, Type, &rbffi_type_data_type, paramTypes[i]);
209
243
  break;
210
244
 
211
245
  case NATIVE_FLOAT32:
212
246
  rbType = rb_const_get(rbffi_TypeClass, rb_intern("DOUBLE"));
213
- Data_Get_Struct(rbType, Type, paramTypes[i]);
247
+ TypedData_Get_Struct(rbType, Type, &rbffi_type_data_type, paramTypes[i]);
214
248
  break;
215
249
 
216
250
  case NATIVE_FUNCTION:
@@ -257,8 +291,9 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
257
291
  rb_raise(rb_eArgError, "Unknown FFI error");
258
292
  }
259
293
 
260
- rbffi_SetupCallParams(paramCount, argv, -1, paramTypes, params,
261
- ffiValues, callbackParameters, callbackCount, invoker->rbEnums);
294
+ callbackProc = rbffi_SetupCallParams(paramCount, argv, -1, paramTypes, params,
295
+ ffiValues, callbackParameters, callbackCount,
296
+ invoker->rbEnums);
262
297
 
263
298
  rbffi_frame_push(&frame);
264
299
 
@@ -276,6 +311,7 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
276
311
  } else {
277
312
  ffi_call(&cif, FFI_FN(invoker->function), retval, ffiValues);
278
313
  }
314
+ RB_GC_GUARD(callbackProc);
279
315
 
280
316
  rbffi_frame_pop(&frame);
281
317
 
@@ -288,6 +324,14 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
288
324
  return rbffi_NativeValue_ToRuby(invoker->returnType, invoker->rbReturnType, retval);
289
325
  }
290
326
 
327
+ static VALUE
328
+ variadic_return_type(VALUE self)
329
+ {
330
+ VariadicInvoker* invoker;
331
+
332
+ TypedData_Get_Struct(self, VariadicInvoker, &variadic_data_type, invoker);
333
+ return invoker->rbReturnType;
334
+ }
291
335
 
292
336
  void
293
337
  rbffi_Variadic_Init(VALUE moduleFFI)
@@ -299,5 +343,6 @@ rbffi_Variadic_Init(VALUE moduleFFI)
299
343
 
300
344
  rb_define_method(classVariadicInvoker, "initialize", variadic_initialize, 4);
301
345
  rb_define_method(classVariadicInvoker, "invoke", variadic_invoke, 2);
346
+ rb_define_method(classVariadicInvoker, "return_type", variadic_return_type, 0);
302
347
  }
303
348