ffi 1.9.24 → 1.16.3

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 (457) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +348 -0
  4. data/Gemfile +4 -5
  5. data/README.md +44 -17
  6. data/Rakefile +74 -148
  7. data/ext/ffi_c/AbstractMemory.c +89 -70
  8. data/ext/ffi_c/AbstractMemory.h +3 -2
  9. data/ext/ffi_c/ArrayType.c +49 -13
  10. data/ext/ffi_c/ArrayType.h +1 -0
  11. data/ext/ffi_c/Buffer.c +90 -38
  12. data/ext/ffi_c/Call.c +55 -56
  13. data/ext/ffi_c/Call.h +12 -6
  14. data/ext/ffi_c/ClosurePool.c +333 -0
  15. data/ext/ffi_c/{Closure.h → ClosurePool.h} +25 -13
  16. data/ext/ffi_c/DynamicLibrary.c +91 -33
  17. data/ext/ffi_c/Function.c +306 -235
  18. data/ext/ffi_c/Function.h +3 -5
  19. data/ext/ffi_c/FunctionInfo.c +87 -32
  20. data/ext/ffi_c/LastError.c +74 -15
  21. data/ext/ffi_c/LongDouble.c +12 -10
  22. data/ext/ffi_c/LongDouble.h +0 -4
  23. data/ext/ffi_c/MappedType.c +66 -23
  24. data/ext/ffi_c/MappedType.h +0 -2
  25. data/ext/ffi_c/MemoryPointer.c +37 -15
  26. data/ext/ffi_c/MemoryPointer.h +0 -4
  27. data/ext/ffi_c/MethodHandle.c +265 -38
  28. data/ext/ffi_c/MethodHandle.h +3 -2
  29. data/ext/ffi_c/Platform.c +5 -56
  30. data/ext/ffi_c/Pointer.c +93 -55
  31. data/ext/ffi_c/Pointer.h +1 -4
  32. data/ext/ffi_c/Struct.c +202 -134
  33. data/ext/ffi_c/Struct.h +18 -9
  34. data/ext/ffi_c/StructByValue.c +50 -23
  35. data/ext/ffi_c/StructLayout.c +135 -64
  36. data/ext/ffi_c/Thread.c +4 -228
  37. data/ext/ffi_c/Thread.h +1 -20
  38. data/ext/ffi_c/Type.c +105 -55
  39. data/ext/ffi_c/Type.h +3 -2
  40. data/ext/ffi_c/Types.c +8 -9
  41. data/ext/ffi_c/Types.h +3 -4
  42. data/ext/ffi_c/Variadic.c +88 -47
  43. data/ext/ffi_c/compat.h +26 -22
  44. data/ext/ffi_c/extconf.rb +75 -32
  45. data/ext/ffi_c/ffi.c +9 -10
  46. data/ext/ffi_c/libffi/.appveyor/site.exp +16 -0
  47. data/ext/ffi_c/libffi/.appveyor/unix-noexec.exp +7 -0
  48. data/ext/ffi_c/libffi/.appveyor.yml +53 -19
  49. data/ext/ffi_c/libffi/.ci/bfin-sim.exp +58 -0
  50. data/ext/ffi_c/libffi/.ci/build-cross-in-container.sh +18 -0
  51. data/ext/ffi_c/libffi/.ci/build-in-container.sh +10 -0
  52. data/ext/ffi_c/libffi/.ci/build.sh +124 -0
  53. data/ext/ffi_c/libffi/.ci/install.sh +78 -0
  54. data/ext/ffi_c/libffi/.ci/m32r-sim.exp +58 -0
  55. data/ext/ffi_c/libffi/{.travis → .ci}/moxie-sim.exp +1 -1
  56. data/ext/ffi_c/libffi/.ci/msvs-detect +1103 -0
  57. data/ext/ffi_c/libffi/.ci/or1k-sim.exp +58 -0
  58. data/ext/ffi_c/libffi/.ci/powerpc-eabisim.exp +58 -0
  59. data/ext/ffi_c/libffi/.ci/site.exp +29 -0
  60. data/ext/ffi_c/libffi/.ci/wine-sim.exp +55 -0
  61. data/ext/ffi_c/libffi/.circleci/config.yml +156 -0
  62. data/ext/ffi_c/libffi/.gitattributes +4 -0
  63. data/ext/ffi_c/libffi/.github/workflows/build.yml +460 -0
  64. data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +171 -0
  65. data/ext/ffi_c/libffi/.gitignore +10 -2
  66. data/ext/ffi_c/libffi/{ChangeLog.libffi-3.1 → ChangeLog.old} +1407 -0
  67. data/ext/ffi_c/libffi/LICENSE +1 -1
  68. data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +5 -4
  69. data/ext/ffi_c/libffi/Makefile.am +64 -73
  70. data/ext/ffi_c/libffi/Makefile.in +553 -235
  71. data/ext/ffi_c/libffi/README.md +165 -100
  72. data/ext/ffi_c/libffi/acinclude.m4 +10 -112
  73. data/ext/ffi_c/libffi/compile +348 -0
  74. data/ext/ffi_c/libffi/config.guess +950 -662
  75. data/ext/ffi_c/libffi/config.sub +1362 -1306
  76. data/ext/ffi_c/libffi/configure +4909 -4096
  77. data/ext/ffi_c/libffi/configure.ac +93 -32
  78. data/ext/ffi_c/libffi/configure.host +76 -28
  79. data/ext/ffi_c/libffi/doc/Makefile.in +15 -8
  80. data/ext/ffi_c/libffi/doc/libffi.texi +107 -46
  81. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  82. data/ext/ffi_c/libffi/fficonfig.h.in +22 -44
  83. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +165 -56
  84. data/ext/ffi_c/libffi/include/Makefile.am +1 -1
  85. data/ext/ffi_c/libffi/include/Makefile.in +17 -12
  86. data/ext/ffi_c/libffi/include/ffi.h.in +64 -48
  87. data/ext/ffi_c/libffi/include/ffi_cfi.h +21 -0
  88. data/ext/ffi_c/libffi/include/ffi_common.h +34 -1
  89. data/ext/ffi_c/libffi/include/tramp.h +45 -0
  90. data/ext/ffi_c/libffi/install-sh +107 -74
  91. data/ext/ffi_c/libffi/libffi.map.in +8 -12
  92. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +2 -48
  93. data/ext/ffi_c/libffi/libtool-version +2 -2
  94. data/ext/ffi_c/libffi/ltmain.sh +576 -284
  95. data/ext/ffi_c/libffi/m4/asmcfi.m4 +1 -1
  96. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +5 -26
  97. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +18 -14
  98. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +108 -72
  99. data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +5 -26
  100. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +76 -44
  101. data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +5 -26
  102. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +7 -3
  103. data/ext/ffi_c/libffi/m4/ax_prepend_flag.m4 +51 -0
  104. data/ext/ffi_c/libffi/make_sunver.pl +333 -0
  105. data/ext/ffi_c/libffi/man/Makefile.in +15 -8
  106. data/ext/ffi_c/libffi/missing +8 -8
  107. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.sln +33 -0
  108. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj +130 -0
  109. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters +57 -0
  110. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.user +4 -0
  111. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +511 -0
  112. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/fficonfig.h +219 -0
  113. data/ext/ffi_c/libffi/msvcc.sh +39 -14
  114. data/ext/ffi_c/libffi/src/aarch64/ffi.c +286 -98
  115. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +19 -3
  116. data/ext/ffi_c/libffi/src/aarch64/internal.h +33 -0
  117. data/ext/ffi_c/libffi/src/aarch64/sysv.S +142 -37
  118. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +506 -0
  119. data/ext/ffi_c/libffi/src/arc/arcompact.S +169 -94
  120. data/ext/ffi_c/libffi/src/arc/ffi.c +325 -148
  121. data/ext/ffi_c/libffi/src/arc/ffitarget.h +14 -0
  122. data/ext/ffi_c/libffi/src/arm/ffi.c +112 -10
  123. data/ext/ffi_c/libffi/src/arm/ffitarget.h +8 -1
  124. data/ext/ffi_c/libffi/src/arm/internal.h +10 -0
  125. data/ext/ffi_c/libffi/src/arm/sysv.S +117 -44
  126. data/ext/ffi_c/libffi/src/arm/sysv_msvc_arm32.S +311 -0
  127. data/ext/ffi_c/libffi/src/closures.c +189 -48
  128. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  129. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  130. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  131. data/ext/ffi_c/libffi/src/dlmalloc.c +6 -1
  132. data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
  133. data/ext/ffi_c/libffi/src/ia64/ffi.c +12 -0
  134. data/ext/ffi_c/libffi/src/ia64/unix.S +20 -2
  135. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  136. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  137. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  138. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  139. data/ext/ffi_c/libffi/src/loongarch64/ffi.c +621 -0
  140. data/ext/ffi_c/libffi/src/loongarch64/ffitarget.h +82 -0
  141. data/ext/ffi_c/libffi/src/loongarch64/sysv.S +327 -0
  142. data/ext/ffi_c/libffi/src/m32r/ffi.c +31 -14
  143. data/ext/ffi_c/libffi/src/metag/ffi.c +1 -1
  144. data/ext/ffi_c/libffi/src/mips/ffi.c +245 -66
  145. data/ext/ffi_c/libffi/src/mips/ffitarget.h +8 -1
  146. data/ext/ffi_c/libffi/src/mips/n32.S +137 -28
  147. data/ext/ffi_c/libffi/src/mips/o32.S +63 -4
  148. data/ext/ffi_c/libffi/src/moxie/ffi.c +48 -23
  149. data/ext/ffi_c/libffi/src/or1k/ffi.c +25 -12
  150. data/ext/ffi_c/libffi/src/pa/ffi.c +62 -108
  151. data/ext/ffi_c/libffi/src/pa/ffi64.c +614 -0
  152. data/ext/ffi_c/libffi/src/pa/ffitarget.h +20 -11
  153. data/ext/ffi_c/libffi/src/pa/hpux32.S +87 -38
  154. data/ext/ffi_c/libffi/src/pa/hpux64.S +681 -0
  155. data/ext/ffi_c/libffi/src/pa/linux.S +109 -39
  156. data/ext/ffi_c/libffi/src/powerpc/ffi.c +6 -4
  157. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +13 -1
  158. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +211 -32
  159. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +18 -7
  160. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +10 -4
  161. data/ext/ffi_c/libffi/src/powerpc/linux64.S +93 -28
  162. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +83 -5
  163. data/ext/ffi_c/libffi/src/powerpc/sysv.S +5 -7
  164. data/ext/ffi_c/libffi/src/powerpc/t-aix +5 -0
  165. data/ext/ffi_c/libffi/src/prep_cif.c +26 -4
  166. data/ext/ffi_c/libffi/src/riscv/ffi.c +79 -10
  167. data/ext/ffi_c/libffi/src/riscv/ffitarget.h +1 -0
  168. data/ext/ffi_c/libffi/src/riscv/sysv.S +86 -7
  169. data/ext/ffi_c/libffi/src/sparc/ffi64.c +16 -0
  170. data/ext/ffi_c/libffi/src/tramp.c +716 -0
  171. data/ext/ffi_c/libffi/src/wasm32/ffi.c +934 -0
  172. data/ext/ffi_c/libffi/src/wasm32/ffitarget.h +62 -0
  173. data/ext/ffi_c/libffi/src/x86/ffi.c +128 -49
  174. data/ext/ffi_c/libffi/src/x86/ffi64.c +89 -23
  175. data/ext/ffi_c/libffi/src/x86/ffitarget.h +21 -4
  176. data/ext/ffi_c/libffi/src/x86/ffiw64.c +63 -10
  177. data/ext/ffi_c/libffi/src/x86/internal.h +14 -0
  178. data/ext/ffi_c/libffi/src/x86/internal64.h +14 -0
  179. data/ext/ffi_c/libffi/src/x86/sysv.S +274 -45
  180. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +998 -0
  181. data/ext/ffi_c/libffi/src/x86/unix64.S +190 -4
  182. data/ext/ffi_c/libffi/src/x86/win64.S +32 -10
  183. data/ext/ffi_c/libffi/src/x86/win64_intel.S +3 -2
  184. data/ext/ffi_c/libffi/src/xtensa/ffi.c +16 -8
  185. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +4 -0
  186. data/ext/ffi_c/libffi/src/xtensa/sysv.S +26 -16
  187. data/ext/ffi_c/libffi/testsuite/Makefile.am +127 -109
  188. data/ext/ffi_c/libffi/testsuite/Makefile.in +144 -88
  189. data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +54 -0
  190. data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +63 -0
  191. data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +80 -0
  192. data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +48 -0
  193. data/ext/ffi_c/libffi/testsuite/emscripten/test.html +7 -0
  194. data/ext/ffi_c/libffi/testsuite/emscripten/test_libffi.py +51 -0
  195. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +71 -25
  196. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +2 -2
  197. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +7 -2
  198. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +5 -4
  199. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2 -2
  200. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +5 -1
  201. data/ext/ffi_c/libffi/testsuite/libffi.call/bpo_38748.c +41 -0
  202. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +12 -1
  203. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +28 -3
  204. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +9 -8
  205. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +3 -0
  206. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +5 -0
  207. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +4 -0
  208. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +4 -0
  209. data/ext/ffi_c/libffi/testsuite/libffi.call/s55.c +60 -0
  210. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +8 -9
  211. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +2 -2
  212. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +2 -2
  213. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +2 -2
  214. data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +1 -1
  215. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_2.c +63 -0
  216. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3.c +65 -0
  217. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3f.c +65 -0
  218. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4.c +67 -0
  219. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4f.c +67 -0
  220. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_big.c +93 -0
  221. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_small.c +61 -0
  222. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_2H.c +63 -0
  223. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_8H.c +90 -0
  224. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +1 -119
  225. data/ext/ffi_c/libffi/testsuite/libffi.call/va_2.c +220 -0
  226. data/ext/ffi_c/libffi/testsuite/libffi.call/va_3.c +154 -0
  227. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +13 -0
  228. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +11 -0
  229. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +15 -0
  230. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure.exp +67 -0
  231. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn0.c +3 -2
  232. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn1.c +2 -0
  233. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn2.c +2 -0
  234. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn3.c +21 -1
  235. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn4.c +2 -0
  236. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn5.c +2 -0
  237. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn6.c +2 -0
  238. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_loc_fn0.c +7 -6
  239. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_simple.c +6 -0
  240. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_12byte.c +18 -0
  241. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_16byte.c +22 -0
  242. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_18byte.c +24 -0
  243. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_19byte.c +29 -0
  244. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_1_1byte.c +4 -0
  245. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_20byte.c +19 -1
  246. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_20byte1.c +21 -1
  247. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_24byte.c +35 -3
  248. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_2byte.c +13 -0
  249. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3_1byte.c +19 -0
  250. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3byte1.c +13 -0
  251. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3byte2.c +13 -0
  252. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3float.c +18 -0
  253. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_4_1byte.c +22 -0
  254. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_4byte.c +13 -0
  255. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_5_1_byte.c +29 -1
  256. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_5byte.c +19 -1
  257. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_64byte.c +24 -0
  258. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_6_1_byte.c +28 -1
  259. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_6byte.c +24 -2
  260. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_7_1_byte.c +39 -1
  261. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_7byte.c +25 -1
  262. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_8byte.c +14 -0
  263. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_9byte1.c +14 -1
  264. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_9byte2.c +14 -2
  265. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_double.c +19 -1
  266. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_float.c +19 -1
  267. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble.c +20 -1
  268. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble_split.c +40 -25
  269. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble_split2.c +40 -3
  270. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_pointer.c +19 -1
  271. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint16.c +18 -1
  272. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint32.c +18 -3
  273. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint64.c +18 -1
  274. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint16.c +18 -1
  275. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint32.c +19 -1
  276. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint64.c +19 -1
  277. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_dbls_struct.c +3 -1
  278. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_double_va.c +9 -1
  279. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_float.c +4 -0
  280. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_longdouble.c +11 -1
  281. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_longdouble_va.c +22 -3
  282. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_schar.c +5 -1
  283. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_sshort.c +6 -1
  284. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_sshortchar.c +9 -1
  285. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_uchar.c +9 -1
  286. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_ushort.c +6 -2
  287. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_ushortchar.c +9 -1
  288. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_pointer.c +5 -0
  289. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_pointer_stack.c +10 -0
  290. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_schar.c +3 -0
  291. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_sint.c +2 -0
  292. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_sshort.c +3 -0
  293. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_struct_va1.c +11 -0
  294. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uchar.c +3 -0
  295. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uint.c +4 -0
  296. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uint_va.c +4 -0
  297. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ulong_va.c +4 -0
  298. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ulonglong.c +2 -0
  299. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ushort.c +3 -0
  300. data/ext/ffi_c/libffi/testsuite/libffi.closures/ffitest.h +1 -0
  301. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/huge_struct.c +24 -22
  302. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct.c +32 -9
  303. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct1.c +1 -1
  304. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct10.c +12 -0
  305. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct11.c +21 -5
  306. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct12.c +86 -0
  307. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct13.c +115 -0
  308. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct2.c +10 -1
  309. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct3.c +10 -1
  310. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct4.c +9 -0
  311. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct5.c +9 -0
  312. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct6.c +11 -0
  313. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct7.c +9 -0
  314. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct8.c +11 -0
  315. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct9.c +11 -0
  316. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs1.c +86 -0
  317. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs2.c +102 -0
  318. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs3.c +101 -0
  319. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_medium.c +1 -1
  320. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_medium2.c +1 -1
  321. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/testclosure.c +6 -1
  322. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/unwindtest.cc +2 -1
  323. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/unwindtest_ffi_call.cc +1 -0
  324. data/ext/ffi_c/libffi.bsd.mk +2 -2
  325. data/ext/ffi_c/libffi.darwin.mk +1 -1
  326. data/ext/ffi_c/libffi.gnu.mk +2 -2
  327. data/ext/ffi_c/rbffi.h +1 -3
  328. data/ffi.gemspec +15 -9
  329. data/lib/ffi/abstract_memory.rb +44 -0
  330. data/lib/ffi/autopointer.rb +8 -23
  331. data/lib/ffi/compat.rb +43 -0
  332. data/lib/ffi/data_converter.rb +67 -0
  333. data/lib/ffi/dynamic_library.rb +89 -0
  334. data/lib/ffi/enum.rb +18 -11
  335. data/lib/ffi/ffi.rb +6 -0
  336. data/lib/ffi/function.rb +71 -0
  337. data/lib/ffi/io.rb +3 -3
  338. data/lib/ffi/library.rb +65 -77
  339. data/lib/ffi/library_path.rb +109 -0
  340. data/lib/ffi/managedstruct.rb +3 -3
  341. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  342. data/lib/ffi/platform/aarch64-freebsd/types.conf +128 -0
  343. data/lib/ffi/platform/aarch64-freebsd12/types.conf +181 -0
  344. data/lib/ffi/platform/aarch64-linux/types.conf +81 -81
  345. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  346. data/lib/ffi/platform/aarch64-windows/types.conf +52 -0
  347. data/lib/ffi/platform/arm-freebsd/types.conf +152 -0
  348. data/lib/ffi/platform/arm-freebsd12/types.conf +152 -0
  349. data/lib/ffi/platform/arm-linux/types.conf +110 -82
  350. data/lib/ffi/platform/hppa1.1-linux/types.conf +178 -0
  351. data/lib/ffi/platform/hppa2.0-linux/types.conf +178 -0
  352. data/lib/ffi/platform/i386-cygwin/types.conf +1 -1
  353. data/lib/ffi/platform/i386-darwin/types.conf +63 -63
  354. data/lib/ffi/platform/i386-freebsd/types.conf +89 -89
  355. data/lib/ffi/platform/i386-freebsd12/types.conf +152 -0
  356. data/lib/ffi/platform/i386-gnu/types.conf +84 -84
  357. data/lib/ffi/platform/i386-linux/types.conf +77 -77
  358. data/lib/ffi/platform/i386-netbsd/types.conf +87 -87
  359. data/lib/ffi/platform/i386-openbsd/types.conf +89 -89
  360. data/lib/ffi/platform/i386-solaris/types.conf +96 -96
  361. data/lib/ffi/platform/i386-windows/types.conf +43 -96
  362. data/lib/ffi/platform/ia64-linux/types.conf +79 -79
  363. data/lib/ffi/platform/loongarch64-linux/types.conf +141 -0
  364. data/lib/ffi/platform/mips-linux/types.conf +79 -79
  365. data/lib/ffi/platform/mips64-linux/types.conf +81 -81
  366. data/lib/ffi/platform/mips64el-linux/types.conf +81 -81
  367. data/lib/ffi/platform/mipsel-linux/types.conf +79 -79
  368. data/lib/ffi/platform/mipsisa32r6-linux/types.conf +79 -79
  369. data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +79 -79
  370. data/lib/ffi/platform/mipsisa64r6-linux/types.conf +81 -81
  371. data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +81 -81
  372. data/lib/ffi/platform/powerpc-aix/types.conf +155 -155
  373. data/lib/ffi/platform/powerpc-darwin/types.conf +63 -63
  374. data/lib/ffi/platform/powerpc-linux/types.conf +108 -78
  375. data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
  376. data/lib/ffi/platform/powerpc64-linux/types.conf +81 -81
  377. data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
  378. data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
  379. data/lib/ffi/platform/s390-linux/types.conf +79 -79
  380. data/lib/ffi/platform/s390x-linux/types.conf +79 -79
  381. data/lib/ffi/platform/sparc-linux/types.conf +79 -79
  382. data/lib/ffi/platform/sparc-solaris/types.conf +103 -103
  383. data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
  384. data/lib/ffi/platform/sparcv9-solaris/types.conf +103 -103
  385. data/lib/ffi/platform/sw_64-linux/types.conf +141 -0
  386. data/lib/ffi/platform/x86_64-cygwin/types.conf +1 -1
  387. data/lib/ffi/platform/x86_64-darwin/types.conf +88 -84
  388. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +130 -0
  389. data/lib/ffi/platform/x86_64-freebsd/types.conf +90 -90
  390. data/lib/ffi/platform/x86_64-freebsd12/types.conf +158 -0
  391. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  392. data/lib/ffi/platform/x86_64-linux/types.conf +107 -77
  393. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  394. data/lib/ffi/platform/x86_64-netbsd/types.conf +89 -89
  395. data/lib/ffi/platform/x86_64-openbsd/types.conf +86 -86
  396. data/lib/ffi/platform/x86_64-solaris/types.conf +96 -96
  397. data/lib/ffi/platform/x86_64-windows/types.conf +42 -110
  398. data/lib/ffi/platform.rb +43 -20
  399. data/lib/ffi/pointer.rb +26 -20
  400. data/lib/ffi/struct.rb +14 -68
  401. data/lib/ffi/struct_by_reference.rb +72 -0
  402. data/lib/ffi/struct_layout.rb +96 -0
  403. data/lib/ffi/struct_layout_builder.rb +1 -1
  404. data/lib/ffi/tools/const_generator.rb +11 -8
  405. data/lib/ffi/tools/generator.rb +47 -2
  406. data/lib/ffi/tools/generator_task.rb +13 -17
  407. data/lib/ffi/tools/struct_generator.rb +6 -5
  408. data/lib/ffi/tools/types_generator.rb +7 -4
  409. data/lib/ffi/types.rb +33 -7
  410. data/lib/ffi/variadic.rb +20 -18
  411. data/lib/ffi/version.rb +1 -1
  412. data/lib/ffi.rb +10 -3
  413. data/rakelib/ffi_gem_helper.rb +65 -0
  414. data/samples/getlogin.rb +1 -1
  415. data/samples/getpid.rb +1 -1
  416. data/samples/gettimeofday.rb +8 -8
  417. data/samples/hello.rb +2 -1
  418. data/samples/hello_ractor.rb +11 -0
  419. data/samples/inotify.rb +1 -1
  420. data/samples/pty.rb +1 -2
  421. data/samples/qsort.rb +0 -1
  422. data/samples/qsort_ractor.rb +28 -0
  423. data.tar.gz.sig +0 -0
  424. metadata +252 -153
  425. metadata.gz.sig +0 -0
  426. data/.gitignore +0 -22
  427. data/.gitmodules +0 -3
  428. data/.travis.yml +0 -52
  429. data/.yardopts +0 -5
  430. data/appveyor.yml +0 -22
  431. data/ext/ffi_c/Closure.c +0 -54
  432. data/ext/ffi_c/DataConverter.c +0 -91
  433. data/ext/ffi_c/StructByReference.c +0 -190
  434. data/ext/ffi_c/StructByReference.h +0 -50
  435. data/ext/ffi_c/libffi/.travis/build.sh +0 -34
  436. data/ext/ffi_c/libffi/.travis/install.sh +0 -22
  437. data/ext/ffi_c/libffi/.travis/site.exp +0 -18
  438. data/ext/ffi_c/libffi/.travis.yml +0 -34
  439. data/ext/ffi_c/libffi/ChangeLog.libffi +0 -584
  440. data/ext/ffi_c/libffi/ChangeLog.libgcj +0 -40
  441. data/ext/ffi_c/libffi/ChangeLog.v1 +0 -764
  442. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar_va.c +0 -44
  443. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort_va.c +0 -44
  444. data/ext/ffi_c/win32/stdbool.h +0 -8
  445. data/ext/ffi_c/win32/stdint.h +0 -201
  446. data/samples/sample_helper.rb +0 -6
  447. data/ext/ffi_c/libffi/{.travis → .ci}/ar-lib +0 -0
  448. data/ext/ffi_c/libffi/{.travis → .ci}/compile +0 -0
  449. data/ext/ffi_c/libffi/testsuite/libffi.call/{pyobjc-tc.c → pyobjc_tc.c} +0 -0
  450. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_double.c +0 -0
  451. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_many_mixed_args.c +0 -0
  452. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_many_mixed_float_double.c +0 -0
  453. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/err_bad_abi.c +0 -0
  454. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/problem1.c +0 -0
  455. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_large.c +0 -0
  456. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_large2.c +0 -0
  457. data/lib/ffi/platform/{sparc64-linux → sparcv9-linux}/types.conf +79 -79
@@ -0,0 +1,621 @@
1
+ /* -----------------------------------------------------------------------
2
+ ffi.c - Copyright (c) 2022 Xu Chenghua <xuchenghua@loongson.cn>
3
+ 2022 Cheng Lulu <chenglulu@loongson.cn>
4
+ Based on RISC-V port
5
+
6
+ LoongArch Foreign Function Interface
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ ``Software''), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included
17
+ in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26
+ DEALINGS IN THE SOFTWARE.
27
+ ----------------------------------------------------------------------- */
28
+
29
+ #include <ffi.h>
30
+ #include <ffi_common.h>
31
+
32
+ #include <stdlib.h>
33
+ #include <stdint.h>
34
+
35
+ #if defined(__loongarch_soft_float)
36
+ # define ABI_FRLEN 0
37
+ #elif defined(__loongarch_single_float)
38
+ # define ABI_FRLEN 32
39
+ # define ABI_FLOAT float
40
+ #elif defined(__loongarch_double_float)
41
+ # define ABI_FRLEN 64
42
+ # define ABI_FLOAT double
43
+ #else
44
+ #error unsupported LoongArch floating-point ABI
45
+ #endif
46
+
47
+ #define NARGREG 8
48
+ #define STKALIGN 16
49
+ #define MAXCOPYARG (2 * sizeof (double))
50
+
51
+ /* call_context registers
52
+ - 8 floating point parameter/result registers.
53
+ - 8 integer parameter/result registers.
54
+ - 2 registers used by the assembly code to in-place construct its own
55
+ stack frame
56
+ - frame register
57
+ - return register
58
+ */
59
+ typedef struct call_context
60
+ {
61
+ ABI_FLOAT fa[8];
62
+ size_t a[10];
63
+ } call_context;
64
+
65
+ typedef struct call_builder
66
+ {
67
+ call_context *aregs;
68
+ int used_integer;
69
+ int used_float;
70
+ size_t *used_stack;
71
+ size_t *stack;
72
+ size_t next_struct_area;
73
+ } call_builder;
74
+
75
+ /* Integer (not pointer) less than ABI GRLEN. */
76
+ /* FFI_TYPE_INT does not appear to be used. */
77
+ #if __SIZEOF_POINTER__ == 8
78
+ # define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT64)
79
+ #else
80
+ # define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT32)
81
+ #endif
82
+
83
+ #if ABI_FRLEN
84
+ typedef struct float_struct_info
85
+ {
86
+ char as_elements;
87
+ char type1;
88
+ char offset2;
89
+ char type2;
90
+ } float_struct_info;
91
+
92
+ #if ABI_FRLEN >= 64
93
+ # define IS_FLOAT(type) ((type) >= FFI_TYPE_FLOAT && (type) <= FFI_TYPE_DOUBLE)
94
+ #else
95
+ # define IS_FLOAT(type) ((type) == FFI_TYPE_FLOAT)
96
+ #endif
97
+
98
+ static ffi_type **
99
+ flatten_struct (ffi_type *in, ffi_type **out, ffi_type **out_end)
100
+ {
101
+ int i;
102
+
103
+ if (out == out_end)
104
+ return out;
105
+ if (in->type != FFI_TYPE_STRUCT)
106
+ *(out++) = in;
107
+ else
108
+ for (i = 0; in->elements[i]; i++)
109
+ out = flatten_struct (in->elements[i], out, out_end);
110
+ return out;
111
+ }
112
+
113
+ /* Structs with at most two fields after flattening, one of which is of
114
+ floating point type, are passed in multiple registers if sufficient
115
+ registers are available. */
116
+ static float_struct_info
117
+ struct_passed_as_elements (call_builder *cb, ffi_type *top)
118
+ {
119
+ float_struct_info ret = {0, 0, 0, 0};
120
+ ffi_type *fields[3];
121
+ int num_floats, num_ints;
122
+ int num_fields = flatten_struct (top, fields, fields + 3) - fields;
123
+
124
+ if (num_fields == 1)
125
+ {
126
+ if (IS_FLOAT (fields[0]->type))
127
+ {
128
+ ret.as_elements = 1;
129
+ ret.type1 = fields[0]->type;
130
+ }
131
+ }
132
+ else if (num_fields == 2)
133
+ {
134
+ num_floats = IS_FLOAT (fields[0]->type) + IS_FLOAT (fields[1]->type);
135
+ num_ints = IS_INT (fields[0]->type) + IS_INT (fields[1]->type);
136
+ if (num_floats == 0 || num_floats + num_ints != 2)
137
+ return ret;
138
+ if (cb->used_float + num_floats > NARGREG
139
+ || cb->used_integer + (2 - num_floats) > NARGREG)
140
+ return ret;
141
+ if (!IS_FLOAT (fields[0]->type) && !IS_FLOAT (fields[1]->type))
142
+ return ret;
143
+
144
+ ret.type1 = fields[0]->type;
145
+ ret.type2 = fields[1]->type;
146
+ ret.offset2 = FFI_ALIGN (fields[0]->size, fields[1]->alignment);
147
+ ret.as_elements = 1;
148
+ }
149
+ return ret;
150
+ }
151
+ #endif
152
+
153
+ /* Allocates a single register, float register, or GRLEN-sized stack slot to a
154
+ datum. */
155
+ static void
156
+ marshal_atom (call_builder *cb, int type, void *data)
157
+ {
158
+ size_t value = 0;
159
+ switch (type)
160
+ {
161
+ case FFI_TYPE_UINT8:
162
+ value = *(uint8_t *) data;
163
+ break;
164
+ case FFI_TYPE_SINT8:
165
+ value = *(int8_t *) data;
166
+ break;
167
+ case FFI_TYPE_UINT16:
168
+ value = *(uint16_t *) data;
169
+ break;
170
+ case FFI_TYPE_SINT16:
171
+ value = *(int16_t *) data;
172
+ break;
173
+ /* 32-bit quantities are always sign-extended in the ABI. */
174
+ case FFI_TYPE_UINT32:
175
+ value = *(int32_t *) data;
176
+ break;
177
+ case FFI_TYPE_SINT32:
178
+ value = *(int32_t *) data;
179
+ break;
180
+ #if __SIZEOF_POINTER__ == 8
181
+ case FFI_TYPE_UINT64:
182
+ value = *(uint64_t *) data;
183
+ break;
184
+ case FFI_TYPE_SINT64:
185
+ value = *(int64_t *) data;
186
+ break;
187
+ #endif
188
+ case FFI_TYPE_POINTER:
189
+ value = *(size_t *) data;
190
+ break;
191
+
192
+ #if ABI_FRLEN >= 32
193
+ case FFI_TYPE_FLOAT:
194
+ *(float *)(cb->aregs->fa + cb->used_float++) = *(float *) data;
195
+ return;
196
+ #endif
197
+ #if ABI_FRLEN >= 64
198
+ case FFI_TYPE_DOUBLE:
199
+ (cb->aregs->fa[cb->used_float++]) = *(double *) data;
200
+ return;
201
+ #endif
202
+ default:
203
+ FFI_ASSERT (0);
204
+ break;
205
+ }
206
+
207
+ if (cb->used_integer == NARGREG)
208
+ *cb->used_stack++ = value;
209
+ else
210
+ cb->aregs->a[cb->used_integer++] = value;
211
+ }
212
+
213
+ static void
214
+ unmarshal_atom (call_builder *cb, int type, void *data)
215
+ {
216
+ size_t value;
217
+ switch (type)
218
+ {
219
+ #if ABI_FRLEN >= 32
220
+ case FFI_TYPE_FLOAT:
221
+ *(float *) data = *(float *)(cb->aregs->fa + cb->used_float++);
222
+ return;
223
+ #endif
224
+ #if ABI_FRLEN >= 64
225
+ case FFI_TYPE_DOUBLE:
226
+ *(double *) data = cb->aregs->fa[cb->used_float++];
227
+ return;
228
+ #endif
229
+ }
230
+
231
+ if (cb->used_integer == NARGREG)
232
+ value = *cb->used_stack++;
233
+ else
234
+ value = cb->aregs->a[cb->used_integer++];
235
+
236
+ switch (type)
237
+ {
238
+ case FFI_TYPE_UINT8:
239
+ case FFI_TYPE_SINT8:
240
+ case FFI_TYPE_UINT16:
241
+ case FFI_TYPE_SINT16:
242
+ case FFI_TYPE_UINT32:
243
+ case FFI_TYPE_SINT32:
244
+ #if __SIZEOF_POINTER__ == 8
245
+ case FFI_TYPE_UINT64:
246
+ case FFI_TYPE_SINT64:
247
+ #endif
248
+ case FFI_TYPE_POINTER:
249
+ *(ffi_arg *)data = value;
250
+ break;
251
+ default:
252
+ FFI_ASSERT (0);
253
+ break;
254
+ }
255
+ }
256
+
257
+ /* Allocate and copy a structure that is passed by value on the stack and
258
+ return a pointer to it. */
259
+ static void *
260
+ allocate_and_copy_struct_to_stack (call_builder *cb, void *data,
261
+ ffi_type *type)
262
+ {
263
+ size_t dest = cb->next_struct_area - type->size;
264
+
265
+ dest = FFI_ALIGN_DOWN (dest, type->alignment);
266
+ cb->next_struct_area = dest;
267
+
268
+ return memcpy ((char *)cb->stack + dest, data, type->size);
269
+ }
270
+
271
+ /* Adds an argument to a call, or a not by reference return value. */
272
+ static void
273
+ marshal (call_builder *cb, ffi_type *type, int var, void *data)
274
+ {
275
+ size_t realign[2];
276
+
277
+ #if ABI_FRLEN
278
+ if (!var && type->type == FFI_TYPE_STRUCT)
279
+ {
280
+ float_struct_info fsi = struct_passed_as_elements (cb, type);
281
+ if (fsi.as_elements)
282
+ {
283
+ marshal_atom (cb, fsi.type1, data);
284
+ if (fsi.offset2)
285
+ marshal_atom (cb, fsi.type2, ((char *) data) + fsi.offset2);
286
+ return;
287
+ }
288
+ }
289
+
290
+ if (!var && cb->used_float < NARGREG
291
+ && IS_FLOAT (type->type))
292
+ {
293
+ marshal_atom (cb, type->type, data);
294
+ return;
295
+ }
296
+
297
+ double promoted;
298
+ if (var && type->type == FFI_TYPE_FLOAT)
299
+ {
300
+ /* C standard requires promoting float -> double for variable arg. */
301
+ promoted = *(float *) data;
302
+ type = &ffi_type_double;
303
+ data = &promoted;
304
+ }
305
+ #endif
306
+
307
+ if (type->size > 2 * __SIZEOF_POINTER__)
308
+ /* Pass by reference. */
309
+ {
310
+ allocate_and_copy_struct_to_stack (cb, data, type);
311
+ data = (char *)cb->stack + cb->next_struct_area;
312
+ marshal_atom (cb, FFI_TYPE_POINTER, &data);
313
+ }
314
+ else if (IS_INT (type->type) || type->type == FFI_TYPE_POINTER)
315
+ marshal_atom (cb, type->type, data);
316
+ else
317
+ {
318
+ /* Overlong integers, soft-float floats, and structs without special
319
+ float handling are treated identically from this point on. */
320
+
321
+ /* Variadics are aligned even in registers. */
322
+ if (type->alignment > __SIZEOF_POINTER__)
323
+ {
324
+ if (var)
325
+ cb->used_integer = FFI_ALIGN (cb->used_integer, 2);
326
+ cb->used_stack
327
+ = (size_t *) FFI_ALIGN (cb->used_stack, 2 * __SIZEOF_POINTER__);
328
+ }
329
+
330
+ memcpy (realign, data, type->size);
331
+ if (type->size > 0)
332
+ marshal_atom (cb, FFI_TYPE_POINTER, realign);
333
+ if (type->size > __SIZEOF_POINTER__)
334
+ marshal_atom (cb, FFI_TYPE_POINTER, realign + 1);
335
+ }
336
+ }
337
+
338
+ /* For arguments passed by reference returns the pointer, otherwise the arg
339
+ is copied (up to MAXCOPYARG bytes). */
340
+ static void *
341
+ unmarshal (call_builder *cb, ffi_type *type, int var, void *data)
342
+ {
343
+ size_t realign[2];
344
+ void *pointer;
345
+
346
+ #if ABI_FRLEN
347
+ if (!var && type->type == FFI_TYPE_STRUCT)
348
+ {
349
+ float_struct_info fsi = struct_passed_as_elements (cb, type);
350
+ if (fsi.as_elements)
351
+ {
352
+ unmarshal_atom (cb, fsi.type1, data);
353
+ if (fsi.offset2)
354
+ unmarshal_atom (cb, fsi.type2, ((char *) data) + fsi.offset2);
355
+ return data;
356
+ }
357
+ }
358
+
359
+ if (!var && cb->used_float < NARGREG
360
+ && IS_FLOAT (type->type))
361
+ {
362
+ unmarshal_atom (cb, type->type, data);
363
+ return data;
364
+ }
365
+
366
+ if (var && type->type == FFI_TYPE_FLOAT)
367
+ {
368
+ int m = cb->used_integer;
369
+ void *promoted
370
+ = m < NARGREG ? cb->aregs->a + m : cb->used_stack + m - NARGREG + 1;
371
+ *(float *) promoted = *(double *) promoted;
372
+ }
373
+ #endif
374
+
375
+ if (type->size > 2 * __SIZEOF_POINTER__)
376
+ {
377
+ /* Pass by reference. */
378
+ unmarshal_atom (cb, FFI_TYPE_POINTER, (char *) &pointer);
379
+ return pointer;
380
+ }
381
+ else if (IS_INT (type->type) || type->type == FFI_TYPE_POINTER)
382
+ {
383
+ unmarshal_atom (cb, type->type, data);
384
+ return data;
385
+ }
386
+ else
387
+ {
388
+ /* Overlong integers, soft-float floats, and structs without special
389
+ float handling are treated identically from this point on. */
390
+
391
+ /* Variadics are aligned even in registers. */
392
+ if (type->alignment > __SIZEOF_POINTER__)
393
+ {
394
+ if (var)
395
+ cb->used_integer = FFI_ALIGN (cb->used_integer, 2);
396
+ cb->used_stack
397
+ = (size_t *) FFI_ALIGN (cb->used_stack, 2 * __SIZEOF_POINTER__);
398
+ }
399
+
400
+ if (type->size > 0)
401
+ unmarshal_atom (cb, FFI_TYPE_POINTER, realign);
402
+ if (type->size > __SIZEOF_POINTER__)
403
+ unmarshal_atom (cb, FFI_TYPE_POINTER, realign + 1);
404
+ memcpy (data, realign, type->size);
405
+ return data;
406
+ }
407
+ }
408
+
409
+ static int
410
+ passed_by_ref (call_builder *cb, ffi_type *type, int var)
411
+ {
412
+ #if ABI_FRLEN
413
+ if (!var && type->type == FFI_TYPE_STRUCT)
414
+ {
415
+ float_struct_info fsi = struct_passed_as_elements (cb, type);
416
+ if (fsi.as_elements)
417
+ return 0;
418
+ }
419
+ #endif
420
+
421
+ return type->size > 2 * __SIZEOF_POINTER__;
422
+ }
423
+
424
+ /* Perform machine dependent cif processing. */
425
+ ffi_status
426
+ ffi_prep_cif_machdep (ffi_cif *cif)
427
+ {
428
+ cif->loongarch_nfixedargs = cif->nargs;
429
+ return FFI_OK;
430
+ }
431
+
432
+ /* Perform machine dependent cif processing when we have a variadic
433
+ function. */
434
+ ffi_status
435
+ ffi_prep_cif_machdep_var (ffi_cif *cif, unsigned int nfixedargs,
436
+ unsigned int ntotalargs)
437
+ {
438
+ cif->loongarch_nfixedargs = nfixedargs;
439
+ return FFI_OK;
440
+ }
441
+
442
+ /* Low level routine for calling functions. */
443
+ extern void ffi_call_asm (void *stack, struct call_context *regs,
444
+ void (*fn) (void), void *closure) FFI_HIDDEN;
445
+
446
+ static void
447
+ ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,
448
+ void *closure)
449
+ {
450
+ /* This is a conservative estimate, assuming a complex return value and
451
+ that all remaining arguments are long long / __int128 */
452
+ size_t arg_bytes = cif->bytes;
453
+ size_t rval_bytes = 0;
454
+ if (rvalue == NULL && cif->rtype->size > 2 * __SIZEOF_POINTER__)
455
+ rval_bytes = FFI_ALIGN (cif->rtype->size, STKALIGN);
456
+ size_t alloc_size = arg_bytes + rval_bytes + sizeof (call_context);
457
+
458
+ /* The assembly code will deallocate all stack data at lower addresses
459
+ than the argument region, so we need to allocate the frame and the
460
+ return value after the arguments in a single allocation. */
461
+ size_t alloc_base;
462
+ /* Argument region must be 16-byte aligned in LP64 ABIs. */
463
+ if (_Alignof(max_align_t) >= STKALIGN)
464
+ /* Since sizeof long double is normally 16, the compiler will
465
+ guarantee alloca alignment to at least that much. */
466
+ alloc_base = (size_t) alloca (alloc_size);
467
+ else
468
+ alloc_base = FFI_ALIGN (alloca (alloc_size + STKALIGN - 1), STKALIGN);
469
+
470
+ if (rval_bytes)
471
+ rvalue = (void *) (alloc_base + arg_bytes);
472
+
473
+ call_builder cb;
474
+ cb.used_float = cb.used_integer = 0;
475
+ cb.aregs = (call_context *) (alloc_base + arg_bytes + rval_bytes);
476
+ cb.used_stack = (void *) alloc_base;
477
+ cb.stack = (void *) alloc_base;
478
+ cb.next_struct_area = arg_bytes;
479
+
480
+ int return_by_ref = passed_by_ref (&cb, cif->rtype, 0);
481
+ if (return_by_ref)
482
+ cb.aregs->a[cb.used_integer++] = (size_t)rvalue;
483
+
484
+ int i;
485
+ for (i = 0; i < cif->nargs; i++)
486
+ marshal (&cb, cif->arg_types[i], i >= cif->loongarch_nfixedargs,
487
+ avalue[i]);
488
+
489
+ ffi_call_asm ((void *) alloc_base, cb.aregs, fn, closure);
490
+
491
+ cb.used_float = cb.used_integer = 0;
492
+ if (!return_by_ref && rvalue)
493
+ unmarshal (&cb, cif->rtype, 0, rvalue);
494
+ }
495
+
496
+ void
497
+ ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
498
+ {
499
+ ffi_call_int (cif, fn, rvalue, avalue, NULL);
500
+ }
501
+
502
+ void
503
+ ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,
504
+ void *closure)
505
+ {
506
+ ffi_call_int (cif, fn, rvalue, avalue, closure);
507
+ }
508
+
509
+ extern void ffi_closure_asm (void) FFI_HIDDEN;
510
+
511
+ ffi_status
512
+ ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif,
513
+ void (*fun) (ffi_cif *, void *, void **, void *),
514
+ void *user_data, void *codeloc)
515
+ {
516
+ uint32_t *tramp = (uint32_t *) &closure->tramp[0];
517
+ uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm;
518
+
519
+ if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)
520
+ return FFI_BAD_ABI;
521
+
522
+ #if defined(FFI_EXEC_STATIC_TRAMP)
523
+ if (ffi_tramp_is_present(closure))
524
+ {
525
+ ffi_tramp_set_parms (closure->ftramp, ffi_closure_asm, closure);
526
+ goto out;
527
+ }
528
+ #endif
529
+
530
+ /* Fill the dynamic trampoline. We will call ffi_closure_inner with codeloc,
531
+ not closure, but as long as the memory is readable it should work. */
532
+ tramp[0] = 0x1800000c; /* pcaddi $t0, 0 (i.e. $t0 <- tramp) */
533
+ tramp[1] = 0x28c0418d; /* ld.d $t1, $t0, 16 */
534
+ tramp[2] = 0x4c0001a0; /* jirl $zero, $t1, 0 */
535
+ tramp[3] = 0x03400000; /* nop */
536
+ tramp[4] = fn;
537
+ tramp[5] = fn >> 32;
538
+
539
+ __builtin___clear_cache (codeloc, codeloc + FFI_TRAMPOLINE_SIZE);
540
+
541
+ #if defined(FFI_EXEC_STATIC_TRAMP)
542
+ out:
543
+ #endif
544
+ closure->cif = cif;
545
+ closure->fun = fun;
546
+ closure->user_data = user_data;
547
+
548
+ return FFI_OK;
549
+ }
550
+
551
+ extern void ffi_go_closure_asm (void) FFI_HIDDEN;
552
+
553
+ ffi_status
554
+ ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
555
+ void (*fun) (ffi_cif *, void *, void **, void *))
556
+ {
557
+ if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)
558
+ return FFI_BAD_ABI;
559
+
560
+ closure->tramp = (void *) ffi_go_closure_asm;
561
+ closure->cif = cif;
562
+ closure->fun = fun;
563
+ return FFI_OK;
564
+ }
565
+
566
+ /* Called by the assembly code with aregs pointing to saved argument registers
567
+ and stack pointing to the stacked arguments. Return values passed in
568
+ registers will be reloaded from aregs. */
569
+ void FFI_HIDDEN
570
+ ffi_closure_inner (ffi_cif *cif,
571
+ void (*fun) (ffi_cif *, void *, void **, void *),
572
+ void *user_data, size_t *stack, call_context *aregs)
573
+ {
574
+ void **avalue = alloca (cif->nargs * sizeof (void *));
575
+ /* Storage for arguments which will be copied by unmarshal(). We could
576
+ theoretically avoid the copies in many cases and use at most 128 bytes
577
+ of memory, but allocating disjoint storage for each argument is
578
+ simpler. */
579
+ char *astorage = alloca (cif->nargs * MAXCOPYARG);
580
+ void *rvalue;
581
+ call_builder cb;
582
+ int return_by_ref;
583
+ int i;
584
+
585
+ cb.aregs = aregs;
586
+ cb.used_integer = cb.used_float = 0;
587
+ cb.used_stack = stack;
588
+
589
+ return_by_ref = passed_by_ref (&cb, cif->rtype, 0);
590
+ if (return_by_ref)
591
+ unmarshal (&cb, &ffi_type_pointer, 0, &rvalue);
592
+ else
593
+ rvalue = alloca (cif->rtype->size);
594
+
595
+ for (i = 0; i < cif->nargs; i++)
596
+ avalue[i]
597
+ = unmarshal (&cb, cif->arg_types[i], i >= cif->loongarch_nfixedargs,
598
+ astorage + i * MAXCOPYARG);
599
+
600
+ fun (cif, rvalue, avalue, user_data);
601
+
602
+ if (!return_by_ref && cif->rtype->type != FFI_TYPE_VOID)
603
+ {
604
+ cb.used_integer = cb.used_float = 0;
605
+ marshal (&cb, cif->rtype, 0, rvalue);
606
+ }
607
+ }
608
+
609
+ #if defined(FFI_EXEC_STATIC_TRAMP)
610
+ void *
611
+ ffi_tramp_arch (size_t *tramp_size, size_t *map_size)
612
+ {
613
+ extern void *trampoline_code_table;
614
+
615
+ *tramp_size = 16;
616
+ /* A mapping size of 64K is chosen to cover the page sizes of 4K, 16K, and
617
+ 64K. */
618
+ *map_size = 1 << 16;
619
+ return &trampoline_code_table;
620
+ }
621
+ #endif
@@ -0,0 +1,82 @@
1
+ /* -----------------------------------------------------------------*-C-*-
2
+ ffitarget.h - Copyright (c) 2022 Xu Chenghua <xuchenghua@loongson.cn>
3
+ 2022 Cheng Lulu <chenglulu@loongson.cn>
4
+
5
+ Target configuration macros for LoongArch.
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining
8
+ a copy of this software and associated documentation files (the
9
+ ``Software''), to deal in the Software without restriction, including
10
+ without limitation the rights to use, copy, modify, merge, publish,
11
+ distribute, sublicense, and/or sell copies of the Software, and to
12
+ permit persons to whom the Software is furnished to do so, subject to
13
+ the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included
16
+ in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
+ DEALINGS IN THE SOFTWARE.
26
+
27
+ ----------------------------------------------------------------------- */
28
+
29
+ #ifndef LIBFFI_TARGET_H
30
+ #define LIBFFI_TARGET_H
31
+
32
+ #ifndef LIBFFI_H
33
+ #error \
34
+ "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
35
+ #endif
36
+
37
+ #ifndef __loongarch__
38
+ #error \
39
+ "libffi was configured for a LoongArch target but this does not appear to be a LoongArch compiler."
40
+ #endif
41
+
42
+ #ifndef LIBFFI_ASM
43
+
44
+ typedef unsigned long ffi_arg;
45
+ typedef signed long ffi_sarg;
46
+
47
+ typedef enum ffi_abi
48
+ {
49
+ FFI_FIRST_ABI = 0,
50
+ FFI_LP64S,
51
+ FFI_LP64F,
52
+ FFI_LP64D,
53
+ FFI_LAST_ABI,
54
+
55
+ #if defined(__loongarch64)
56
+ #if defined(__loongarch_soft_float)
57
+ FFI_DEFAULT_ABI = FFI_LP64S
58
+ #elif defined(__loongarch_single_float)
59
+ FFI_DEFAULT_ABI = FFI_LP64F
60
+ #elif defined(__loongarch_double_float)
61
+ FFI_DEFAULT_ABI = FFI_LP64D
62
+ #else
63
+ #error unsupported LoongArch floating-point ABI
64
+ #endif
65
+ #else
66
+ #error unsupported LoongArch base architecture
67
+ #endif
68
+ } ffi_abi;
69
+
70
+ #endif /* LIBFFI_ASM */
71
+
72
+ /* ---- Definitions for closures ----------------------------------------- */
73
+
74
+ #define FFI_CLOSURES 1
75
+ #define FFI_GO_CLOSURES 1
76
+ #define FFI_TRAMPOLINE_SIZE 24
77
+ #define FFI_NATIVE_RAW_API 0
78
+ #define FFI_EXTRA_CIF_FIELDS \
79
+ unsigned loongarch_nfixedargs; \
80
+ unsigned loongarch_unused;
81
+ #define FFI_TARGET_SPECIFIC_VARIADIC
82
+ #endif