ffi 1.0.0 → 1.17.1

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 (694) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +4 -0
  3. data/CHANGELOG.md +465 -0
  4. data/COPYING +49 -0
  5. data/Gemfile +21 -0
  6. data/LICENSE +21 -11
  7. data/LICENSE.SPECS +22 -0
  8. data/README.md +137 -0
  9. data/Rakefile +165 -148
  10. data/ext/ffi_c/AbstractMemory.c +716 -97
  11. data/ext/ffi_c/AbstractMemory.h +38 -17
  12. data/ext/ffi_c/ArrayType.c +102 -33
  13. data/ext/ffi_c/ArrayType.h +20 -18
  14. data/ext/ffi_c/Buffer.c +229 -54
  15. data/ext/ffi_c/Call.c +211 -100
  16. data/ext/ffi_c/Call.h +46 -28
  17. data/ext/ffi_c/ClosurePool.c +110 -81
  18. data/ext/ffi_c/ClosurePool.h +31 -1
  19. data/ext/ffi_c/DynamicLibrary.c +216 -54
  20. data/ext/ffi_c/DynamicLibrary.h +76 -0
  21. data/ext/ffi_c/Function.c +527 -164
  22. data/ext/ffi_c/Function.h +24 -20
  23. data/ext/ffi_c/FunctionInfo.c +151 -50
  24. data/ext/ffi_c/LastError.c +112 -28
  25. data/ext/ffi_c/LastError.h +29 -0
  26. data/ext/ffi_c/LongDouble.c +65 -0
  27. data/ext/ffi_c/LongDouble.h +47 -0
  28. data/ext/ffi_c/MappedType.c +107 -42
  29. data/ext/ffi_c/MappedType.h +20 -20
  30. data/ext/ffi_c/MemoryPointer.c +108 -46
  31. data/ext/ffi_c/MemoryPointer.h +33 -4
  32. data/ext/ffi_c/MethodHandle.c +71 -67
  33. data/ext/ffi_c/MethodHandle.h +26 -23
  34. data/ext/ffi_c/Platform.c +42 -25
  35. data/ext/ffi_c/Platform.h +32 -3
  36. data/ext/ffi_c/Pointer.c +324 -51
  37. data/ext/ffi_c/Pointer.h +29 -18
  38. data/ext/ffi_c/Struct.c +434 -161
  39. data/ext/ffi_c/Struct.h +47 -27
  40. data/ext/ffi_c/StructByValue.c +74 -37
  41. data/ext/ffi_c/StructByValue.h +20 -18
  42. data/ext/ffi_c/StructLayout.c +358 -87
  43. data/ext/ffi_c/Thread.c +129 -0
  44. data/ext/ffi_c/Thread.h +76 -0
  45. data/ext/ffi_c/Type.c +241 -76
  46. data/ext/ffi_c/Type.h +27 -11
  47. data/ext/ffi_c/Types.c +54 -34
  48. data/ext/ffi_c/Types.h +24 -24
  49. data/ext/ffi_c/Variadic.c +151 -55
  50. data/ext/ffi_c/compat.h +48 -38
  51. data/ext/ffi_c/extconf.rb +106 -34
  52. data/ext/ffi_c/ffi.c +35 -26
  53. data/ext/ffi_c/libffi/.allow-ai-service +0 -0
  54. data/ext/ffi_c/libffi/.appveyor/site.exp +16 -0
  55. data/ext/ffi_c/libffi/.appveyor/unix-noexec.exp +7 -0
  56. data/ext/ffi_c/libffi/.appveyor.yml +84 -0
  57. data/ext/ffi_c/libffi/.ci/ar-lib +270 -0
  58. data/ext/ffi_c/libffi/.ci/bfin-sim.exp +58 -0
  59. data/ext/ffi_c/libffi/.ci/build-cross-in-container.sh +18 -0
  60. data/ext/ffi_c/libffi/.ci/build-in-container.sh +10 -0
  61. data/ext/ffi_c/libffi/.ci/build.sh +124 -0
  62. data/ext/ffi_c/libffi/.ci/compile +351 -0
  63. data/ext/ffi_c/libffi/.ci/install.sh +78 -0
  64. data/ext/ffi_c/libffi/.ci/m32r-sim.exp +58 -0
  65. data/ext/ffi_c/libffi/.ci/moxie-sim.exp +60 -0
  66. data/ext/ffi_c/libffi/.ci/msvs-detect +1103 -0
  67. data/ext/ffi_c/libffi/.ci/or1k-sim.exp +58 -0
  68. data/ext/ffi_c/libffi/.ci/powerpc-eabisim.exp +58 -0
  69. data/ext/ffi_c/libffi/.ci/site.exp +29 -0
  70. data/ext/ffi_c/libffi/.ci/wine-sim.exp +55 -0
  71. data/ext/ffi_c/libffi/.circleci/config.yml +156 -0
  72. data/ext/ffi_c/libffi/.gitattributes +4 -0
  73. data/ext/ffi_c/libffi/.github/issue_template.md +10 -0
  74. data/ext/ffi_c/libffi/.github/workflows/build.yml +479 -0
  75. data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +172 -0
  76. data/ext/ffi_c/libffi/.gitignore +46 -0
  77. data/ext/ffi_c/libffi/{ChangeLog → ChangeLog.old} +6528 -3180
  78. data/ext/ffi_c/libffi/LICENSE +3 -3
  79. data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +353 -0
  80. data/ext/ffi_c/libffi/Makefile.am +132 -162
  81. data/ext/ffi_c/libffi/Makefile.in +1339 -1003
  82. data/ext/ffi_c/libffi/README.md +531 -0
  83. data/ext/ffi_c/libffi/acinclude.m4 +289 -4
  84. data/ext/ffi_c/libffi/autogen.sh +2 -0
  85. data/ext/ffi_c/libffi/compile +227 -21
  86. data/ext/ffi_c/libffi/config.guess +1034 -778
  87. data/ext/ffi_c/libffi/config.sub +1394 -1204
  88. data/ext/ffi_c/libffi/configure +14327 -8503
  89. data/ext/ffi_c/libffi/configure.ac +294 -247
  90. data/ext/ffi_c/libffi/configure.host +330 -4
  91. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  92. data/ext/ffi_c/libffi/doc/Makefile.in +818 -0
  93. data/ext/ffi_c/libffi/doc/libffi.texi +572 -67
  94. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  95. data/ext/ffi_c/libffi/fficonfig.h.in +53 -46
  96. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +312 -0
  97. data/ext/ffi_c/libffi/include/Makefile.am +3 -3
  98. data/ext/ffi_c/libffi/include/Makefile.in +219 -79
  99. data/ext/ffi_c/libffi/include/ffi.h.in +230 -111
  100. data/ext/ffi_c/libffi/include/ffi_cfi.h +76 -0
  101. data/ext/ffi_c/libffi/include/ffi_common.h +78 -16
  102. data/ext/ffi_c/libffi/include/tramp.h +45 -0
  103. data/ext/ffi_c/libffi/install-sh +402 -184
  104. data/ext/ffi_c/libffi/libffi.map.in +81 -0
  105. data/ext/ffi_c/libffi/libffi.pc.in +3 -2
  106. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +997 -0
  107. data/ext/ffi_c/libffi/libtool-ldflags +106 -0
  108. data/ext/ffi_c/libffi/libtool-version +2 -2
  109. data/ext/ffi_c/libffi/ltmain.sh +5752 -2722
  110. data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
  111. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +50 -0
  112. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +198 -0
  113. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +158 -0
  114. data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +53 -0
  115. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +119 -0
  116. data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +49 -0
  117. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +302 -0
  118. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +267 -0
  119. data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +89 -0
  120. data/ext/ffi_c/libffi/m4/ax_prepend_flag.m4 +51 -0
  121. data/ext/ffi_c/libffi/m4/ax_require_defined.m4 +37 -0
  122. data/ext/ffi_c/libffi/make_sunver.pl +333 -0
  123. data/ext/ffi_c/libffi/man/Makefile.am +2 -2
  124. data/ext/ffi_c/libffi/man/Makefile.in +174 -57
  125. data/ext/ffi_c/libffi/man/ffi.3 +10 -0
  126. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +6 -4
  127. data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +73 -0
  128. data/ext/ffi_c/libffi/missing +155 -300
  129. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.sln +33 -0
  130. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj +130 -0
  131. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters +57 -0
  132. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.user +4 -0
  133. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +511 -0
  134. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/fficonfig.h +219 -0
  135. data/ext/ffi_c/libffi/msvcc.sh +353 -0
  136. data/ext/ffi_c/libffi/src/aarch64/ffi.c +1142 -0
  137. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +97 -0
  138. data/ext/ffi_c/libffi/src/aarch64/internal.h +100 -0
  139. data/ext/ffi_c/libffi/src/aarch64/sysv.S +695 -0
  140. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +506 -0
  141. data/ext/ffi_c/libffi/src/alpha/ffi.c +335 -98
  142. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +10 -1
  143. data/ext/ffi_c/libffi/src/alpha/internal.h +23 -0
  144. data/ext/ffi_c/libffi/src/alpha/osf.S +162 -246
  145. data/ext/ffi_c/libffi/src/arc/arcompact.S +210 -0
  146. data/ext/ffi_c/libffi/src/arc/ffi.c +443 -0
  147. data/ext/ffi_c/libffi/src/arc/ffitarget.h +67 -0
  148. data/ext/ffi_c/libffi/src/arm/ffi.c +806 -194
  149. data/ext/ffi_c/libffi/src/arm/ffitarget.h +43 -3
  150. data/ext/ffi_c/libffi/src/arm/internal.h +17 -0
  151. data/ext/ffi_c/libffi/src/arm/sysv.S +381 -231
  152. data/ext/ffi_c/libffi/src/arm/sysv_msvc_arm32.S +311 -0
  153. data/ext/ffi_c/libffi/src/avr32/ffi.c +4 -2
  154. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +8 -3
  155. data/ext/ffi_c/libffi/src/bfin/ffi.c +196 -0
  156. data/ext/ffi_c/libffi/src/bfin/ffitarget.h +43 -0
  157. data/ext/ffi_c/libffi/src/bfin/sysv.S +179 -0
  158. data/ext/ffi_c/libffi/src/closures.c +574 -100
  159. data/ext/ffi_c/libffi/src/cris/ffi.c +11 -8
  160. data/ext/ffi_c/libffi/src/cris/ffitarget.h +8 -3
  161. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  162. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  163. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  164. data/ext/ffi_c/libffi/src/debug.c +8 -3
  165. data/ext/ffi_c/libffi/src/dlmalloc.c +89 -17
  166. data/ext/ffi_c/libffi/src/frv/ffi.c +2 -2
  167. data/ext/ffi_c/libffi/src/frv/ffitarget.h +8 -7
  168. data/ext/ffi_c/libffi/src/ia64/ffi.c +48 -12
  169. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +10 -4
  170. data/ext/ffi_c/libffi/src/ia64/unix.S +28 -3
  171. data/ext/ffi_c/libffi/src/java_raw_api.c +24 -6
  172. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  173. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  174. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  175. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  176. data/ext/ffi_c/libffi/src/loongarch64/ffi.c +624 -0
  177. data/ext/ffi_c/libffi/src/loongarch64/ffitarget.h +82 -0
  178. data/ext/ffi_c/libffi/src/loongarch64/sysv.S +327 -0
  179. data/ext/ffi_c/libffi/src/m32r/ffi.c +32 -15
  180. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +8 -3
  181. data/ext/ffi_c/libffi/src/m68k/ffi.c +97 -13
  182. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +8 -3
  183. data/ext/ffi_c/libffi/src/m68k/sysv.S +148 -25
  184. data/ext/ffi_c/libffi/src/m88k/ffi.c +400 -0
  185. data/ext/ffi_c/libffi/src/m88k/ffitarget.h +49 -0
  186. data/ext/ffi_c/libffi/src/m88k/obsd.S +209 -0
  187. data/ext/ffi_c/libffi/src/metag/ffi.c +330 -0
  188. data/ext/ffi_c/libffi/src/metag/ffitarget.h +53 -0
  189. data/ext/ffi_c/libffi/src/metag/sysv.S +311 -0
  190. data/ext/ffi_c/libffi/src/microblaze/ffi.c +321 -0
  191. data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +53 -0
  192. data/ext/ffi_c/libffi/src/microblaze/sysv.S +302 -0
  193. data/ext/ffi_c/libffi/src/mips/ffi.c +392 -104
  194. data/ext/ffi_c/libffi/src/mips/ffitarget.h +40 -24
  195. data/ext/ffi_c/libffi/src/mips/n32.S +325 -93
  196. data/ext/ffi_c/libffi/src/mips/o32.S +211 -31
  197. data/ext/ffi_c/libffi/src/moxie/eabi.S +101 -0
  198. data/ext/ffi_c/libffi/src/moxie/ffi.c +310 -0
  199. data/ext/ffi_c/libffi/src/moxie/ffitarget.h +52 -0
  200. data/ext/ffi_c/libffi/src/nios2/ffi.c +304 -0
  201. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +52 -0
  202. data/ext/ffi_c/libffi/src/nios2/sysv.S +136 -0
  203. data/ext/ffi_c/libffi/src/or1k/ffi.c +341 -0
  204. data/ext/ffi_c/libffi/src/or1k/ffitarget.h +58 -0
  205. data/ext/ffi_c/libffi/src/or1k/sysv.S +107 -0
  206. data/ext/ffi_c/libffi/src/pa/ffi.c +68 -111
  207. data/ext/ffi_c/libffi/src/pa/ffi64.c +614 -0
  208. data/ext/ffi_c/libffi/src/pa/ffitarget.h +34 -17
  209. data/ext/ffi_c/libffi/src/pa/hpux32.S +87 -38
  210. data/ext/ffi_c/libffi/src/pa/hpux64.S +681 -0
  211. data/ext/ffi_c/libffi/src/pa/linux.S +109 -39
  212. data/ext/ffi_c/libffi/src/powerpc/aix.S +250 -8
  213. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +255 -4
  214. data/ext/ffi_c/libffi/src/powerpc/asm.h +3 -3
  215. data/ext/ffi_c/libffi/src/powerpc/darwin.S +211 -78
  216. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +356 -102
  217. data/ext/ffi_c/libffi/src/powerpc/ffi.c +108 -1375
  218. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +746 -210
  219. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +1153 -0
  220. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +105 -0
  221. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
  222. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +126 -48
  223. data/ext/ffi_c/libffi/src/powerpc/linux64.S +191 -85
  224. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +438 -108
  225. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +138 -68
  226. data/ext/ffi_c/libffi/src/powerpc/sysv.S +73 -119
  227. data/ext/ffi_c/libffi/src/powerpc/t-aix +5 -0
  228. data/ext/ffi_c/libffi/src/prep_cif.c +141 -32
  229. data/ext/ffi_c/libffi/src/raw_api.c +18 -5
  230. data/ext/ffi_c/libffi/src/riscv/ffi.c +514 -0
  231. data/ext/ffi_c/libffi/src/riscv/ffitarget.h +69 -0
  232. data/ext/ffi_c/libffi/src/riscv/sysv.S +293 -0
  233. data/ext/ffi_c/libffi/src/s390/ffi.c +294 -318
  234. data/ext/ffi_c/libffi/src/s390/ffitarget.h +13 -3
  235. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  236. data/ext/ffi_c/libffi/src/s390/sysv.S +257 -366
  237. data/ext/ffi_c/libffi/src/sh/ffi.c +4 -3
  238. data/ext/ffi_c/libffi/src/sh/ffitarget.h +8 -3
  239. data/ext/ffi_c/libffi/src/sh64/ffi.c +3 -2
  240. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +8 -3
  241. data/ext/ffi_c/libffi/src/sparc/ffi.c +334 -491
  242. data/ext/ffi_c/libffi/src/sparc/ffi64.c +630 -0
  243. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +20 -5
  244. data/ext/ffi_c/libffi/src/sparc/internal.h +26 -0
  245. data/ext/ffi_c/libffi/src/sparc/v8.S +364 -234
  246. data/ext/ffi_c/libffi/src/sparc/v9.S +340 -207
  247. data/ext/ffi_c/libffi/src/tile/ffi.c +355 -0
  248. data/ext/ffi_c/libffi/src/tile/ffitarget.h +65 -0
  249. data/ext/ffi_c/libffi/src/tile/tile.S +360 -0
  250. data/ext/ffi_c/libffi/src/tramp.c +716 -0
  251. data/ext/ffi_c/libffi/src/types.c +48 -19
  252. data/ext/ffi_c/libffi/src/vax/elfbsd.S +195 -0
  253. data/ext/ffi_c/libffi/src/vax/ffi.c +276 -0
  254. data/ext/ffi_c/libffi/src/vax/ffitarget.h +49 -0
  255. data/ext/ffi_c/libffi/src/wasm32/ffi.c +947 -0
  256. data/ext/ffi_c/libffi/src/wasm32/ffitarget.h +62 -0
  257. data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
  258. data/ext/ffi_c/libffi/src/x86/ffi.c +690 -540
  259. data/ext/ffi_c/libffi/src/x86/ffi64.c +450 -126
  260. data/ext/ffi_c/libffi/src/x86/ffitarget.h +86 -42
  261. data/ext/ffi_c/libffi/src/x86/ffiw64.c +361 -0
  262. data/ext/ffi_c/libffi/src/x86/internal.h +43 -0
  263. data/ext/ffi_c/libffi/src/x86/internal64.h +36 -0
  264. data/ext/ffi_c/libffi/src/x86/sysv.S +1199 -381
  265. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +998 -0
  266. data/ext/ffi_c/libffi/src/x86/unix64.S +587 -298
  267. data/ext/ffi_c/libffi/src/x86/win64.S +251 -457
  268. data/ext/ffi_c/libffi/src/x86/win64_intel.S +238 -0
  269. data/ext/ffi_c/libffi/src/xtensa/ffi.c +306 -0
  270. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +57 -0
  271. data/ext/ffi_c/libffi/src/xtensa/sysv.S +268 -0
  272. data/ext/ffi_c/libffi/stamp-h.in +1 -0
  273. data/ext/ffi_c/libffi/testsuite/Makefile.am +80 -73
  274. data/ext/ffi_c/libffi/testsuite/Makefile.in +251 -117
  275. data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +54 -0
  276. data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +63 -0
  277. data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +86 -0
  278. data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +48 -0
  279. data/ext/ffi_c/libffi/testsuite/emscripten/test.html +7 -0
  280. data/ext/ffi_c/libffi/testsuite/emscripten/test_libffi.py +51 -0
  281. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +682 -0
  282. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +22 -2
  283. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/Makefile +28 -0
  284. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/README +78 -0
  285. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/alignof.h +50 -0
  286. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +63 -0
  287. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +1746 -0
  288. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2885 -0
  289. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +747 -0
  290. data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
  291. data/ext/ffi_c/libffi/testsuite/libffi.call/align_stdcall.c +46 -0
  292. data/ext/ffi_c/libffi/testsuite/libffi.call/bpo_38748.c +41 -0
  293. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +28 -10
  294. data/ext/ffi_c/libffi/testsuite/libffi.call/callback.c +99 -0
  295. data/ext/ffi_c/libffi/testsuite/libffi.call/callback2.c +108 -0
  296. data/ext/ffi_c/libffi/testsuite/libffi.call/callback3.c +114 -0
  297. data/ext/ffi_c/libffi/testsuite/libffi.call/callback4.c +119 -0
  298. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +4 -3
  299. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +88 -42
  300. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +3 -1
  301. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +15 -12
  302. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +4 -2
  303. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +110 -0
  304. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +6 -16
  305. data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +57 -0
  306. data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +70 -0
  307. data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +78 -0
  308. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +0 -1
  309. data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +46 -0
  310. data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +127 -0
  311. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +1 -0
  312. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
  313. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +6 -0
  314. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +1 -1
  315. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +4 -0
  316. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +1 -1
  317. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +4 -0
  318. data/ext/ffi_c/libffi/testsuite/libffi.call/s55.c +60 -0
  319. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +9 -10
  320. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +49 -0
  321. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +49 -0
  322. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +55 -0
  323. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +9 -7
  324. data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +57 -0
  325. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +7 -7
  326. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +7 -6
  327. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +9 -8
  328. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +9 -8
  329. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +9 -9
  330. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +9 -9
  331. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +9 -8
  332. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +9 -8
  333. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_2.c +63 -0
  334. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3.c +65 -0
  335. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3f.c +65 -0
  336. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4.c +67 -0
  337. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4f.c +67 -0
  338. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_big.c +93 -0
  339. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_small.c +61 -0
  340. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_2H.c +63 -0
  341. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_8H.c +90 -0
  342. data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
  343. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +78 -0
  344. data/ext/ffi_c/libffi/testsuite/libffi.call/va_2.c +220 -0
  345. data/ext/ffi_c/libffi/testsuite/libffi.call/va_3.c +154 -0
  346. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +134 -0
  347. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +134 -0
  348. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +140 -0
  349. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure.exp +67 -0
  350. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn0.c +3 -2
  351. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn1.c +2 -0
  352. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn2.c +2 -0
  353. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn3.c +21 -1
  354. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn4.c +2 -0
  355. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn5.c +2 -0
  356. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn6.c +2 -0
  357. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_loc_fn0.c +7 -6
  358. data/ext/ffi_c/libffi/testsuite/{libffi.call/closure_stdcall.c → libffi.closures/closure_simple.c} +13 -16
  359. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_12byte.c +22 -4
  360. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_16byte.c +26 -4
  361. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_18byte.c +28 -4
  362. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_19byte.c +33 -4
  363. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_1_1byte.c +8 -4
  364. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_20byte.c +23 -5
  365. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_20byte1.c +25 -5
  366. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_24byte.c +40 -8
  367. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_2byte.c +17 -4
  368. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3_1byte.c +23 -4
  369. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3byte1.c +17 -4
  370. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3byte2.c +17 -4
  371. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3float.c +113 -0
  372. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_4_1byte.c +26 -4
  373. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_4byte.c +17 -4
  374. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_5_1_byte.c +33 -5
  375. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_5byte.c +23 -5
  376. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_64byte.c +29 -5
  377. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_6_1_byte.c +32 -5
  378. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_6byte.c +28 -6
  379. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_7_1_byte.c +43 -5
  380. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_7byte.c +29 -5
  381. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_8byte.c +18 -4
  382. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_9byte1.c +18 -5
  383. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_9byte2.c +18 -6
  384. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_double.c +23 -5
  385. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_float.c +23 -5
  386. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble.c +24 -5
  387. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble_split.c +44 -31
  388. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble_split2.c +44 -9
  389. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_pointer.c +23 -5
  390. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint16.c +22 -5
  391. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint32.c +22 -7
  392. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint64.c +23 -5
  393. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint16.c +22 -5
  394. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint32.c +23 -5
  395. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint64.c +24 -5
  396. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_dbls_struct.c +7 -5
  397. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_double_va.c +21 -9
  398. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_float.c +4 -0
  399. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_longdouble.c +13 -3
  400. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_longdouble_va.c +34 -11
  401. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_args.c +70 -0
  402. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_float_double.c +55 -0
  403. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_schar.c +5 -1
  404. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_sshort.c +6 -1
  405. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_sshortchar.c +9 -1
  406. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_uchar.c +9 -1
  407. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_ushort.c +6 -2
  408. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_ushortchar.c +9 -1
  409. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_pointer.c +7 -2
  410. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_pointer_stack.c +22 -10
  411. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_schar.c +3 -0
  412. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_sint.c +2 -0
  413. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_sshort.c +3 -0
  414. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_struct_va1.c +125 -0
  415. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uchar.c +3 -0
  416. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uint.c +4 -0
  417. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint_va.c +49 -0
  418. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulong_va.c +49 -0
  419. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ulonglong.c +8 -5
  420. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ushort.c +3 -0
  421. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/err_bad_abi.c +2 -3
  422. data/ext/ffi_c/libffi/testsuite/libffi.closures/ffitest.h +1 -0
  423. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/huge_struct.c +57 -56
  424. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct.c +38 -15
  425. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct1.c +9 -9
  426. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct10.c +19 -6
  427. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct11.c +137 -0
  428. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct12.c +86 -0
  429. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct13.c +115 -0
  430. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct2.c +15 -6
  431. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct3.c +15 -6
  432. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct4.c +14 -5
  433. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct5.c +14 -5
  434. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct6.c +17 -6
  435. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct7.c +14 -5
  436. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct8.c +17 -6
  437. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct9.c +17 -6
  438. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs1.c +86 -0
  439. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs2.c +102 -0
  440. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs3.c +101 -0
  441. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_large.c +7 -7
  442. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_large2.c +7 -7
  443. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_medium.c +6 -6
  444. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_medium2.c +7 -6
  445. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/testclosure.c +8 -3
  446. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.closures}/unwindtest.cc +4 -10
  447. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.closures}/unwindtest_ffi_call.cc +4 -2
  448. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +91 -0
  449. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +10 -0
  450. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +10 -0
  451. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +10 -0
  452. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +42 -0
  453. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +10 -0
  454. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +10 -0
  455. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +10 -0
  456. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +71 -0
  457. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +10 -0
  458. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +10 -0
  459. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +10 -0
  460. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +80 -0
  461. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +10 -0
  462. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +16 -0
  463. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +10 -0
  464. data/ext/ffi_c/libffi/testsuite/{libffi.special/special.exp → libffi.complex/complex.exp} +9 -10
  465. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +51 -0
  466. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +7 -0
  467. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +7 -0
  468. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +7 -0
  469. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +10 -0
  470. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +10 -0
  471. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +86 -0
  472. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +10 -0
  473. data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +1 -0
  474. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +78 -0
  475. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +10 -0
  476. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +10 -0
  477. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +10 -0
  478. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +37 -0
  479. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +41 -0
  480. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +10 -0
  481. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +10 -0
  482. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +10 -0
  483. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +44 -0
  484. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +10 -0
  485. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +10 -0
  486. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +10 -0
  487. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +10 -0
  488. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +10 -0
  489. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +10 -0
  490. data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +34 -0
  491. data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +28 -0
  492. data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +1 -0
  493. data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +36 -0
  494. data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +19 -0
  495. data/ext/ffi_c/libffi.bsd.mk +14 -8
  496. data/ext/ffi_c/libffi.darwin.mk +56 -26
  497. data/ext/ffi_c/libffi.gnu.mk +9 -6
  498. data/ext/ffi_c/libffi.mk +13 -8
  499. data/ext/ffi_c/libffi.vc.mk +26 -0
  500. data/ext/ffi_c/libffi.vc64.mk +26 -0
  501. data/ext/ffi_c/rbffi.h +34 -6
  502. data/ext/ffi_c/{endian.h → rbffi_endian.h} +21 -2
  503. data/ffi.gemspec +42 -0
  504. data/lib/ffi/abstract_memory.rb +44 -0
  505. data/lib/ffi/autopointer.rb +111 -52
  506. data/lib/ffi/compat.rb +43 -0
  507. data/lib/ffi/data_converter.rb +67 -0
  508. data/lib/ffi/dynamic_library.rb +118 -0
  509. data/lib/ffi/enum.rb +203 -22
  510. data/lib/ffi/errno.rb +27 -12
  511. data/lib/ffi/ffi.rb +88 -11
  512. data/lib/ffi/function.rb +71 -0
  513. data/lib/ffi/io.rb +35 -14
  514. data/lib/ffi/library.rb +382 -96
  515. data/lib/ffi/library_path.rb +109 -0
  516. data/lib/ffi/managedstruct.rb +64 -35
  517. data/lib/ffi/memorypointer.rb +1 -33
  518. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  519. data/lib/ffi/platform/aarch64-freebsd/types.conf +128 -0
  520. data/lib/ffi/platform/aarch64-freebsd12/types.conf +181 -0
  521. data/lib/ffi/platform/aarch64-linux/types.conf +175 -0
  522. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  523. data/lib/ffi/platform/aarch64-windows/types.conf +52 -0
  524. data/lib/ffi/platform/arm-freebsd/types.conf +152 -0
  525. data/lib/ffi/platform/arm-freebsd12/types.conf +152 -0
  526. data/lib/ffi/platform/arm-linux/types.conf +132 -0
  527. data/lib/ffi/platform/hppa1.1-linux/types.conf +178 -0
  528. data/lib/ffi/platform/hppa2.0-linux/types.conf +178 -0
  529. data/lib/ffi/platform/i386-cygwin/types.conf +3 -0
  530. data/lib/ffi/platform/i386-darwin/types.conf +100 -0
  531. data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
  532. data/lib/ffi/platform/i386-freebsd12/types.conf +152 -0
  533. data/lib/ffi/platform/i386-gnu/types.conf +107 -0
  534. data/lib/ffi/platform/i386-linux/types.conf +103 -0
  535. data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
  536. data/lib/ffi/platform/i386-openbsd/types.conf +128 -0
  537. data/lib/ffi/platform/i386-solaris/types.conf +122 -0
  538. data/lib/ffi/platform/i386-windows/types.conf +52 -0
  539. data/lib/ffi/platform/ia64-linux/types.conf +104 -0
  540. data/lib/ffi/platform/loongarch64-linux/types.conf +141 -0
  541. data/lib/ffi/platform/mips-linux/types.conf +102 -0
  542. data/lib/ffi/platform/mips64-linux/types.conf +104 -0
  543. data/lib/ffi/platform/mips64el-linux/types.conf +104 -0
  544. data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
  545. data/lib/ffi/platform/mipsisa32r6-linux/types.conf +102 -0
  546. data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +102 -0
  547. data/lib/ffi/platform/mipsisa64r6-linux/types.conf +104 -0
  548. data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +104 -0
  549. data/lib/ffi/platform/powerpc-aix/types.conf +180 -0
  550. data/lib/ffi/platform/powerpc-darwin/types.conf +100 -0
  551. data/lib/ffi/platform/powerpc-linux/types.conf +130 -0
  552. data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
  553. data/lib/ffi/platform/powerpc64-linux/types.conf +104 -0
  554. data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
  555. data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
  556. data/lib/ffi/platform/s390-linux/types.conf +102 -0
  557. data/lib/ffi/platform/s390x-linux/types.conf +102 -0
  558. data/lib/ffi/platform/sparc-linux/types.conf +102 -0
  559. data/lib/ffi/platform/sparc-solaris/types.conf +128 -0
  560. data/lib/ffi/platform/sparcv9-linux/types.conf +102 -0
  561. data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
  562. data/lib/ffi/platform/sparcv9-solaris/types.conf +128 -0
  563. data/lib/ffi/platform/sw_64-linux/types.conf +141 -0
  564. data/lib/ffi/platform/x86_64-cygwin/types.conf +3 -0
  565. data/lib/ffi/platform/x86_64-darwin/types.conf +130 -0
  566. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +130 -0
  567. data/lib/ffi/platform/x86_64-freebsd/types.conf +128 -0
  568. data/lib/ffi/platform/x86_64-freebsd12/types.conf +158 -0
  569. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  570. data/lib/ffi/platform/x86_64-linux/types.conf +132 -0
  571. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  572. data/lib/ffi/platform/x86_64-netbsd/types.conf +128 -0
  573. data/lib/ffi/platform/x86_64-openbsd/types.conf +134 -0
  574. data/lib/ffi/platform/x86_64-solaris/types.conf +122 -0
  575. data/lib/ffi/platform/x86_64-windows/types.conf +52 -0
  576. data/lib/ffi/platform.rb +110 -34
  577. data/lib/ffi/pointer.rb +117 -90
  578. data/lib/ffi/struct.rb +101 -70
  579. data/lib/ffi/struct_by_reference.rb +72 -0
  580. data/lib/ffi/struct_layout.rb +96 -0
  581. data/lib/ffi/struct_layout_builder.rb +90 -21
  582. data/lib/ffi/tools/const_generator.rb +86 -31
  583. data/lib/ffi/tools/generator.rb +49 -2
  584. data/lib/ffi/tools/generator_task.rb +13 -16
  585. data/lib/ffi/tools/struct_generator.rb +6 -5
  586. data/lib/ffi/tools/types_generator.rb +25 -11
  587. data/lib/ffi/types.rb +105 -36
  588. data/lib/ffi/union.rb +23 -12
  589. data/lib/ffi/variadic.rb +44 -29
  590. data/lib/ffi/version.rb +3 -0
  591. data/lib/ffi.rb +25 -9
  592. data/rakelib/ffi_gem_helper.rb +65 -0
  593. data/samples/getlogin.rb +8 -0
  594. data/samples/getpid.rb +8 -0
  595. data/samples/gettimeofday.rb +18 -0
  596. data/samples/hello.rb +8 -0
  597. data/samples/hello_ractor.rb +11 -0
  598. data/samples/inotify.rb +60 -0
  599. data/samples/pty.rb +75 -0
  600. data/samples/qsort.rb +20 -0
  601. data/samples/qsort_ractor.rb +28 -0
  602. data/sig/ffi/abstract_memory.rbs +165 -0
  603. data/sig/ffi/auto_pointer.rbs +26 -0
  604. data/sig/ffi/buffer.rbs +18 -0
  605. data/sig/ffi/data_converter.rbs +10 -0
  606. data/sig/ffi/dynamic_library.rbs +9 -0
  607. data/sig/ffi/enum.rbs +38 -0
  608. data/sig/ffi/function.rbs +39 -0
  609. data/sig/ffi/library.rbs +42 -0
  610. data/sig/ffi/native_type.rbs +86 -0
  611. data/sig/ffi/pointer.rbs +42 -0
  612. data/sig/ffi/struct.rbs +76 -0
  613. data/sig/ffi/struct_by_reference.rbs +11 -0
  614. data/sig/ffi/struct_by_value.rbs +7 -0
  615. data/sig/ffi/struct_layout.rbs +9 -0
  616. data/sig/ffi/struct_layout_builder.rbs +5 -0
  617. data/sig/ffi/type.rbs +39 -0
  618. data/sig/ffi.rbs +26 -0
  619. data.tar.gz.sig +0 -0
  620. metadata +547 -248
  621. metadata.gz.sig +0 -0
  622. data/History.txt +0 -109
  623. data/README.rdoc +0 -70
  624. data/ext/ffi_c/DataConverter.c +0 -62
  625. data/ext/ffi_c/StructByReference.c +0 -150
  626. data/ext/ffi_c/StructByReference.h +0 -50
  627. data/ext/ffi_c/libffi/ChangeLog.libffi +0 -658
  628. data/ext/ffi_c/libffi/ChangeLog.libgcj +0 -40
  629. data/ext/ffi_c/libffi/ChangeLog.v1 +0 -764
  630. data/ext/ffi_c/libffi/README +0 -306
  631. data/ext/ffi_c/libffi/aclocal.m4 +0 -8998
  632. data/ext/ffi_c/libffi/depcomp +0 -584
  633. data/ext/ffi_c/libffi/doc/libffi.info +0 -533
  634. data/ext/ffi_c/libffi/doc/stamp-vti +0 -4
  635. data/ext/ffi_c/libffi/m4/libtool.m4 +0 -7360
  636. data/ext/ffi_c/libffi/m4/ltoptions.m4 +0 -368
  637. data/ext/ffi_c/libffi/m4/ltsugar.m4 +0 -123
  638. data/ext/ffi_c/libffi/m4/ltversion.m4 +0 -23
  639. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +0 -92
  640. data/ext/ffi_c/libffi/mdate-sh +0 -201
  641. data/ext/ffi_c/libffi/src/x86/darwin.S +0 -444
  642. data/ext/ffi_c/libffi/src/x86/darwin64.S +0 -416
  643. data/ext/ffi_c/libffi/src/x86/freebsd.S +0 -458
  644. data/ext/ffi_c/libffi/src/x86/win32.S +0 -877
  645. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +0 -300
  646. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +0 -63
  647. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +0 -44
  648. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +0 -96
  649. data/ext/ffi_c/libffi/texinfo.tex +0 -7210
  650. data/gen/Rakefile +0 -14
  651. data/spec/ffi/async_callback_spec.rb +0 -23
  652. data/spec/ffi/bool_spec.rb +0 -24
  653. data/spec/ffi/buffer_spec.rb +0 -202
  654. data/spec/ffi/callback_spec.rb +0 -653
  655. data/spec/ffi/custom_param_type.rb +0 -31
  656. data/spec/ffi/custom_type_spec.rb +0 -73
  657. data/spec/ffi/enum_spec.rb +0 -183
  658. data/spec/ffi/errno_spec.rb +0 -13
  659. data/spec/ffi/ffi_spec.rb +0 -24
  660. data/spec/ffi/function_spec.rb +0 -73
  661. data/spec/ffi/library_spec.rb +0 -174
  662. data/spec/ffi/managed_struct_spec.rb +0 -56
  663. data/spec/ffi/number_spec.rb +0 -231
  664. data/spec/ffi/pointer_spec.rb +0 -210
  665. data/spec/ffi/rbx/attach_function_spec.rb +0 -28
  666. data/spec/ffi/rbx/memory_pointer_spec.rb +0 -109
  667. data/spec/ffi/rbx/spec_helper.rb +0 -1
  668. data/spec/ffi/rbx/struct_spec.rb +0 -13
  669. data/spec/ffi/spec_helper.rb +0 -21
  670. data/spec/ffi/string_spec.rb +0 -103
  671. data/spec/ffi/strptr_spec.rb +0 -36
  672. data/spec/ffi/struct_callback_spec.rb +0 -64
  673. data/spec/ffi/struct_initialize_spec.rb +0 -30
  674. data/spec/ffi/struct_packed_spec.rb +0 -46
  675. data/spec/ffi/struct_spec.rb +0 -638
  676. data/spec/ffi/typedef_spec.rb +0 -62
  677. data/spec/ffi/union_spec.rb +0 -60
  678. data/spec/ffi/variadic_spec.rb +0 -84
  679. data/spec/spec.opts +0 -4
  680. data/tasks/ann.rake +0 -80
  681. data/tasks/extension.rake +0 -25
  682. data/tasks/gem.rake +0 -200
  683. data/tasks/git.rake +0 -41
  684. data/tasks/notes.rake +0 -27
  685. data/tasks/post_load.rake +0 -34
  686. data/tasks/rdoc.rake +0 -50
  687. data/tasks/rubyforge.rake +0 -55
  688. data/tasks/setup.rb +0 -301
  689. data/tasks/spec.rake +0 -54
  690. data/tasks/svn.rake +0 -47
  691. data/tasks/test.rake +0 -40
  692. /data/ext/ffi_c/libffi/testsuite/libffi.call/{pyobjc-tc.c → pyobjc_tc.c} +0 -0
  693. /data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_double.c +0 -0
  694. /data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/problem1.c +0 -0
data/ext/ffi_c/Function.c CHANGED
@@ -1,40 +1,56 @@
1
1
  /*
2
- * Copyright (c) 2009, Wayne Meissner
3
-
4
- * All rights reserved.
2
+ * Copyright (c) 2009-2011 Wayne Meissner
5
3
  *
6
- * This file is part of ruby-ffi.
7
- *
8
- * This code is free software: you can redistribute it and/or modify it under
9
- * the terms of the GNU Lesser General Public License version 3 only, as
10
- * published by the Free Software Foundation.
4
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
5
+ * All rights reserved.
11
6
  *
12
- * This code is distributed in the hope that it will be useful, but WITHOUT
13
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
- * version 3 for more details.
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ * * Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of the Ruby FFI project nor the
15
+ * names of its contributors may be used to endorse or promote products
16
+ * derived from this software without specific prior written permission.
16
17
  *
17
- * You should have received a copy of the GNU Lesser General Public License
18
- * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
22
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
28
  */
20
29
 
21
- #include "MethodHandle.h"
22
-
23
-
30
+ #ifndef _MSC_VER
24
31
  #include <sys/param.h>
32
+ #endif
25
33
  #include <sys/types.h>
26
34
  #ifndef _WIN32
27
35
  # include <sys/mman.h>
36
+ # include <unistd.h>
28
37
  #endif
38
+
29
39
  #include <stdio.h>
30
40
  #include <stdint.h>
31
41
  #include <stdbool.h>
32
42
  #include <ruby.h>
43
+ #include <ruby/thread.h>
44
+
45
+ #if HAVE_RB_EXT_RACTOR_SAFE
46
+ #include <ruby/ractor.h>
47
+ #endif
33
48
 
34
49
  #include <ffi.h>
35
50
  #if defined(HAVE_NATIVETHREAD) && !defined(_WIN32)
36
51
  #include <pthread.h>
37
52
  #endif
53
+ #include <fcntl.h>
38
54
 
39
55
  #include "rbffi.h"
40
56
  #include "compat.h"
@@ -47,106 +63,245 @@
47
63
  #include "LastError.h"
48
64
  #include "Call.h"
49
65
  #include "ClosurePool.h"
50
- #include "Function.h"
51
66
  #include "MappedType.h"
67
+ #include "Thread.h"
68
+ #include "LongDouble.h"
69
+ #include "MethodHandle.h"
70
+ #include "Function.h"
71
+
72
+ #define DEFER_ASYNC_CALLBACK 1
52
73
 
74
+ struct async_cb_dispatcher;
53
75
  typedef struct Function_ {
54
- AbstractMemory memory;
76
+ Pointer base;
55
77
  FunctionType* info;
56
78
  MethodHandle* methodHandle;
57
79
  bool autorelease;
58
80
  Closure* closure;
59
81
  VALUE rbProc;
60
82
  VALUE rbFunctionInfo;
83
+ #if defined(DEFER_ASYNC_CALLBACK)
84
+ struct async_cb_dispatcher *dispatcher;
85
+ #endif
61
86
  } Function;
62
87
 
63
- static void function_mark(Function *);
64
- static void function_free(Function *);
88
+ static void function_mark(void *data);
89
+ static void function_compact(void *data);
90
+ static void function_free(void *data);
91
+ static size_t function_memsize(const void *data);
65
92
  static VALUE function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc);
66
93
  static void callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data);
67
94
  static bool callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize);
68
95
  static void* callback_with_gvl(void* data);
69
-
70
- #if defined(HAVE_NATIVETHREAD) && defined(HAVE_RB_THREAD_BLOCKING_REGION)
71
- # define DEFER_ASYNC_CALLBACK 1
72
- #endif
96
+ static VALUE invoke_callback(VALUE data);
97
+ static VALUE save_callback_exception(VALUE data, VALUE exc);
73
98
 
74
99
  #if defined(DEFER_ASYNC_CALLBACK)
75
- static VALUE async_cb_event(void);
100
+ static VALUE async_cb_event(void *);
76
101
  static VALUE async_cb_call(void *);
77
102
  #endif
78
103
 
79
- #if defined(HAVE_NATIVETHREAD) && defined (HAVE_RB_THREAD_BLOCKING_REGION)
80
- # define DEFER_ASYNC_CALLBACK
81
- #endif
82
-
83
- #ifdef HAVE_RUBY_THREAD_HAS_GVL_P
84
104
  extern int ruby_thread_has_gvl_p(void);
85
- #endif
86
-
87
- #ifdef HAVE_RB_THREAD_CALL_WITH_GVL
88
- extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
89
- #endif
105
+ extern int ruby_native_thread_p(void);
106
+
107
+ static const rb_data_type_t function_data_type = {
108
+ .wrap_struct_name = "FFI::Function",
109
+ .function = {
110
+ .dmark = function_mark,
111
+ .dfree = function_free,
112
+ .dsize = function_memsize,
113
+ ffi_compact_callback( function_compact )
114
+ },
115
+ .parent = &rbffi_pointer_data_type,
116
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
117
+ // macro to update VALUE references, as to trigger write barriers.
118
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
119
+ };
90
120
 
91
121
  VALUE rbffi_FunctionClass = Qnil;
92
122
 
93
- #if defined(DEFER_ASYNC_CALLBACK)
94
- static VALUE async_cb_thread = Qnil;
95
- #endif
96
-
97
123
  static ID id_call = 0, id_to_native = 0, id_from_native = 0, id_cbtable = 0, id_cb_ref = 0;
98
124
 
99
125
  struct gvl_callback {
100
126
  Closure* closure;
101
127
  void* retval;
102
128
  void** parameters;
103
-
129
+ bool done;
130
+ rbffi_frame_t *frame;
104
131
  #if defined(DEFER_ASYNC_CALLBACK)
132
+ struct async_cb_dispatcher *dispatcher;
105
133
  struct gvl_callback* next;
134
+
135
+ /* Signal when the callback has finished and retval is set */
106
136
  # ifndef _WIN32
107
137
  pthread_cond_t async_cond;
108
138
  pthread_mutex_t async_mutex;
139
+ # else
140
+ HANDLE async_event;
109
141
  # endif
110
142
  #endif
111
143
  };
112
144
 
113
145
 
114
146
  #if defined(DEFER_ASYNC_CALLBACK)
115
- static struct gvl_callback* async_cb_list = NULL;
147
+ struct async_cb_dispatcher {
148
+ /* the Ractor-local dispatcher thread */
149
+ VALUE thread;
150
+
151
+ /* single linked list of pending callbacks */
152
+ struct gvl_callback* async_cb_list;
153
+
154
+ /* Signal new entries in async_cb_list */
116
155
  # ifndef _WIN32
117
- static pthread_mutex_t async_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
118
- static pthread_cond_t async_cb_cond = PTHREAD_COND_INITIALIZER;
156
+ pthread_mutex_t async_cb_mutex;
157
+ pthread_cond_t async_cb_cond;
158
+ # else
159
+ HANDLE async_cb_cond;
160
+ CRITICAL_SECTION async_cb_lock;
119
161
  # endif
162
+ };
163
+
164
+ #if HAVE_RB_EXT_RACTOR_SAFE
165
+ static void
166
+ async_cb_dispatcher_mark(void *ptr)
167
+ {
168
+ struct async_cb_dispatcher *ctx = (struct async_cb_dispatcher *)ptr;
169
+ if (ctx) {
170
+ rb_gc_mark(ctx->thread);
171
+ }
172
+ }
173
+
174
+ static void
175
+ async_cb_dispatcher_free(void *ptr)
176
+ {
177
+ struct async_cb_dispatcher *ctx = (struct async_cb_dispatcher *)ptr;
178
+ if (ctx) {
179
+ xfree(ctx);
180
+ }
181
+ }
182
+
183
+ struct rb_ractor_local_storage_type async_cb_dispatcher_key_type = {
184
+ async_cb_dispatcher_mark,
185
+ async_cb_dispatcher_free,
186
+ };
187
+
188
+ static rb_ractor_local_key_t async_cb_dispatcher_key;
189
+
190
+ static struct async_cb_dispatcher *
191
+ async_cb_dispatcher_get(void)
192
+ {
193
+ struct async_cb_dispatcher *ctx = (struct async_cb_dispatcher *)rb_ractor_local_storage_ptr(async_cb_dispatcher_key);
194
+ return ctx;
195
+ }
196
+
197
+ static void
198
+ async_cb_dispatcher_set(struct async_cb_dispatcher *ctx)
199
+ {
200
+ rb_ractor_local_storage_ptr_set(async_cb_dispatcher_key, ctx);
201
+ }
202
+ #else
203
+ // for ruby 2.x
204
+ static struct async_cb_dispatcher *async_cb_dispatcher = NULL;
205
+
206
+ static struct async_cb_dispatcher *
207
+ async_cb_dispatcher_get(void)
208
+ {
209
+ return async_cb_dispatcher;
210
+ }
211
+
212
+ static void
213
+ async_cb_dispatcher_set(struct async_cb_dispatcher *ctx)
214
+ {
215
+ async_cb_dispatcher = ctx;
216
+ }
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);
120
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
+ }
241
+
242
+ static struct async_cb_dispatcher *
243
+ async_cb_dispatcher_ensure_created(void)
244
+ {
245
+ struct async_cb_dispatcher *ctx = async_cb_dispatcher_get();
246
+ if (ctx == NULL) {
247
+ ctx = (struct async_cb_dispatcher*)ALLOC(struct async_cb_dispatcher);
248
+ async_cb_dispatcher_initialize(ctx);
249
+ async_cb_dispatcher_set(ctx);
250
+ }
251
+ return ctx;
252
+ }
121
253
 
122
254
 
255
+ static VALUE
256
+ async_cb_dispatcher_atfork_child(VALUE self)
257
+ {
258
+ struct async_cb_dispatcher *ctx = async_cb_dispatcher_get();
259
+ if (ctx) {
260
+ async_cb_dispatcher_initialize(ctx);
261
+ }
262
+ return Qnil;
263
+ }
264
+ #endif
265
+
123
266
  static VALUE
124
267
  function_allocate(VALUE klass)
125
268
  {
126
269
  Function *fn;
127
270
  VALUE obj;
128
271
 
129
- obj = Data_Make_Struct(klass, Function, function_mark, function_free, fn);
272
+ obj = TypedData_Make_Struct(klass, Function, &function_data_type, fn);
130
273
 
131
- fn->memory.flags = MEM_RD;
132
-
133
- fn->rbProc = Qnil;
134
- fn->rbFunctionInfo = Qnil;
274
+ fn->base.memory.flags = MEM_RD;
275
+ RB_OBJ_WRITE(obj, &fn->base.rbParent, Qnil);
276
+ RB_OBJ_WRITE(obj, &fn->rbProc, Qnil);
277
+ RB_OBJ_WRITE(obj, &fn->rbFunctionInfo, Qnil);
135
278
  fn->autorelease = true;
136
279
 
137
280
  return obj;
138
281
  }
139
282
 
140
283
  static void
141
- function_mark(Function *fn)
284
+ function_mark(void *data)
285
+ {
286
+ Function *fn = (Function *)data;
287
+ rb_gc_mark_movable(fn->base.rbParent);
288
+ rb_gc_mark_movable(fn->rbProc);
289
+ rb_gc_mark_movable(fn->rbFunctionInfo);
290
+ }
291
+
292
+ static void
293
+ function_compact(void *data)
142
294
  {
143
- rb_gc_mark(fn->rbProc);
144
- rb_gc_mark(fn->rbFunctionInfo);
295
+ Function *fn = (Function *)data;
296
+ ffi_gc_location(fn->base.rbParent);
297
+ ffi_gc_location(fn->rbProc);
298
+ ffi_gc_location(fn->rbFunctionInfo);
145
299
  }
146
300
 
147
301
  static void
148
- function_free(Function *fn)
302
+ function_free(void *data)
149
303
  {
304
+ Function *fn = (Function *)data;
150
305
  if (fn->methodHandle != NULL) {
151
306
  rbffi_MethodHandle_Free(fn->methodHandle);
152
307
  }
@@ -158,10 +313,38 @@ function_free(Function *fn)
158
313
  xfree(fn);
159
314
  }
160
315
 
316
+ static size_t
317
+ function_memsize(const void *data)
318
+ {
319
+ const Function *fn = (const Function *)data;
320
+ size_t memsize = sizeof(Function);
321
+
322
+ // Would be nice to better account for MethodHandle and Closure too.
323
+ if (fn->closure) {
324
+ memsize += sizeof(Closure);
325
+ }
326
+
327
+ return memsize;
328
+ }
329
+
330
+ /*
331
+ * @param [Type, Symbol] return_type return type for the function
332
+ * @param [Array<Type, Symbol>] param_types array of parameters types
333
+ * @param [Hash] options see {FFI::FunctionType} for available options
334
+ * @return [self]
335
+ * A new Function instance.
336
+ *
337
+ * Define a function from a Proc or a block.
338
+ *
339
+ * @overload initialize(return_type, param_types, options = {}) { |i| ... }
340
+ * @yieldparam i parameters for the function
341
+ * @overload initialize(return_type, param_types, proc, options = {})
342
+ * @param [Proc] proc
343
+ */
161
344
  static VALUE
162
345
  function_initialize(int argc, VALUE* argv, VALUE self)
163
346
  {
164
-
347
+
165
348
  VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbProc = Qnil, rbOptions = Qnil;
166
349
  VALUE rbFunctionInfo = Qnil;
167
350
  VALUE infoArgv[3];
@@ -169,11 +352,11 @@ function_initialize(int argc, VALUE* argv, VALUE self)
169
352
 
170
353
  nargs = rb_scan_args(argc, argv, "22", &rbReturnType, &rbParamTypes, &rbProc, &rbOptions);
171
354
 
172
- //
173
- // Callback with block,
174
- // e.g. Function.new(:int, [ :int ]) { |i| blah }
175
- // or Function.new(:int, [ :int ], { :convention => :stdcall }) { |i| blah }
176
- //
355
+ /*
356
+ * Callback with block,
357
+ * e.g. Function.new(:int, [ :int ]) { |i| blah }
358
+ * or Function.new(:int, [ :int ], { :convention => :stdcall }) { |i| blah }
359
+ */
177
360
  if (rb_block_given_p()) {
178
361
  if (nargs > 3) {
179
362
  rb_raise(rb_eArgError, "cannot create function with both proc/address and block");
@@ -181,23 +364,36 @@ function_initialize(int argc, VALUE* argv, VALUE self)
181
364
  rbOptions = rbProc;
182
365
  rbProc = rb_block_proc();
183
366
  } else {
184
- // Callback with proc, or Function with address
185
- // e.g. Function.new(:int, [ :int ], Proc.new { |i| })
186
- // Function.new(:int, [ :int ], Proc.new { |i| }, { :convention => :stdcall })
187
- // Function.new(:int, [ :int ], addr)
188
- // Function.new(:int, [ :int ], addr, { :convention => :stdcall })
367
+ /* Callback with proc, or Function with address
368
+ * e.g. Function.new(:int, [ :int ], Proc.new { |i| })
369
+ * Function.new(:int, [ :int ], Proc.new { |i| }, { :convention => :stdcall })
370
+ * Function.new(:int, [ :int ], addr)
371
+ * Function.new(:int, [ :int ], addr, { :convention => :stdcall })
372
+ */
189
373
  }
190
-
374
+
191
375
  infoArgv[0] = rbReturnType;
192
376
  infoArgv[1] = rbParamTypes;
193
377
  infoArgv[2] = rbOptions;
194
378
  rbFunctionInfo = rb_class_new_instance(rbOptions != Qnil ? 3 : 2, infoArgv, rbffi_FunctionTypeClass);
195
379
 
196
380
  function_init(self, rbFunctionInfo, rbProc);
197
-
381
+
198
382
  return self;
199
383
  }
200
384
 
385
+ /*
386
+ * call-seq: initialize_copy(other)
387
+ * @return [nil]
388
+ * DO NOT CALL THIS METHOD
389
+ */
390
+ static VALUE
391
+ function_initialize_copy(VALUE self, VALUE other)
392
+ {
393
+ rb_raise(rb_eRuntimeError, "cannot duplicate function instances");
394
+ return Qnil;
395
+ }
396
+
201
397
  VALUE
202
398
  rbffi_Function_NewInstance(VALUE rbFunctionInfo, VALUE rbProc)
203
399
  {
@@ -208,22 +404,22 @@ VALUE
208
404
  rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
209
405
  {
210
406
  VALUE callback, cbref, cbTable;
211
- Function* fp;
212
407
 
213
408
  cbref = RTEST(rb_ivar_defined(proc, id_cb_ref)) ? rb_ivar_get(proc, id_cb_ref) : Qnil;
214
409
  /* If the first callback reference has the same function function signature, use it */
215
410
  if (cbref != Qnil && CLASS_OF(cbref) == rbffi_FunctionClass) {
216
- Data_Get_Struct(cbref, Function, fp);
411
+ Function* fp;
412
+ TypedData_Get_Struct(cbref, Function, &function_data_type, fp);
217
413
  if (fp->rbFunctionInfo == rbFunctionInfo) {
218
414
  return cbref;
219
415
  }
220
416
  }
221
-
417
+
222
418
  cbTable = RTEST(rb_ivar_defined(proc, id_cbtable)) ? rb_ivar_get(proc, id_cbtable) : Qnil;
223
419
  if (cbTable != Qnil && (callback = rb_hash_aref(cbTable, rbFunctionInfo)) != Qnil) {
224
420
  return callback;
225
421
  }
226
-
422
+
227
423
  /* No existing function for the proc with that signature, create a new one and cache it */
228
424
  callback = rbffi_Function_NewInstance(rbFunctionInfo, proc);
229
425
  if (cbref == Qnil) {
@@ -231,8 +427,10 @@ rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
231
427
  rb_ivar_set(proc, id_cb_ref, callback);
232
428
  } else {
233
429
  /* The proc instance has been used as more than one type of callback, store extras in a hash */
234
- cbTable = rb_hash_new();
235
- rb_ivar_set(proc, id_cbtable, cbTable);
430
+ if(cbTable == Qnil) {
431
+ cbTable = rb_hash_new();
432
+ rb_ivar_set(proc, id_cbtable, cbTable);
433
+ }
236
434
  rb_hash_aset(cbTable, rbFunctionInfo, callback);
237
435
  }
238
436
 
@@ -243,17 +441,18 @@ static VALUE
243
441
  function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
244
442
  {
245
443
  Function* fn = NULL;
246
-
247
- Data_Get_Struct(self, Function, fn);
248
444
 
249
- fn->rbFunctionInfo = rbFunctionInfo;
445
+ TypedData_Get_Struct(self, Function, &function_data_type, fn);
446
+
447
+ RB_OBJ_WRITE(self, &fn->rbFunctionInfo, rbFunctionInfo);
250
448
 
251
- Data_Get_Struct(fn->rbFunctionInfo, FunctionType, fn->info);
449
+ TypedData_Get_Struct(fn->rbFunctionInfo, FunctionType, &rbffi_fntype_data_type, fn->info);
252
450
 
253
451
  if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) {
254
- AbstractMemory* memory;
255
- Data_Get_Struct(rbProc, AbstractMemory, memory);
256
- fn->memory = *memory;
452
+ Pointer* orig;
453
+ TypedData_Get_Struct(rbProc, Pointer, &rbffi_pointer_data_type, orig);
454
+ fn->base.memory = orig->memory;
455
+ RB_OBJ_WRITE(self, &fn->base.rbParent, rbProc);
257
456
 
258
457
  } else if (rb_obj_is_kind_of(rbProc, rb_cProc) || rb_respond_to(rbProc, id_call)) {
259
458
  if (fn->info->closurePool == NULL) {
@@ -264,44 +463,55 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
264
463
  }
265
464
 
266
465
  #if defined(DEFER_ASYNC_CALLBACK)
267
- if (async_cb_thread == Qnil) {
268
- async_cb_thread = rb_thread_create(async_cb_event, NULL);
269
- }
466
+ fn->dispatcher = async_cb_dispatcher_ensure_created();
270
467
  #endif
271
468
 
272
469
  fn->closure = rbffi_Closure_Alloc(fn->info->closurePool);
273
470
  fn->closure->info = fn;
274
- fn->memory.address = fn->closure->code;
275
- fn->memory.size = sizeof(*fn->closure);
471
+ fn->base.memory.address = fn->closure->code;
472
+ fn->base.memory.size = sizeof(*fn->closure);
276
473
  fn->autorelease = true;
277
474
 
278
475
  } else {
279
476
  rb_raise(rb_eTypeError, "wrong argument type %s, expected pointer or proc",
280
477
  rb_obj_classname(rbProc));
281
478
  }
282
-
283
- fn->rbProc = rbProc;
479
+
480
+ RB_OBJ_WRITE(self, &fn->rbProc, rbProc);
284
481
 
285
482
  return self;
286
483
  }
287
484
 
485
+ /*
486
+ * call-seq: call(*args)
487
+ * @param [Array] args function arguments
488
+ * @return [FFI::Type]
489
+ * Call the function
490
+ */
288
491
  static VALUE
289
492
  function_call(int argc, VALUE* argv, VALUE self)
290
493
  {
291
494
  Function* fn;
292
495
 
293
- Data_Get_Struct(self, Function, fn);
496
+ TypedData_Get_Struct(self, Function, &function_data_type, fn);
294
497
 
295
- return (*fn->info->invoke)(argc, argv, fn->memory.address, fn->info);
498
+ return (*fn->info->invoke)(argc, argv, fn->base.memory.address, fn->info);
296
499
  }
297
500
 
501
+ /*
502
+ * call-seq: attach(m, name)
503
+ * @param [Module] m
504
+ * @param [String] name
505
+ * @return [self]
506
+ * Attach a Function to the Module +m+ as +name+.
507
+ */
298
508
  static VALUE
299
509
  function_attach(VALUE self, VALUE module, VALUE name)
300
510
  {
301
511
  Function* fn;
302
- char var[1024];
303
512
 
304
- Data_Get_Struct(self, Function, fn);
513
+ StringValue(name);
514
+ TypedData_Get_Struct(self, Function, &function_data_type, fn);
305
515
 
306
516
  if (fn->info->parameterCount == -1) {
307
517
  rb_raise(rb_eRuntimeError, "cannot attach variadic functions");
@@ -314,31 +524,32 @@ function_attach(VALUE self, VALUE module, VALUE name)
314
524
  }
315
525
 
316
526
  if (fn->methodHandle == NULL) {
317
- fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->memory.address);
527
+ fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->base.memory.address);
318
528
  }
319
529
 
320
- //
321
- // Stash the Function in a module variable so it does not get garbage collected
322
- //
323
- snprintf(var, sizeof(var), "@@%s", StringValueCStr(name));
324
- rb_cv_set(module, var, self);
325
-
326
530
  rb_define_singleton_method(module, StringValueCStr(name),
327
531
  rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
328
532
 
329
-
533
+
330
534
  rb_define_method(module, StringValueCStr(name),
331
535
  rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
332
536
 
333
537
  return self;
334
538
  }
335
539
 
540
+ /*
541
+ * call-seq: autorelease = autorelease
542
+ * @param [Boolean] autorelease
543
+ * @return [self]
544
+ * Set +autorelease+ attribute (See {Pointer}).
545
+ */
336
546
  static VALUE
337
547
  function_set_autorelease(VALUE self, VALUE autorelease)
338
548
  {
339
549
  Function* fn;
340
550
 
341
- Data_Get_Struct(self, Function, fn);
551
+ rb_check_frozen(self);
552
+ TypedData_Get_Struct(self, Function, &function_data_type, fn);
342
553
 
343
554
  fn->autorelease = RTEST(autorelease);
344
555
 
@@ -350,147 +561,251 @@ function_autorelease_p(VALUE self)
350
561
  {
351
562
  Function* fn;
352
563
 
353
- Data_Get_Struct(self, Function, fn);
564
+ TypedData_Get_Struct(self, Function, &function_data_type, fn);
354
565
 
355
566
  return fn->autorelease ? Qtrue : Qfalse;
356
567
  }
357
568
 
569
+ static VALUE
570
+ function_type(VALUE self)
571
+ {
572
+ Function* fn;
573
+
574
+ TypedData_Get_Struct(self, Function, &function_data_type, fn);
575
+
576
+ return fn->rbFunctionInfo;
577
+ }
578
+
579
+ /*
580
+ * call-seq: free
581
+ * @return [self]
582
+ * Free memory allocated by Function.
583
+ */
358
584
  static VALUE
359
585
  function_release(VALUE self)
360
586
  {
361
587
  Function* fn;
362
588
 
363
- Data_Get_Struct(self, Function, fn);
589
+ TypedData_Get_Struct(self, Function, &function_data_type, fn);
364
590
 
365
591
  if (fn->closure == NULL) {
366
592
  rb_raise(rb_eRuntimeError, "cannot free function which was not allocated");
367
593
  }
368
-
594
+
369
595
  rbffi_Closure_Free(fn->closure);
370
596
  fn->closure = NULL;
371
-
597
+
372
598
  return self;
373
599
  }
374
600
 
375
601
  static void
376
602
  callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
377
603
  {
378
- struct gvl_callback cb;
604
+ Function* fn;
605
+ struct gvl_callback cb = { 0 };
606
+
379
607
  cb.closure = (Closure *) user_data;
380
608
  cb.retval = retval;
381
609
  cb.parameters = parameters;
610
+ cb.done = false;
611
+ cb.frame = rbffi_frame_current();
612
+ fn = (Function *) cb.closure->info;
382
613
 
383
- #ifdef HAVE_RUBY_THREAD_HAS_GVL_P
384
- if (ruby_thread_has_gvl_p()) {
385
- #else
386
- if (1) {
387
- #endif
614
+ if (cb.frame != NULL) cb.frame->exc = Qnil;
615
+
616
+ if (ruby_native_thread_p()) {
617
+ if(ruby_thread_has_gvl_p()) {
388
618
  callback_with_gvl(&cb);
389
-
390
- #if defined(HAVE_RUBY_NATIVE_THREAD_P) && defined (HAVE_RB_THREAD_CALL_WITH_GVL)
391
- } else if (ruby_native_thread_p()) {
619
+ } else {
392
620
  rb_thread_call_with_gvl(callback_with_gvl, &cb);
393
- #endif
621
+ }
394
622
  #if defined(DEFER_ASYNC_CALLBACK) && !defined(_WIN32)
395
623
  } else {
624
+ bool empty = false;
625
+ struct async_cb_dispatcher *ctx = fn->dispatcher;
626
+
396
627
  pthread_mutex_init(&cb.async_mutex, NULL);
397
628
  pthread_cond_init(&cb.async_cond, NULL);
398
629
 
630
+ /* Now signal the async callback dispatcher thread */
631
+ pthread_mutex_lock(&ctx->async_cb_mutex);
632
+ empty = ctx->async_cb_list == NULL;
633
+ cb.next = ctx->async_cb_list;
634
+ ctx->async_cb_list = &cb;
635
+
636
+ pthread_cond_signal(&ctx->async_cb_cond);
637
+ pthread_mutex_unlock(&ctx->async_cb_mutex);
638
+
639
+ /* Wait for the thread executing the ruby callback to signal it is done */
399
640
  pthread_mutex_lock(&cb.async_mutex);
641
+ while (!cb.done) {
642
+ pthread_cond_wait(&cb.async_cond, &cb.async_mutex);
643
+ }
644
+ pthread_mutex_unlock(&cb.async_mutex);
645
+ pthread_cond_destroy(&cb.async_cond);
646
+ pthread_mutex_destroy(&cb.async_mutex);
647
+
648
+ #elif defined(DEFER_ASYNC_CALLBACK) && defined(_WIN32)
649
+ } else {
650
+ bool empty = false;
651
+ struct async_cb_dispatcher *ctx = fn->dispatcher;
400
652
 
401
- // Now signal the async callback thread
402
- pthread_mutex_lock(&async_cb_mutex);
403
- cb.next = async_cb_list;
404
- async_cb_list = &cb;
405
- pthread_cond_signal(&async_cb_cond);
406
- pthread_mutex_unlock(&async_cb_mutex);
653
+ cb.async_event = CreateEvent(NULL, FALSE, FALSE, NULL);
407
654
 
408
- // Wait for the thread executing the ruby callback to signal it is done
409
- pthread_cond_wait(&cb.async_cond, &cb.async_mutex);
655
+ /* Now signal the async callback dispatcher thread */
656
+ EnterCriticalSection(&ctx->async_cb_lock);
657
+ empty = ctx->async_cb_list == NULL;
658
+ cb.next = ctx->async_cb_list;
659
+ ctx->async_cb_list = &cb;
660
+ LeaveCriticalSection(&ctx->async_cb_lock);
661
+
662
+ SetEvent(ctx->async_cb_cond);
663
+
664
+ /* Wait for the thread executing the ruby callback to signal it is done */
665
+ WaitForSingleObject(cb.async_event, INFINITE);
666
+ CloseHandle(cb.async_event);
410
667
  #endif
411
668
  }
412
669
  }
413
670
 
414
671
  #if defined(DEFER_ASYNC_CALLBACK)
415
672
  struct async_wait {
673
+ struct async_cb_dispatcher *dispatcher;
416
674
  void* cb;
417
675
  bool stop;
418
676
  };
419
677
 
420
- static VALUE async_cb_wait(void *);
678
+ static void * async_cb_wait(void *);
421
679
  static void async_cb_stop(void *);
422
680
 
423
681
  static VALUE
424
- async_cb_event(void)
682
+ async_cb_event(void* ptr)
425
683
  {
426
- struct async_wait w = { 0 };
684
+ struct async_cb_dispatcher *ctx = (struct async_cb_dispatcher *)ptr;
685
+ struct async_wait w = { ctx };
427
686
 
428
687
  w.stop = false;
429
688
  while (!w.stop) {
430
- rb_thread_blocking_region(async_cb_wait, &w, async_cb_stop, &w);
689
+ rb_thread_call_without_gvl(async_cb_wait, &w, async_cb_stop, &w);
431
690
  if (w.cb != NULL) {
432
- // Start up a new ruby thread to run the ruby callback
433
- rb_thread_create(async_cb_call, w.cb);
691
+ /* Start up a new ruby thread to run the ruby callback */
692
+ VALUE new_thread = rb_thread_create(async_cb_call, w.cb);
693
+ /* Name thread, for better debugging */
694
+ rb_funcall(new_thread, rb_intern("name="), 1, rb_str_new2("FFI Callback Runner"));
434
695
  }
435
696
  }
436
-
697
+
437
698
  return Qnil;
438
699
  }
439
700
 
440
- static VALUE
701
+ #ifdef _WIN32
702
+ static void *
441
703
  async_cb_wait(void *data)
442
704
  {
443
705
  struct async_wait* w = (struct async_wait *) data;
706
+ struct async_cb_dispatcher *ctx = w->dispatcher;
444
707
 
445
708
  w->cb = NULL;
446
709
 
447
- pthread_mutex_lock(&async_cb_mutex);
710
+ EnterCriticalSection(&ctx->async_cb_lock);
448
711
 
449
- while (!w->stop && async_cb_list == NULL) {
450
- pthread_cond_wait(&async_cb_cond, &async_cb_mutex);
712
+ while (!w->stop && ctx->async_cb_list == NULL) {
713
+ LeaveCriticalSection(&ctx->async_cb_lock);
714
+ WaitForSingleObject(ctx->async_cb_cond, INFINITE);
715
+ EnterCriticalSection(&ctx->async_cb_lock);
451
716
  }
452
-
453
- if (async_cb_list != NULL) {
454
- w->cb = async_cb_list;
455
- async_cb_list = async_cb_list->next;
717
+
718
+ if (ctx->async_cb_list != NULL) {
719
+ w->cb = ctx->async_cb_list;
720
+ ctx->async_cb_list = ctx->async_cb_list->next;
456
721
  }
457
722
 
458
- pthread_mutex_unlock(&async_cb_mutex);
459
-
460
- return Qnil;
723
+ LeaveCriticalSection(&ctx->async_cb_lock);
724
+
725
+ return NULL;
461
726
  }
462
727
 
463
728
  static void
464
729
  async_cb_stop(void *data)
465
730
  {
466
731
  struct async_wait* w = (struct async_wait *) data;
732
+ struct async_cb_dispatcher *ctx = w->dispatcher;
467
733
 
468
- pthread_mutex_lock(&async_cb_mutex);
734
+ EnterCriticalSection(&ctx->async_cb_lock);
469
735
  w->stop = true;
470
- pthread_cond_signal(&async_cb_cond);
471
- pthread_mutex_unlock(&async_cb_mutex);
736
+ LeaveCriticalSection(&ctx->async_cb_lock);
737
+ SetEvent(ctx->async_cb_cond);
472
738
  }
473
739
 
740
+ #else
741
+ static void *
742
+ async_cb_wait(void *data)
743
+ {
744
+ struct async_wait* w = (struct async_wait *) data;
745
+ struct async_cb_dispatcher *ctx = w->dispatcher;
746
+
747
+ w->cb = NULL;
748
+
749
+ pthread_mutex_lock(&ctx->async_cb_mutex);
750
+
751
+ while (!w->stop && ctx->async_cb_list == NULL) {
752
+ pthread_cond_wait(&ctx->async_cb_cond, &ctx->async_cb_mutex);
753
+ }
754
+
755
+ if (ctx->async_cb_list != NULL) {
756
+ w->cb = ctx->async_cb_list;
757
+ ctx->async_cb_list = ctx->async_cb_list->next;
758
+ }
759
+
760
+ pthread_mutex_unlock(&ctx->async_cb_mutex);
761
+
762
+ return NULL;
763
+ }
764
+
765
+ static void
766
+ async_cb_stop(void *data)
767
+ {
768
+ struct async_wait* w = (struct async_wait *) data;
769
+ struct async_cb_dispatcher *ctx = w->dispatcher;
770
+
771
+ pthread_mutex_lock(&ctx->async_cb_mutex);
772
+ w->stop = true;
773
+ pthread_cond_signal(&ctx->async_cb_cond);
774
+ pthread_mutex_unlock(&ctx->async_cb_mutex);
775
+ }
776
+ #endif
777
+
474
778
  static VALUE
475
779
  async_cb_call(void *data)
476
780
  {
477
781
  struct gvl_callback* cb = (struct gvl_callback *) data;
478
782
 
479
- callback_with_gvl(cb);
783
+ callback_with_gvl(data);
480
784
 
481
- // Signal the original native thread that the ruby code has completed
785
+ /* Signal the original native thread that the ruby code has completed */
786
+ #ifdef _WIN32
787
+ SetEvent(cb->async_event);
788
+ #else
482
789
  pthread_mutex_lock(&cb->async_mutex);
790
+ cb->done = true;
483
791
  pthread_cond_signal(&cb->async_cond);
484
792
  pthread_mutex_unlock(&cb->async_mutex);
793
+ #endif
485
794
 
486
795
  return Qnil;
487
796
  }
488
797
 
489
798
  #endif
490
799
 
491
-
492
- static void*
800
+ static void *
493
801
  callback_with_gvl(void* data)
802
+ {
803
+ rb_rescue2(invoke_callback, (VALUE) data, save_callback_exception, (VALUE) data, rb_eException, (VALUE) 0);
804
+ return NULL;
805
+ }
806
+
807
+ static VALUE
808
+ invoke_callback(VALUE data)
494
809
  {
495
810
  struct gvl_callback* cb = (struct gvl_callback *) data;
496
811
 
@@ -511,8 +826,8 @@ callback_with_gvl(void* data)
511
826
  VALUE rbParamType = rb_ary_entry(cbInfo->rbParameterTypes, i);
512
827
 
513
828
  if (unlikely(paramType->nativeType == NATIVE_MAPPED)) {
514
- paramType = ((MappedType *) paramType)->type;
515
829
  rbParamType = ((MappedType *) paramType)->rbType;
830
+ paramType = ((MappedType *) paramType)->type;
516
831
  }
517
832
 
518
833
  switch (paramType->nativeType) {
@@ -552,8 +867,11 @@ callback_with_gvl(void* data)
552
867
  case NATIVE_FLOAT64:
553
868
  param = rb_float_new(*(double *) parameters[i]);
554
869
  break;
870
+ case NATIVE_LONGDOUBLE:
871
+ param = rbffi_longdouble_new(*(long double *) parameters[i]);
872
+ break;
555
873
  case NATIVE_STRING:
556
- param = (*(void **) parameters[i] != NULL) ? rb_tainted_str_new2(*(char **) parameters[i]) : Qnil;
874
+ param = (*(void **) parameters[i] != NULL) ? rb_str_new2(*(char **) parameters[i]) : Qnil;
557
875
  break;
558
876
  case NATIVE_POINTER:
559
877
  param = rbffi_Pointer_NewInstance(*(void **) parameters[i]);
@@ -563,9 +881,8 @@ callback_with_gvl(void* data)
563
881
  break;
564
882
 
565
883
  case NATIVE_FUNCTION:
566
- case NATIVE_CALLBACK:
567
884
  case NATIVE_STRUCT:
568
- param = rbffi_NativeValue_ToRuby(paramType, rbParamType, parameters[i], Qnil);
885
+ param = rbffi_NativeValue_ToRuby(paramType, rbParamType, parameters[i]);
569
886
  break;
570
887
 
571
888
  default:
@@ -573,7 +890,7 @@ callback_with_gvl(void* data)
573
890
  break;
574
891
  }
575
892
 
576
- // Convert the native value into a custom ruby value
893
+ /* Convert the native value into a custom ruby value */
577
894
  if (unlikely(cbInfo->parameterTypes[i]->nativeType == NATIVE_MAPPED)) {
578
895
  VALUE values[] = { param, Qnil };
579
896
  param = rb_funcall2(((MappedType *) cbInfo->parameterTypes[i])->rbConverter, id_from_native, 2, values);
@@ -583,7 +900,7 @@ callback_with_gvl(void* data)
583
900
  }
584
901
 
585
902
  rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams);
586
-
903
+
587
904
  if (unlikely(returnType->nativeType == NATIVE_MAPPED)) {
588
905
  VALUE values[] = { rbReturnValue, Qnil };
589
906
  rbReturnValue = rb_funcall2(((MappedType *) returnType)->rbConverter, id_to_native, 2, values);
@@ -622,11 +939,16 @@ callback_with_gvl(void* data)
622
939
  case NATIVE_FLOAT64:
623
940
  *((double *) retval) = NUM2DBL(rbReturnValue);
624
941
  break;
942
+ case NATIVE_LONGDOUBLE:
943
+ *((long double *) retval) = rbffi_num2longdouble(rbReturnValue);
944
+ break;
625
945
  case NATIVE_POINTER:
626
946
  if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
627
- *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
947
+ AbstractMemory* memory;
948
+ TypedData_Get_Struct(rbReturnValue, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
949
+ *((void **) retval) = memory->address;
628
950
  } else {
629
- // Default to returning NULL if not a value pointer object. handles nil case as well
951
+ /* Default to returning NULL if not a value pointer object. handles nil case as well */
630
952
  *((void **) retval) = NULL;
631
953
  }
632
954
  break;
@@ -636,17 +958,21 @@ callback_with_gvl(void* data)
636
958
  break;
637
959
 
638
960
  case NATIVE_FUNCTION:
639
- case NATIVE_CALLBACK:
640
961
  if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
962
+ AbstractMemory* memory;
963
+ TypedData_Get_Struct(rbReturnValue, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
641
964
 
642
- *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
965
+ *((void **) retval) = memory->address;
643
966
 
644
967
  } else if (rb_obj_is_kind_of(rbReturnValue, rb_cProc) || rb_respond_to(rbReturnValue, id_call)) {
645
968
  VALUE function;
969
+ AbstractMemory* memory;
646
970
 
647
971
  function = rbffi_Function_ForProc(rbReturnType, rbReturnValue);
648
972
 
649
- *((void **) retval) = ((AbstractMemory *) DATA_PTR(function))->address;
973
+ TypedData_Get_Struct(function, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
974
+
975
+ *((void **) retval) = memory->address;
650
976
  } else {
651
977
  *((void **) retval) = NULL;
652
978
  }
@@ -654,7 +980,11 @@ callback_with_gvl(void* data)
654
980
 
655
981
  case NATIVE_STRUCT:
656
982
  if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_StructClass)) {
657
- AbstractMemory* memory = ((Struct *) DATA_PTR(rbReturnValue))->pointer;
983
+ Struct* s;
984
+ AbstractMemory* memory;
985
+
986
+ TypedData_Get_Struct(rbReturnValue, Struct, &rbffi_struct_data_type, s);
987
+ memory = s->pointer;
658
988
 
659
989
  if (memory->address != NULL) {
660
990
  memcpy(retval, memory->address, returnType->ffiType->size);
@@ -662,7 +992,7 @@ callback_with_gvl(void* data)
662
992
  } else {
663
993
  memset(retval, 0, returnType->ffiType->size);
664
994
  }
665
-
995
+
666
996
  } else {
667
997
  memset(retval, 0, returnType->ffiType->size);
668
998
  }
@@ -673,9 +1003,19 @@ callback_with_gvl(void* data)
673
1003
  break;
674
1004
  }
675
1005
 
676
- return NULL;
1006
+ return Qnil;
677
1007
  }
678
1008
 
1009
+ static VALUE
1010
+ save_callback_exception(VALUE data, VALUE exc)
1011
+ {
1012
+ struct gvl_callback* cb = (struct gvl_callback *) data;
1013
+
1014
+ memset(cb->retval, 0, ((Function *) cb->closure->info)->info->returnType->ffiType->size);
1015
+ if (cb->frame != NULL) cb->frame->exc = exc;
1016
+
1017
+ return Qnil;
1018
+ }
679
1019
 
680
1020
  static bool
681
1021
  callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
@@ -683,9 +1023,9 @@ callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errm
683
1023
  FunctionType* fnInfo = (FunctionType *) ctx;
684
1024
  ffi_status ffiStatus;
685
1025
 
686
- ffiStatus = ffi_prep_closure(code, &fnInfo->ffi_cif, callback_invoke, closure);
1026
+ ffiStatus = ffi_prep_closure_loc(closure->pcl, &fnInfo->ffi_cif, callback_invoke, closure, code);
687
1027
  if (ffiStatus != FFI_OK) {
688
- snprintf(errmsg, errmsgsize, "ffi_prep_closure failed. status=%#x", ffiStatus);
1028
+ snprintf(errmsg, errmsgsize, "ffi_prep_closure_loc failed. status=%#x", ffiStatus);
689
1029
  return false;
690
1030
  }
691
1031
 
@@ -696,17 +1036,33 @@ void
696
1036
  rbffi_Function_Init(VALUE moduleFFI)
697
1037
  {
698
1038
  rbffi_FunctionInfo_Init(moduleFFI);
1039
+ /*
1040
+ * Document-class: FFI::Function < FFI::Pointer
1041
+ */
699
1042
  rbffi_FunctionClass = rb_define_class_under(moduleFFI, "Function", rbffi_PointerClass);
700
-
1043
+
701
1044
  rb_global_variable(&rbffi_FunctionClass);
702
1045
  rb_define_alloc_func(rbffi_FunctionClass, function_allocate);
703
1046
 
704
1047
  rb_define_method(rbffi_FunctionClass, "initialize", function_initialize, -1);
1048
+ rb_define_method(rbffi_FunctionClass, "initialize_copy", function_initialize_copy, 1);
705
1049
  rb_define_method(rbffi_FunctionClass, "call", function_call, -1);
706
1050
  rb_define_method(rbffi_FunctionClass, "attach", function_attach, 2);
707
1051
  rb_define_method(rbffi_FunctionClass, "free", function_release, 0);
708
1052
  rb_define_method(rbffi_FunctionClass, "autorelease=", function_set_autorelease, 1);
1053
+ rb_define_private_method(rbffi_FunctionClass, "type", function_type, 0);
1054
+ /*
1055
+ * call-seq: autorelease
1056
+ * @return [Boolean]
1057
+ * Get +autorelease+ attribute.
1058
+ * Synonymous for {#autorelease?}.
1059
+ */
709
1060
  rb_define_method(rbffi_FunctionClass, "autorelease", function_autorelease_p, 0);
1061
+ /*
1062
+ * call-seq: autorelease?
1063
+ * @return [Boolean] +autorelease+ attribute
1064
+ * Get +autorelease+ attribute.
1065
+ */
710
1066
  rb_define_method(rbffi_FunctionClass, "autorelease?", function_autorelease_p, 0);
711
1067
 
712
1068
  id_call = rb_intern("call");
@@ -714,5 +1070,12 @@ rbffi_Function_Init(VALUE moduleFFI)
714
1070
  id_cb_ref = rb_intern("@__ffi_callback__");
715
1071
  id_to_native = rb_intern("to_native");
716
1072
  id_from_native = rb_intern("from_native");
1073
+ #if defined(DEFER_ASYNC_CALLBACK) && defined(HAVE_RB_EXT_RACTOR_SAFE)
1074
+ async_cb_dispatcher_key = rb_ractor_local_storage_ptr_newkey(&async_cb_dispatcher_key_type);
1075
+ #endif
1076
+ #ifdef DEFER_ASYNC_CALLBACK
1077
+ /* Ruby code will call this method in a Process._fork patch */
1078
+ rb_define_singleton_method(moduleFFI, "_async_cb_dispatcher_atfork_child",
1079
+ async_cb_dispatcher_atfork_child, 0);
1080
+ #endif
717
1081
  }
718
-