ffi 1.17.0 → 1.17.4

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 (359) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +51 -0
  4. data/Gemfile +8 -3
  5. data/README.md +1 -0
  6. data/Rakefile +8 -5
  7. data/Steepfile +8 -0
  8. data/ext/ffi_c/DynamicLibrary.c +1 -1
  9. data/ext/ffi_c/Function.c +54 -34
  10. data/ext/ffi_c/MethodHandle.c +4 -2
  11. data/ext/ffi_c/StructLayout.c +129 -12
  12. data/ext/ffi_c/libffi/LICENSE +1 -1
  13. data/ext/ffi_c/libffi/Makefile.am +20 -15
  14. data/ext/ffi_c/libffi/Makefile.in +41 -54
  15. data/ext/ffi_c/libffi/README.md +40 -4
  16. data/ext/ffi_c/libffi/acinclude.m4 +6 -0
  17. data/ext/ffi_c/libffi/config.guess +80 -22
  18. data/ext/ffi_c/libffi/config.sub +161 -80
  19. data/ext/ffi_c/libffi/configure +135 -135
  20. data/ext/ffi_c/libffi/configure.ac +28 -14
  21. data/ext/ffi_c/libffi/configure.host +6 -6
  22. data/ext/ffi_c/libffi/doc/Makefile.in +4 -0
  23. data/ext/ffi_c/libffi/doc/libffi.texi +27 -4
  24. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  25. data/ext/ffi_c/libffi/fficonfig.h.in +3 -3
  26. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -28
  27. data/ext/ffi_c/libffi/include/Makefile.in +4 -0
  28. data/ext/ffi_c/libffi/include/ffi.h.in +19 -1
  29. data/ext/ffi_c/libffi/include/ffi_cfi.h +2 -0
  30. data/ext/ffi_c/libffi/include/ffi_common.h +17 -0
  31. data/ext/ffi_c/libffi/libffi.map.in +13 -1
  32. data/ext/ffi_c/libffi/libtool-version +1 -1
  33. data/ext/ffi_c/libffi/m4/asmcfi.m4 +28 -11
  34. data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +13 -3
  35. data/ext/ffi_c/libffi/man/Makefile.in +4 -0
  36. data/ext/ffi_c/libffi/src/aarch64/ffi.c +7 -4
  37. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +2 -2
  38. data/ext/ffi_c/libffi/src/aarch64/internal.h +63 -17
  39. data/ext/ffi_c/libffi/src/aarch64/sysv.S +22 -12
  40. data/ext/ffi_c/libffi/src/arc/arcompact.S +2 -2
  41. data/ext/ffi_c/libffi/src/arc/ffi.c +6 -2
  42. data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
  43. data/ext/ffi_c/libffi/src/closures.c +3 -3
  44. data/ext/ffi_c/libffi/src/dlmalloc.c +1 -0
  45. data/ext/ffi_c/libffi/src/mips/ffitarget.h +2 -4
  46. data/ext/ffi_c/libffi/src/mips/n32.S +4 -0
  47. data/ext/ffi_c/libffi/src/mips/o32.S +4 -0
  48. data/ext/ffi_c/libffi/src/or1k/ffi.c +2 -2
  49. data/ext/ffi_c/libffi/src/pa/linux.S +4 -0
  50. data/ext/ffi_c/libffi/src/powerpc/ffi.c +19 -0
  51. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +26 -19
  52. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +26 -16
  53. data/ext/ffi_c/libffi/src/powerpc/internal.h +10 -0
  54. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +47 -0
  55. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +24 -0
  56. data/ext/ffi_c/libffi/src/prep_cif.c +1 -4
  57. data/ext/ffi_c/libffi/src/riscv/ffi.c +39 -16
  58. data/ext/ffi_c/libffi/src/riscv/internal.h +7 -0
  59. data/ext/ffi_c/libffi/src/riscv/sysv.S +24 -0
  60. data/ext/ffi_c/libffi/src/s390/ffi.c +28 -1
  61. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  62. data/ext/ffi_c/libffi/src/s390/sysv.S +38 -0
  63. data/ext/ffi_c/libffi/src/sparc/ffi.c +16 -0
  64. data/ext/ffi_c/libffi/src/tramp.c +6 -1
  65. data/ext/ffi_c/libffi/src/types.c +23 -1
  66. data/ext/ffi_c/libffi/src/{wasm32 → wasm}/ffi.c +166 -315
  67. data/ext/ffi_c/libffi/src/{wasm32 → wasm}/ffitarget.h +17 -0
  68. data/ext/ffi_c/libffi/src/x86/ffi.c +4 -1
  69. data/ext/ffi_c/libffi/src/x86/ffi64.c +4 -1
  70. data/ext/ffi_c/libffi/src/x86/ffitarget.h +0 -3
  71. data/ext/ffi_c/libffi/src/x86/sysv.S +1 -3
  72. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +1 -3
  73. data/ext/ffi_c/libffi/testsuite/Makefile.in +10 -4
  74. data/ext/ffi_c/libffi.mk +5 -0
  75. data/ffi.gemspec +7 -6
  76. data/lib/ffi/autopointer.rb +6 -0
  77. data/lib/ffi/compat.rb +11 -0
  78. data/lib/ffi/ffi.rb +59 -0
  79. data/lib/ffi/function.rb +23 -0
  80. data/lib/ffi/library.rb +19 -3
  81. data/lib/ffi/struct_by_reference.rb +1 -1
  82. data/lib/ffi/version.rb +1 -1
  83. data/samples/hello_ractor.rb +9 -1
  84. data/samples/qsort_ractor.rb +9 -1
  85. data/sig/ffi/auto_pointer.rbs +1 -2
  86. data/sig/ffi/errno.rbs +8 -0
  87. data/sig/ffi/library.rbs +1 -1
  88. data/sig/ffi/platform.rbs +49 -0
  89. data/sig/ffi/struct.rbs +2 -2
  90. data/sig/ffi/struct_by_reference.rbs +1 -1
  91. data/sig/ffi.rbs +4 -1
  92. data.tar.gz.sig +0 -0
  93. metadata +25 -339
  94. metadata.gz.sig +0 -0
  95. data/ext/ffi_c/libffi/.allow-ai-service +0 -0
  96. data/ext/ffi_c/libffi/.appveyor/site.exp +0 -16
  97. data/ext/ffi_c/libffi/.appveyor/unix-noexec.exp +0 -7
  98. data/ext/ffi_c/libffi/.appveyor.yml +0 -84
  99. data/ext/ffi_c/libffi/.ci/ar-lib +0 -270
  100. data/ext/ffi_c/libffi/.ci/bfin-sim.exp +0 -58
  101. data/ext/ffi_c/libffi/.ci/build-cross-in-container.sh +0 -18
  102. data/ext/ffi_c/libffi/.ci/build-in-container.sh +0 -10
  103. data/ext/ffi_c/libffi/.ci/build.sh +0 -124
  104. data/ext/ffi_c/libffi/.ci/compile +0 -351
  105. data/ext/ffi_c/libffi/.ci/install.sh +0 -78
  106. data/ext/ffi_c/libffi/.ci/m32r-sim.exp +0 -58
  107. data/ext/ffi_c/libffi/.ci/moxie-sim.exp +0 -60
  108. data/ext/ffi_c/libffi/.ci/msvs-detect +0 -1103
  109. data/ext/ffi_c/libffi/.ci/or1k-sim.exp +0 -58
  110. data/ext/ffi_c/libffi/.ci/powerpc-eabisim.exp +0 -58
  111. data/ext/ffi_c/libffi/.ci/site.exp +0 -29
  112. data/ext/ffi_c/libffi/.ci/wine-sim.exp +0 -55
  113. data/ext/ffi_c/libffi/.circleci/config.yml +0 -156
  114. data/ext/ffi_c/libffi/.gitattributes +0 -4
  115. data/ext/ffi_c/libffi/.github/issue_template.md +0 -10
  116. data/ext/ffi_c/libffi/.github/workflows/build.yml +0 -479
  117. data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +0 -172
  118. data/ext/ffi_c/libffi/.gitignore +0 -46
  119. data/ext/ffi_c/libffi/src/nios2/ffi.c +0 -304
  120. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +0 -52
  121. data/ext/ffi_c/libffi/src/nios2/sysv.S +0 -136
  122. data/ext/ffi_c/libffi/testsuite/Makefile.am +0 -87
  123. data/ext/ffi_c/libffi/testsuite/config/default.exp +0 -1
  124. data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +0 -54
  125. data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +0 -63
  126. data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +0 -86
  127. data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +0 -48
  128. data/ext/ffi_c/libffi/testsuite/emscripten/test.html +0 -7
  129. data/ext/ffi_c/libffi/testsuite/emscripten/test_libffi.py +0 -51
  130. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +0 -682
  131. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +0 -283
  132. data/ext/ffi_c/libffi/testsuite/lib/wrapper.exp +0 -45
  133. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/Makefile +0 -28
  134. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/README +0 -78
  135. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/alignof.h +0 -50
  136. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +0 -63
  137. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +0 -1746
  138. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +0 -2885
  139. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +0 -747
  140. data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +0 -46
  141. data/ext/ffi_c/libffi/testsuite/libffi.call/align_stdcall.c +0 -46
  142. data/ext/ffi_c/libffi/testsuite/libffi.call/bpo_38748.c +0 -41
  143. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +0 -54
  144. data/ext/ffi_c/libffi/testsuite/libffi.call/callback.c +0 -99
  145. data/ext/ffi_c/libffi/testsuite/libffi.call/callback2.c +0 -108
  146. data/ext/ffi_c/libffi/testsuite/libffi.call/callback3.c +0 -114
  147. data/ext/ffi_c/libffi/testsuite/libffi.call/callback4.c +0 -119
  148. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +0 -26
  149. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +0 -163
  150. data/ext/ffi_c/libffi/testsuite/libffi.call/float.c +0 -59
  151. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +0 -60
  152. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +0 -61
  153. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +0 -74
  154. data/ext/ffi_c/libffi/testsuite/libffi.call/float4.c +0 -62
  155. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +0 -110
  156. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +0 -59
  157. data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +0 -57
  158. data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +0 -70
  159. data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +0 -78
  160. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +0 -52
  161. data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +0 -46
  162. data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +0 -127
  163. data/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c +0 -59
  164. data/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc_tc.c +0 -114
  165. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +0 -36
  166. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c +0 -43
  167. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c +0 -42
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c +0 -35
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c +0 -36
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c +0 -49
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c +0 -42
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +0 -34
  173. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c +0 -41
  174. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +0 -48
  175. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +0 -36
  176. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +0 -42
  177. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +0 -38
  178. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +0 -42
  179. data/ext/ffi_c/libffi/testsuite/libffi.call/s55.c +0 -60
  180. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +0 -43
  181. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +0 -49
  182. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +0 -49
  183. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +0 -55
  184. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +0 -67
  185. data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +0 -57
  186. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +0 -67
  187. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +0 -60
  188. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +0 -64
  189. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +0 -66
  190. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +0 -64
  191. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +0 -74
  192. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +0 -81
  193. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +0 -68
  194. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_2.c +0 -63
  195. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3.c +0 -65
  196. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3f.c +0 -65
  197. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4.c +0 -67
  198. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4f.c +0 -67
  199. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_big.c +0 -93
  200. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_small.c +0 -61
  201. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_2H.c +0 -63
  202. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_8H.c +0 -90
  203. data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +0 -61
  204. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +0 -78
  205. data/ext/ffi_c/libffi/testsuite/libffi.call/va_2.c +0 -220
  206. data/ext/ffi_c/libffi/testsuite/libffi.call/va_3.c +0 -154
  207. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +0 -134
  208. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +0 -134
  209. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +0 -140
  210. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure.exp +0 -67
  211. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn0.c +0 -90
  212. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn1.c +0 -83
  213. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn2.c +0 -83
  214. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn3.c +0 -102
  215. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn4.c +0 -91
  216. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn5.c +0 -94
  217. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn6.c +0 -92
  218. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_loc_fn0.c +0 -96
  219. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_simple.c +0 -61
  220. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_12byte.c +0 -112
  221. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_16byte.c +0 -117
  222. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_18byte.c +0 -120
  223. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_19byte.c +0 -131
  224. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_1_1byte.c +0 -93
  225. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_20byte.c +0 -109
  226. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_20byte1.c +0 -113
  227. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_24byte.c +0 -145
  228. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_2byte.c +0 -103
  229. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3_1byte.c +0 -114
  230. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3byte1.c +0 -103
  231. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3byte2.c +0 -103
  232. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3float.c +0 -113
  233. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_4_1byte.c +0 -120
  234. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_4byte.c +0 -103
  235. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_5_1_byte.c +0 -137
  236. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_5byte.c +0 -116
  237. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_64byte.c +0 -148
  238. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_6_1_byte.c +0 -140
  239. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_6byte.c +0 -121
  240. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_7_1_byte.c +0 -155
  241. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_7byte.c +0 -121
  242. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_8byte.c +0 -102
  243. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_9byte1.c +0 -103
  244. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_9byte2.c +0 -103
  245. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_double.c +0 -111
  246. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_float.c +0 -109
  247. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble.c +0 -111
  248. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble_split.c +0 -147
  249. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble_split2.c +0 -152
  250. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_pointer.c +0 -113
  251. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint16.c +0 -108
  252. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint32.c +0 -106
  253. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint64.c +0 -109
  254. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint16.c +0 -108
  255. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint32.c +0 -109
  256. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint64.c +0 -111
  257. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_dbls_struct.c +0 -68
  258. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_double.c +0 -43
  259. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_double_va.c +0 -69
  260. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_float.c +0 -46
  261. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_longdouble.c +0 -115
  262. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_longdouble_va.c +0 -80
  263. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_args.c +0 -70
  264. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_float_double.c +0 -55
  265. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_schar.c +0 -78
  266. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshort.c +0 -79
  267. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c +0 -94
  268. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_uchar.c +0 -99
  269. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushort.c +0 -78
  270. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c +0 -94
  271. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_pointer.c +0 -79
  272. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_pointer_stack.c +0 -152
  273. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_schar.c +0 -47
  274. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_sint.c +0 -44
  275. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_sshort.c +0 -45
  276. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_struct_va1.c +0 -125
  277. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uchar.c +0 -45
  278. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint.c +0 -47
  279. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint_va.c +0 -49
  280. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulong_va.c +0 -49
  281. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulonglong.c +0 -49
  282. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ushort.c +0 -46
  283. data/ext/ffi_c/libffi/testsuite/libffi.closures/err_bad_abi.c +0 -36
  284. data/ext/ffi_c/libffi/testsuite/libffi.closures/ffitest.h +0 -1
  285. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +0 -343
  286. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct.c +0 -175
  287. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct1.c +0 -161
  288. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct10.c +0 -146
  289. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct11.c +0 -137
  290. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct12.c +0 -86
  291. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct13.c +0 -115
  292. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct2.c +0 -119
  293. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct3.c +0 -120
  294. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct4.c +0 -120
  295. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct5.c +0 -121
  296. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct6.c +0 -142
  297. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct7.c +0 -120
  298. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct8.c +0 -142
  299. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct9.c +0 -142
  300. data/ext/ffi_c/libffi/testsuite/libffi.closures/problem1.c +0 -90
  301. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs1.c +0 -86
  302. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs2.c +0 -102
  303. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs3.c +0 -101
  304. data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_large.c +0 -145
  305. data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_large2.c +0 -148
  306. data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_medium.c +0 -124
  307. data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_medium2.c +0 -125
  308. data/ext/ffi_c/libffi/testsuite/libffi.closures/testclosure.c +0 -75
  309. data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest.cc +0 -118
  310. data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc +0 -55
  311. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +0 -91
  312. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +0 -10
  313. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +0 -10
  314. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +0 -10
  315. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +0 -42
  316. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +0 -10
  317. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +0 -10
  318. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +0 -10
  319. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +0 -71
  320. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +0 -10
  321. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +0 -10
  322. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +0 -10
  323. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +0 -80
  324. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +0 -10
  325. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +0 -16
  326. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +0 -10
  327. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.exp +0 -36
  328. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +0 -51
  329. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +0 -7
  330. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +0 -7
  331. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +0 -7
  332. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +0 -10
  333. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +0 -10
  334. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +0 -86
  335. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +0 -10
  336. data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +0 -1
  337. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +0 -78
  338. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +0 -10
  339. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +0 -10
  340. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +0 -10
  341. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +0 -37
  342. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +0 -41
  343. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +0 -10
  344. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +0 -10
  345. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +0 -10
  346. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +0 -44
  347. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +0 -10
  348. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +0 -10
  349. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +0 -10
  350. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +0 -10
  351. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +0 -10
  352. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +0 -10
  353. data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +0 -34
  354. data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +0 -28
  355. data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +0 -1
  356. data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +0 -36
  357. data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +0 -19
  358. data/lib/ffi/tools/types_generator.rb +0 -137
  359. data/rakelib/ffi_gem_helper.rb +0 -65
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 482fe808cf14286b91be92938712e98f6332021d2773268f96ac583b5c264fc9
4
- data.tar.gz: f89f881dd5e337ec5ec815e9977158b54ead3a2480bc03fd2591477c7872d29e
3
+ metadata.gz: d5e14157e145e6fcd1024a5dbe0a77e6ea78df08b38cf61d95426cc5f4287c13
4
+ data.tar.gz: 6634a6296c5c34028f0e0d952ea402b0d7a5a5234f0197b80e42ef89c944eb98
5
5
  SHA512:
6
- metadata.gz: 877625d5994e1b456e8cf12a68647ce4e9d64efac2239c7a4e1806406b803fad5c1138ba0ad7e8b34ac6b8ebfeaed9f469381291f394527c523c4db8f36bd976
7
- data.tar.gz: 8d78610fc0c110ad7d6da40158dab176d815c8008a1276865b9112a44b46e1d43816db7430f9ab991671e4e8fad4dec0880fa259e2e2c83afaf916f59b7bb5c9
6
+ metadata.gz: d088e31edfa168f488881583d6a97e77e080d54374bc7b91dc91e6bdef93648cc5375451f12379e20c6cf5e26756330fd9fbfd8805c986b85ebb94687cfb6d99
7
+ data.tar.gz: 6057264da88292e8fffe1d88faa6043ffc92e36ea84ac2d07f698c5d13b5358e04a69921d9aceff56ce6d63438751177cfa5070d31a9a2ffb1fa8b36f3e0a9fc
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,3 +1,54 @@
1
+ 1.17.4 / 2026-03-26
2
+ -------------------
3
+
4
+ Fixed:
5
+ * Fix union by-value ABI mismatch with float and double types on ARM64 and X86_64.
6
+ See #1177 and #1178 for details.
7
+ * Exclude libffi files, which are unnecessary. #1176
8
+
9
+
10
+ 1.17.3 / 2025-12-29
11
+ -------------------
12
+
13
+ Fixed:
14
+ * Opt-in for MFA requirement explicitly. #1159
15
+ * Fix type signature for FFI::AutoPointer#initialize, FFI::StructByReference#native_type and FFI::Struct#auto_ptr . #1158
16
+ * Fix function signature of function_call in FFI trampoline. #1154
17
+ It failed on `aarch64-mingw-ucrt`.
18
+ * Add workaround for segmentation faults on `aarch64-mingw-ucrt`. #1154
19
+ * Call super in `Library#freeze` . #1154
20
+ * Deny duplication of AutoPointer per #dup and #clone . #1173
21
+ They led to double free before.
22
+
23
+ Added:
24
+ * Add binary gems for Ruby-4.0, now providing binary gems for Ruby-3.0 to 4.0.
25
+ * Add msys2_mingw_dependencies for Windows Mingw for automatic installation of libffi. #1143
26
+ * Mark callback dispatcher thread as fork safe for Puma. #1156
27
+ * Add missing FFI::Platform module and LastError signatures. #1169
28
+
29
+ Removed:
30
+ * Drop fat binary gems for Ruby < 3.0
31
+ * Remove `FFI::TypesGenerator` from distributed gems. #1164
32
+ * Remove libffi build dir after install, safing some install space. #1157
33
+
34
+
35
+ 1.17.2 / 2025-04-15
36
+ -------------------
37
+
38
+ Fixed:
39
+ * #1144, #1145 Update libffi to 3.4.8 to fix installation issues on latest Macos on ARM64
40
+ * Various adjustments to run the specs cleanly on Ruby-3.5 master branch.
41
+
42
+
43
+ 1.17.1 / 2024-12-30
44
+ -------------------
45
+
46
+ Fixed:
47
+ * #1117 Restart async callback dispatcher thread after fork.
48
+ * #1133 Add ruby-3.4 native gem.
49
+ * #1134 Fix FFI::DataConverter non-generic usage in RBS files.
50
+
51
+
1
52
  1.17.0 / 2024-06-02
2
53
  -------------------
3
54
 
data/Gemfile CHANGED
@@ -1,11 +1,15 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gemspec
4
+
3
5
  group :development do
6
+ gem 'benchmark' # necessary on ruby-3.5+
4
7
  gem 'bigdecimal' # necessary on ruby-3.3+
5
- gem 'bundler', '>= 1.16', '< 3'
8
+ gem 'bundler', '>= 1.16', '< 5.dev'
9
+ gem 'fiddle' # necessary on ruby-4.0+
6
10
  gem 'rake', '~> 13.0'
7
11
  gem 'rake-compiler', '~> 1.1'
8
- gem 'rake-compiler-dock', '~> 1.0.pre'
12
+ gem 'rake-compiler-dock', '~> 1.11.0'
9
13
  gem 'rspec', '~> 3.0'
10
14
  end
11
15
 
@@ -15,7 +19,8 @@ group :doc do
15
19
  end
16
20
 
17
21
  group :type_check do
18
- if RUBY_VERSION >= "2.6" && %w[ ruby truffleruby ].include?(RUBY_ENGINE)
22
+ if RUBY_VERSION >= "3.0" && %w[ ruby truffleruby ].include?(RUBY_ENGINE)
19
23
  gem 'rbs', '~> 3.0'
24
+ gem 'steep', '~> 1.6'
20
25
  end
21
26
  end
data/README.md CHANGED
@@ -33,6 +33,7 @@ MyLib.puts 'Hello, World using libc!'
33
33
 
34
34
  For less minimalistic and more examples you may look at:
35
35
 
36
+ * The [documentation](https://www.rubydoc.info/gems/ffi)
36
37
  * the `samples/` folder
37
38
  * the examples on the [wiki](https://github.com/ffi/ffi/wiki)
38
39
  * the projects using FFI listed on the wiki: https://github.com/ffi/ffi/wiki/projects-using-ffi
data/Rakefile CHANGED
@@ -97,6 +97,7 @@ Bundler::GemHelper.instance.cross_platforms = %w[
97
97
  arm-linux-musl
98
98
  aarch64-linux-gnu
99
99
  aarch64-linux-musl
100
+ aarch64-mingw-ucrt
100
101
  x86_64-darwin
101
102
  arm64-darwin
102
103
  ]
@@ -111,6 +112,8 @@ if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
111
112
  ext.cross_platform = Bundler::GemHelper.instance.cross_platforms
112
113
  ext.cross_compiling do |spec|
113
114
  spec.files.reject! { |path| File.fnmatch?('ext/*', path) }
115
+ # Binary gems don't need libffi header+lib files
116
+ spec.metadata.delete("msys2_mingw_dependencies")
114
117
  end
115
118
  # Enable debug info for 'rake compile' but not for 'gem install'
116
119
  ext.config_options << "--enable-debug"
@@ -126,7 +129,7 @@ end
126
129
  namespace "gem" do
127
130
  task 'prepare' do
128
131
  require 'rake_compiler_dock'
129
- sh "bundle package --all"
132
+ sh "bundle package"
130
133
  end
131
134
 
132
135
  Bundler::GemHelper.instance.cross_platforms.each do |plat|
@@ -136,9 +139,9 @@ namespace "gem" do
136
139
  desc "Build the native gem for #{plat}"
137
140
  task plat => ['prepare', 'build'] do
138
141
  RakeCompilerDock.sh <<-EOT, platform: plat
139
- #{ "sudo apt-get update && sudo apt-get install -y libltdl-dev &&" if plat !~ /linux/ }
140
- bundle --local &&
141
- rake native:#{plat} pkg/#{gem_spec.full_name}-#{plat}.gem MAKE='nice make -j`nproc`' RUBY_CC_VERSION=${RUBY_CC_VERSION/:2.4.0/}
142
+ sudo apt-get update && sudo apt-get install -y libltdl-dev &&
143
+ bundle install --local &&
144
+ rake native:#{plat} pkg/#{gem_spec.full_name}-#{plat}.gem MAKE='nice make -j`nproc`' RUBY_CC_VERSION=#{RakeCompilerDock.ruby_cc_version("~>4.0", "~>3.0")}
142
145
  EOT
143
146
  end
144
147
  end
@@ -180,7 +183,7 @@ logfile = File.join(File.dirname(__FILE__), 'types_log')
180
183
 
181
184
  task types_conf do |task|
182
185
  require 'fileutils'
183
- require_relative "lib/ffi/tools/types_generator"
186
+ require_relative "rakelib/types_generator"
184
187
  options = {}
185
188
  FileUtils.mkdir_p(File.dirname(task.name), mode: 0755 )
186
189
  File.open(task.name, File::CREAT|File::TRUNC|File::RDWR, 0644) do |f|
data/Steepfile ADDED
@@ -0,0 +1,8 @@
1
+ target :lib do
2
+ signature "sig"
3
+
4
+ check "lib"
5
+
6
+ # ignore whole of lib, to just validate RBS in sig
7
+ ignore "lib"
8
+ end
@@ -236,7 +236,7 @@ dl_error(char* buf, int size)
236
236
  NULL, error, 0, (LPSTR)&message, 0, NULL);
237
237
 
238
238
  // Update the passed in buffer
239
- snprintf(buf, size, "Failed with error %d: %s", error, message);
239
+ snprintf(buf, size, "Failed with error %lu: %s", error, message);
240
240
 
241
241
  // Free the allocated message
242
242
  LocalFree(message);
data/ext/ffi_c/Function.c CHANGED
@@ -215,6 +215,54 @@ async_cb_dispatcher_set(struct async_cb_dispatcher *ctx)
215
215
  async_cb_dispatcher = ctx;
216
216
  }
217
217
  #endif
218
+
219
+ static void
220
+ async_cb_dispatcher_initialize(struct async_cb_dispatcher *ctx)
221
+ {
222
+ ctx->async_cb_list = NULL;
223
+
224
+ #if !defined(_WIN32)
225
+ /* n.b. we _used_ to try and destroy the mutex/cond before initializing here,
226
+ * but it's undefined what happens if you try and destory an unitialized cond.
227
+ * glibc in particular seems to wait for any concurrent waiters to finish before
228
+ * destroying a condvar, trying to destroy a condvar after fork that someone was
229
+ * waiting on pre-fork won't work. Just re-init he memory directly. */
230
+ pthread_mutex_init(&ctx->async_cb_mutex, NULL);
231
+ pthread_cond_init(&ctx->async_cb_cond, NULL);
232
+ #else
233
+ InitializeCriticalSection(&ctx->async_cb_lock);
234
+ ctx->async_cb_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
235
+ #endif
236
+ ctx->thread = rb_thread_create(async_cb_event, ctx);
237
+
238
+ /* Name thread, for better debugging */
239
+ rb_funcall(ctx->thread, rb_intern("name="), 1, rb_str_new2("FFI Callback Dispatcher"));
240
+ /* Advise multi-threaded app servers to ignore this thread for the purposes of fork safety warnings */
241
+ rb_funcall(ctx->thread, rb_intern("thread_variable_set"), 2, ID2SYM(rb_intern("fork_safe")), Qtrue);
242
+ }
243
+
244
+ static struct async_cb_dispatcher *
245
+ async_cb_dispatcher_ensure_created(void)
246
+ {
247
+ struct async_cb_dispatcher *ctx = async_cb_dispatcher_get();
248
+ if (ctx == NULL) {
249
+ ctx = (struct async_cb_dispatcher*)ALLOC(struct async_cb_dispatcher);
250
+ async_cb_dispatcher_initialize(ctx);
251
+ async_cb_dispatcher_set(ctx);
252
+ }
253
+ return ctx;
254
+ }
255
+
256
+
257
+ static VALUE
258
+ async_cb_dispatcher_atfork_child(VALUE self)
259
+ {
260
+ struct async_cb_dispatcher *ctx = async_cb_dispatcher_get();
261
+ if (ctx) {
262
+ async_cb_dispatcher_initialize(ctx);
263
+ }
264
+ return Qnil;
265
+ }
218
266
  #endif
219
267
 
220
268
  static VALUE
@@ -391,15 +439,6 @@ rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
391
439
  return callback;
392
440
  }
393
441
 
394
- #if !defined(_WIN32) && defined(DEFER_ASYNC_CALLBACK)
395
- static void
396
- after_fork_callback(void)
397
- {
398
- /* Ensure that a new dispatcher thread is started in a forked process */
399
- async_cb_dispatcher_set(NULL);
400
- }
401
- #endif
402
-
403
442
  static VALUE
404
443
  function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
405
444
  {
@@ -426,31 +465,7 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
426
465
  }
427
466
 
428
467
  #if defined(DEFER_ASYNC_CALLBACK)
429
- {
430
- struct async_cb_dispatcher *ctx = async_cb_dispatcher_get();
431
- if (ctx == NULL) {
432
- ctx = (struct async_cb_dispatcher*)ALLOC(struct async_cb_dispatcher);
433
- ctx->async_cb_list = NULL;
434
-
435
- #if !defined(_WIN32)
436
- pthread_mutex_init(&ctx->async_cb_mutex, NULL);
437
- pthread_cond_init(&ctx->async_cb_cond, NULL);
438
- if( pthread_atfork(NULL, NULL, after_fork_callback) ){
439
- rb_warn("FFI: unable to register fork callback");
440
- }
441
- #else
442
- InitializeCriticalSection(&ctx->async_cb_lock);
443
- ctx->async_cb_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
444
- #endif
445
- ctx->thread = rb_thread_create(async_cb_event, ctx);
446
-
447
- /* Name thread, for better debugging */
448
- rb_funcall(ctx->thread, rb_intern("name="), 1, rb_str_new2("FFI Callback Dispatcher"));
449
-
450
- async_cb_dispatcher_set(ctx);
451
- }
452
- fn->dispatcher = ctx;
453
- }
468
+ fn->dispatcher = async_cb_dispatcher_ensure_created();
454
469
  #endif
455
470
 
456
471
  fn->closure = rbffi_Closure_Alloc(fn->info->closurePool);
@@ -1060,4 +1075,9 @@ rbffi_Function_Init(VALUE moduleFFI)
1060
1075
  #if defined(DEFER_ASYNC_CALLBACK) && defined(HAVE_RB_EXT_RACTOR_SAFE)
1061
1076
  async_cb_dispatcher_key = rb_ractor_local_storage_ptr_newkey(&async_cb_dispatcher_key_type);
1062
1077
  #endif
1078
+ #ifdef DEFER_ASYNC_CALLBACK
1079
+ /* Ruby code will call this method in a Process._fork patch */
1080
+ rb_define_singleton_method(moduleFFI, "_async_cb_dispatcher_atfork_child",
1081
+ async_cb_dispatcher_atfork_child, 0);
1082
+ #endif
1063
1083
  }
@@ -336,11 +336,13 @@ rbffi_MethodHandle_Init(VALUE module)
336
336
  rb_raise(rb_eFatal, "Could not locate offsets in trampoline code");
337
337
  }
338
338
  #else
339
+
340
+ /* static VALUE function_call(int argc, VALUE* argv, VALUE self) */
339
341
  methodHandleParamTypes[0] = &ffi_type_sint;
340
342
  methodHandleParamTypes[1] = &ffi_type_pointer;
341
- methodHandleParamTypes[2] = &ffi_type_ulong;
343
+ methodHandleParamTypes[2] = &ffi_type_pointer;
342
344
 
343
- ffiStatus = ffi_prep_cif(&mh_cif, FFI_DEFAULT_ABI, 3, &ffi_type_ulong,
345
+ ffiStatus = ffi_prep_cif(&mh_cif, FFI_DEFAULT_ABI, 3, &ffi_type_pointer,
344
346
  methodHandleParamTypes);
345
347
  if (ffiStatus != FFI_OK) {
346
348
  rb_raise(rb_eFatal, "ffi_prep_cif failed. status=%#x", ffiStatus);
@@ -548,29 +548,141 @@ struct_layout_initialize(VALUE self, VALUE fields, VALUE size, VALUE align)
548
548
  return self;
549
549
  }
550
550
 
551
+ static const ffi_type * const *
552
+ get_int_types(void)
553
+ {
554
+ static const ffi_type *types[5];
555
+ types[0] = &ffi_type_sint8;
556
+ types[1] = &ffi_type_sint16;
557
+ types[2] = &ffi_type_sint32;
558
+ types[3] = &ffi_type_sint64;
559
+ types[4] = NULL;
560
+ return types;
561
+ }
562
+
563
+ static const ffi_type * const *
564
+ get_float_types(void)
565
+ {
566
+ static const ffi_type *types[4];
567
+ types[0] = &ffi_type_float;
568
+ types[1] = &ffi_type_double;
569
+ types[2] = &ffi_type_longdouble;
570
+ types[3] = NULL;
571
+ return types;
572
+ }
573
+
574
+ static const ffi_type *
575
+ find_type_by_alignment(const ffi_type * const *types, unsigned short alignment)
576
+ {
577
+ int i;
578
+ for (i = 0; types[i] != NULL; i++) {
579
+ if (types[i]->alignment == alignment) return types[i];
580
+ }
581
+ return NULL;
582
+ }
583
+
584
+ static bool
585
+ is_float_type(const ffi_type *type)
586
+ {
587
+ int i;
588
+ const ffi_type * const *ftypes = get_float_types();
589
+ for (i = 0; ftypes[i] != NULL; i++) {
590
+ if (type->type == ftypes[i]->type) return true;
591
+ }
592
+ return false;
593
+ }
594
+
551
595
  /*
552
- * call-seq: [](field)
553
- * @param [Symbol] field
554
- * @return [StructLayout::Field]
555
- * Get a field from the layout.
596
+ * Recursively inspect the leaf elements of an ffi_type.
597
+ *
598
+ * Returns the leaf type if all leaves are the same primitive type, or NULL
599
+ * if mixed. Sets float_only to false when any non-float leaf is encountered.
600
+ *
601
+ * Examples (float_only initially true):
602
+ * {double, double} -> &ffi_type_double, float_only = true
603
+ * {float, double} -> NULL, float_only = true
604
+ * {float, int} -> NULL, float_only = false
556
605
  */
606
+ static const ffi_type *
607
+ find_homogeneous_leaf_type(const ffi_type *type, bool *float_only)
608
+ {
609
+ const ffi_type *result = NULL;
610
+ int i;
611
+
612
+ if (type->type != FFI_TYPE_STRUCT || type->elements == NULL) {
613
+ if (!is_float_type(type)) {
614
+ *float_only = false;
615
+ }
616
+ return type;
617
+ }
618
+
619
+ for (i = 0; type->elements[i] != NULL; i++) {
620
+ const ffi_type *elem = find_homogeneous_leaf_type(type->elements[i], float_only);
621
+
622
+ if (result == NULL) {
623
+ result = elem;
624
+ } else if (elem == NULL || result != elem) {
625
+ result = NULL;
626
+ }
627
+ }
628
+
629
+ return result;
630
+ }
631
+
557
632
  static VALUE
558
633
  struct_layout_union_bang(VALUE self)
559
634
  {
560
- const ffi_type *alignment_types[] = { &ffi_type_sint8, &ffi_type_sint16, &ffi_type_sint32, &ffi_type_sint64,
561
- &ffi_type_float, &ffi_type_double, &ffi_type_longdouble, NULL };
562
635
  StructLayout* layout;
563
636
  ffi_type *t = NULL;
564
637
  int count, i;
638
+ bool float_only = true;
639
+ const ffi_type *homogeneous = NULL;
565
640
 
566
641
  TypedData_Get_Struct(self, StructLayout, &rbffi_struct_layout_data_type, layout);
567
642
 
568
- for (i = 0; alignment_types[i] != NULL; ++i) {
569
- if (alignment_types[i]->alignment == layout->align) {
570
- t = (ffi_type *) alignment_types[i];
571
- break;
572
- }
643
+ /*
644
+ * __union! replaces the real field types with a repeated filler type.
645
+ * The filler must be chosen so that libffi uses the same calling convention
646
+ * as the C compiler would for the real union.
647
+ *
648
+ * The rules vary by architecture:
649
+ *
650
+ * ARM64: A "Homogeneous Floating-point Aggregate" (HFA) is
651
+ * passed in floating-point registers (d0-d3). An HFA requires all members
652
+ * to be the *same* float type. {double, double} is an HFA; {float, double}
653
+ * is NOT. Non-HFAs use integer registers.
654
+ *
655
+ * x86_64 targets using the System V ABI (Linux/macOS/BSD, not Windows):
656
+ * an eightbyte containing only float/double fields is classified as SSE
657
+ * and passed in XMM registers, regardless of whether the float types are
658
+ * mixed. {float, double} is SSE; {int, double} is INTEGER.
659
+ *
660
+ * Strategy:
661
+ * 1. If all fields are the same float type, use that type directly.
662
+ * Correct on all platforms.
663
+ * 2. If fields are mixed float types (e.g. {float, double}):
664
+ * - On ARM64: not an HFA, use integer filler.
665
+ * - On x86_64 System V targets: still SSE class, use float filler.
666
+ * 3. Otherwise: use integer filler.
667
+ */
668
+ homogeneous = find_homogeneous_leaf_type(layout->base.ffiType, &float_only);
669
+
670
+ if (homogeneous != NULL && float_only) {
671
+ /* Case 1: all fields are the same float type. */
672
+ t = (ffi_type *) homogeneous;
673
+ }
674
+ #if defined(__x86_64__) && !defined(_WIN32)
675
+ else if (float_only) {
676
+ /* Case 2: mixed float types use float filler on SysV x86_64. */
677
+ t = (ffi_type *) find_type_by_alignment(get_float_types(), layout->align);
573
678
  }
679
+ #endif
680
+
681
+ if (t == NULL) {
682
+ /* Case 3: integer or mixed int/float — use integer filler */
683
+ t = (ffi_type *) find_type_by_alignment(get_int_types(), layout->align);
684
+ }
685
+
574
686
  if (t == NULL) {
575
687
  rb_raise(rb_eRuntimeError, "cannot create libffi union representation for alignment %d", layout->align);
576
688
  return Qnil;
@@ -588,6 +700,12 @@ struct_layout_union_bang(VALUE self)
588
700
  return self;
589
701
  }
590
702
 
703
+ /*
704
+ * call-seq: [](field)
705
+ * @param [Symbol] field
706
+ * @return [StructLayout::Field]
707
+ * Get a field from the layout.
708
+ */
591
709
  static VALUE
592
710
  struct_layout_aref(VALUE self, VALUE field)
593
711
  {
@@ -766,4 +884,3 @@ rbffi_StructLayout_Init(VALUE moduleFFI)
766
884
  rb_define_method(rbffi_StructLayoutClass, "__union!", struct_layout_union_bang, 0);
767
885
 
768
886
  }
769
-
@@ -1,4 +1,4 @@
1
- libffi - Copyright (c) 1996-2024 Anthony Green, Red Hat, Inc and others.
1
+ libffi - Copyright (c) 1996-2025 Anthony Green, Red Hat, Inc and others.
2
2
  See source files for details.
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
@@ -4,6 +4,10 @@ AUTOMAKE_OPTIONS = foreign subdir-objects
4
4
 
5
5
  ACLOCAL_AMFLAGS = -I m4
6
6
 
7
+ # Alias required by AX_ENABLE_BUILDDIR / config-ml
8
+ .PHONY: all-configured
9
+ all-configured: all
10
+
7
11
  SUBDIRS = include testsuite man
8
12
  if BUILD_DOCS
9
13
  ## This hack is needed because it doesn't seem possible to make a
@@ -14,15 +18,15 @@ if BUILD_DOCS
14
18
  SUBDIRS += doc
15
19
  endif
16
20
 
17
- EXTRA_DIST = LICENSE ChangeLog.old \
18
- m4/libtool.m4 m4/lt~obsolete.m4 \
19
- m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \
20
- m4/ltversion.m4 src/debug.c msvcc.sh \
21
- generate-darwin-source-and-headers.py \
22
- libffi.xcodeproj/project.pbxproj \
23
- src/powerpc/t-aix \
24
- libtool-ldflags libtool-version configure.host README.md \
25
- libffi.map.in LICENSE-BUILDTOOLS msvc_build make_sunver.pl
21
+ EXTRA_DIST = LICENSE ChangeLog.old \
22
+ m4/libtool.m4 m4/lt~obsolete.m4 \
23
+ m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \
24
+ m4/ltversion.m4 src/debug.c msvcc.sh \
25
+ generate-darwin-source-and-headers.py \
26
+ libffi.xcodeproj/project.pbxproj \
27
+ src/powerpc/t-aix \
28
+ libtool-ldflags libtool-version configure.host README.md \
29
+ libffi.map.in LICENSE-BUILDTOOLS msvc_build make_sunver.pl
26
30
 
27
31
  # local.exp is generated by configure
28
32
  DISTCLEANFILES = local.exp
@@ -55,14 +59,15 @@ noinst_HEADERS = src/aarch64/ffitarget.h src/aarch64/internal.h \
55
59
  src/m32r/ffitarget.h src/m68k/ffitarget.h \
56
60
  src/m88k/ffitarget.h src/metag/ffitarget.h \
57
61
  src/microblaze/ffitarget.h src/mips/ffitarget.h \
58
- src/moxie/ffitarget.h src/nios2/ffitarget.h \
62
+ src/moxie/ffitarget.h \
59
63
  src/or1k/ffitarget.h src/pa/ffitarget.h \
60
64
  src/powerpc/ffitarget.h src/powerpc/asm.h \
61
- src/powerpc/ffi_powerpc.h src/riscv/ffitarget.h \
65
+ src/powerpc/ffi_powerpc.h src/powerpc/internal.h \
66
+ src/riscv/ffitarget.h src/riscv/internal.h \
62
67
  src/s390/ffitarget.h src/s390/internal.h src/sh/ffitarget.h \
63
68
  src/sh64/ffitarget.h src/sparc/ffitarget.h \
64
69
  src/sparc/internal.h src/tile/ffitarget.h src/vax/ffitarget.h \
65
- src/wasm32/ffitarget.h \
70
+ src/wasm/ffitarget.h \
66
71
  src/x86/ffitarget.h src/x86/internal.h src/x86/internal64.h \
67
72
  src/x86/asmnames.h src/xtensa/ffitarget.h src/dlmalloc.c \
68
73
  src/kvx/ffitarget.h src/kvx/asm.h \
@@ -80,7 +85,7 @@ EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \
80
85
  src/metag/ffi.c src/metag/sysv.S src/microblaze/ffi.c \
81
86
  src/microblaze/sysv.S src/mips/ffi.c src/mips/o32.S \
82
87
  src/mips/n32.S src/moxie/ffi.c src/moxie/eabi.S \
83
- src/nios2/ffi.c src/nios2/sysv.S src/or1k/ffi.c \
88
+ src/or1k/ffi.c \
84
89
  src/or1k/sysv.S src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
85
90
  src/pa/hpux64.S src/powerpc/ffi.c src/powerpc/ffi_sysv.c \
86
91
  src/powerpc/ffi_linux64.c src/powerpc/sysv.S \
@@ -93,7 +98,7 @@ EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \
93
98
  src/sh64/sysv.S src/sparc/ffi.c src/sparc/ffi64.c \
94
99
  src/sparc/v8.S src/sparc/v9.S src/tile/ffi.c src/tile/tile.S \
95
100
  src/vax/ffi.c src/vax/elfbsd.S src/x86/ffi.c src/x86/sysv.S \
96
- src/wasm32/ffi.c \
101
+ src/wasm/ffi.c \
97
102
  src/x86/ffiw64.c src/x86/win64.S src/x86/ffi64.c \
98
103
  src/x86/unix64.S src/x86/sysv_intel.S src/x86/win64_intel.S \
99
104
  src/xtensa/ffi.c src/xtensa/sysv.S src/kvx/ffi.c \
@@ -146,7 +151,7 @@ libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script
146
151
  libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep)
147
152
 
148
153
  AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
149
- AM_CCASFLAGS = $(AM_CPPFLAGS)
154
+ AM_CCASFLAGS = '$(AM_CPPFLAGS)'
150
155
 
151
156
  dist-hook:
152
157
  d=`(cd $(distdir); pwd)`; (cd doc; make pdf; cp *.pdf $$d/doc)