ffi 1.1.5 → 1.15.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (629) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +338 -0
  3. data/COPYING +49 -0
  4. data/Gemfile +14 -0
  5. data/LICENSE +21 -11
  6. data/LICENSE.SPECS +22 -0
  7. data/README.md +136 -0
  8. data/Rakefile +149 -154
  9. data/ext/ffi_c/AbstractMemory.c +133 -57
  10. data/ext/ffi_c/AbstractMemory.h +21 -12
  11. data/ext/ffi_c/ArrayType.c +27 -14
  12. data/ext/ffi_c/ArrayType.h +21 -12
  13. data/ext/ffi_c/Buffer.c +29 -25
  14. data/ext/ffi_c/Call.c +154 -125
  15. data/ext/ffi_c/Call.h +43 -20
  16. data/ext/ffi_c/ClosurePool.c +100 -42
  17. data/ext/ffi_c/ClosurePool.h +24 -13
  18. data/ext/ffi_c/DynamicLibrary.c +47 -28
  19. data/ext/ffi_c/DynamicLibrary.h +70 -12
  20. data/ext/ffi_c/Function.c +119 -167
  21. data/ext/ffi_c/Function.h +23 -19
  22. data/ext/ffi_c/FunctionInfo.c +55 -25
  23. data/ext/ffi_c/LastError.c +70 -21
  24. data/ext/ffi_c/LastError.h +21 -12
  25. data/ext/ffi_c/LongDouble.c +15 -9
  26. data/ext/ffi_c/LongDouble.h +21 -16
  27. data/ext/ffi_c/MappedType.c +22 -15
  28. data/ext/ffi_c/MappedType.h +21 -12
  29. data/ext/ffi_c/MemoryPointer.c +58 -33
  30. data/ext/ffi_c/MemoryPointer.h +22 -19
  31. data/ext/ffi_c/MethodHandle.c +49 -50
  32. data/ext/ffi_c/MethodHandle.h +24 -14
  33. data/ext/ffi_c/Platform.c +28 -62
  34. data/ext/ffi_c/Platform.h +21 -12
  35. data/ext/ffi_c/Pointer.c +63 -46
  36. data/ext/ffi_c/Pointer.h +22 -19
  37. data/ext/ffi_c/Struct.c +198 -80
  38. data/ext/ffi_c/Struct.h +33 -18
  39. data/ext/ffi_c/StructByValue.c +23 -20
  40. data/ext/ffi_c/StructByValue.h +21 -12
  41. data/ext/ffi_c/StructLayout.c +184 -39
  42. data/ext/ffi_c/Thread.c +73 -270
  43. data/ext/ffi_c/Thread.h +32 -35
  44. data/ext/ffi_c/Type.c +26 -32
  45. data/ext/ffi_c/Type.h +24 -10
  46. data/ext/ffi_c/Types.c +28 -20
  47. data/ext/ffi_c/Types.h +25 -16
  48. data/ext/ffi_c/Variadic.c +78 -39
  49. data/ext/ffi_c/compat.h +25 -17
  50. data/ext/ffi_c/extconf.rb +68 -31
  51. data/ext/ffi_c/ffi.c +27 -20
  52. data/ext/ffi_c/libffi/.appveyor.yml +66 -0
  53. data/ext/ffi_c/libffi/.gitattributes +4 -0
  54. data/ext/ffi_c/libffi/.github/issue_template.md +10 -0
  55. data/ext/ffi_c/libffi/.gitignore +38 -0
  56. data/ext/ffi_c/libffi/.travis/ar-lib +270 -0
  57. data/ext/ffi_c/libffi/.travis/bfin-sim.exp +58 -0
  58. data/ext/ffi_c/libffi/.travis/build-cross-in-container.sh +14 -0
  59. data/ext/ffi_c/libffi/.travis/build-in-container.sh +12 -0
  60. data/ext/ffi_c/libffi/.travis/build.sh +142 -0
  61. data/ext/ffi_c/libffi/.travis/compile +351 -0
  62. data/ext/ffi_c/libffi/.travis/install.sh +71 -0
  63. data/ext/ffi_c/libffi/.travis/m32r-sim.exp +58 -0
  64. data/ext/ffi_c/libffi/.travis/moxie-sim.exp +60 -0
  65. data/ext/ffi_c/libffi/.travis/or1k-sim.exp +58 -0
  66. data/ext/ffi_c/libffi/.travis/powerpc-eabisim.exp +58 -0
  67. data/ext/ffi_c/libffi/.travis/site.exp +27 -0
  68. data/ext/ffi_c/libffi/.travis/wine-sim.exp +55 -0
  69. data/ext/ffi_c/libffi/.travis.yml +83 -0
  70. data/ext/ffi_c/libffi/{ChangeLog → ChangeLog.old} +6366 -3559
  71. data/ext/ffi_c/libffi/LICENSE +1 -1
  72. data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +353 -0
  73. data/ext/ffi_c/libffi/Makefile.am +123 -169
  74. data/ext/ffi_c/libffi/Makefile.in +1243 -1003
  75. data/ext/ffi_c/libffi/README.md +486 -0
  76. data/ext/ffi_c/libffi/acinclude.m4 +387 -0
  77. data/ext/ffi_c/libffi/autogen.sh +2 -0
  78. data/ext/ffi_c/libffi/config.guess +690 -504
  79. data/ext/ffi_c/libffi/config.sub +1353 -1207
  80. data/ext/ffi_c/libffi/configure +7308 -2449
  81. data/ext/ffi_c/libffi/configure.ac +178 -259
  82. data/ext/ffi_c/libffi/configure.host +311 -4
  83. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  84. data/ext/ffi_c/libffi/doc/Makefile.in +815 -0
  85. data/ext/ffi_c/libffi/doc/libffi.texi +455 -58
  86. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  87. data/ext/ffi_c/libffi/fficonfig.h.in +37 -13
  88. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +201 -0
  89. data/ext/ffi_c/libffi/include/Makefile.am +3 -3
  90. data/ext/ffi_c/libffi/include/Makefile.in +196 -75
  91. data/ext/ffi_c/libffi/include/ffi.h.in +163 -67
  92. data/ext/ffi_c/libffi/include/ffi_cfi.h +55 -0
  93. data/ext/ffi_c/libffi/include/ffi_common.h +39 -12
  94. data/ext/ffi_c/libffi/install-sh +207 -209
  95. data/ext/ffi_c/libffi/libffi.map.in +76 -0
  96. data/ext/ffi_c/libffi/libffi.pc.in +3 -2
  97. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +997 -0
  98. data/ext/ffi_c/libffi/libtool-ldflags +106 -0
  99. data/ext/ffi_c/libffi/libtool-version +1 -1
  100. data/ext/ffi_c/libffi/ltmain.sh +3641 -2026
  101. data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
  102. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +50 -0
  103. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +32 -14
  104. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +33 -106
  105. data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +53 -0
  106. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +38 -13
  107. data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +8 -29
  108. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +11 -9
  109. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +104 -52
  110. data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +18 -8
  111. data/ext/ffi_c/libffi/m4/ax_require_defined.m4 +37 -0
  112. data/ext/ffi_c/libffi/make_sunver.pl +333 -0
  113. data/ext/ffi_c/libffi/man/Makefile.am +2 -2
  114. data/ext/ffi_c/libffi/man/Makefile.in +151 -55
  115. data/ext/ffi_c/libffi/man/ffi.3 +10 -0
  116. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +6 -4
  117. data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +73 -0
  118. data/ext/ffi_c/libffi/missing +153 -314
  119. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.sln +33 -0
  120. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj +130 -0
  121. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters +57 -0
  122. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.user +4 -0
  123. data/ext/ffi_c/libffi/{include/ffi.h.vc64 → msvc_build/aarch64/aarch64_include/ffi.h} +151 -67
  124. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/fficonfig.h +219 -0
  125. data/ext/ffi_c/libffi/msvcc.sh +176 -20
  126. data/ext/ffi_c/libffi/src/aarch64/ffi.c +1025 -0
  127. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +97 -0
  128. data/ext/ffi_c/libffi/src/aarch64/internal.h +68 -0
  129. data/ext/ffi_c/libffi/src/aarch64/sysv.S +451 -0
  130. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +506 -0
  131. data/ext/ffi_c/libffi/src/alpha/ffi.c +335 -98
  132. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +10 -1
  133. data/ext/ffi_c/libffi/src/alpha/internal.h +23 -0
  134. data/ext/ffi_c/libffi/src/alpha/osf.S +161 -266
  135. data/ext/ffi_c/libffi/src/arc/arcompact.S +135 -0
  136. data/ext/ffi_c/libffi/src/arc/ffi.c +266 -0
  137. data/ext/ffi_c/libffi/src/arc/ffitarget.h +53 -0
  138. data/ext/ffi_c/libffi/src/arm/ffi.c +663 -515
  139. data/ext/ffi_c/libffi/src/arm/ffitarget.h +32 -8
  140. data/ext/ffi_c/libffi/src/arm/internal.h +7 -0
  141. data/ext/ffi_c/libffi/src/arm/sysv.S +305 -417
  142. data/ext/ffi_c/libffi/src/arm/sysv_msvc_arm32.S +311 -0
  143. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +6 -1
  144. data/ext/ffi_c/libffi/src/bfin/ffi.c +196 -0
  145. data/ext/ffi_c/libffi/src/bfin/ffitarget.h +43 -0
  146. data/ext/ffi_c/libffi/src/bfin/sysv.S +179 -0
  147. data/ext/ffi_c/libffi/src/closures.c +465 -59
  148. data/ext/ffi_c/libffi/src/cris/ffi.c +10 -7
  149. data/ext/ffi_c/libffi/src/cris/ffitarget.h +6 -1
  150. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  151. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  152. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  153. data/ext/ffi_c/libffi/src/debug.c +6 -1
  154. data/ext/ffi_c/libffi/src/dlmalloc.c +17 -12
  155. data/ext/ffi_c/libffi/src/frv/ffi.c +2 -2
  156. data/ext/ffi_c/libffi/src/frv/ffitarget.h +6 -1
  157. data/ext/ffi_c/libffi/src/ia64/ffi.c +35 -13
  158. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +8 -2
  159. data/ext/ffi_c/libffi/src/ia64/unix.S +8 -1
  160. data/ext/ffi_c/libffi/src/java_raw_api.c +23 -5
  161. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  162. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  163. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  164. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  165. data/ext/ffi_c/libffi/src/m32r/ffi.c +1 -1
  166. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +6 -1
  167. data/ext/ffi_c/libffi/src/m68k/ffi.c +87 -13
  168. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +6 -1
  169. data/ext/ffi_c/libffi/src/m68k/sysv.S +119 -32
  170. data/ext/ffi_c/libffi/src/m88k/ffi.c +400 -0
  171. data/ext/ffi_c/libffi/src/m88k/ffitarget.h +49 -0
  172. data/ext/ffi_c/libffi/src/m88k/obsd.S +209 -0
  173. data/ext/ffi_c/libffi/src/metag/ffi.c +330 -0
  174. data/ext/ffi_c/libffi/{fficonfig.hw → src/metag/ffitarget.h} +22 -26
  175. data/ext/ffi_c/libffi/src/metag/sysv.S +311 -0
  176. data/ext/ffi_c/libffi/src/microblaze/ffi.c +321 -0
  177. data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +53 -0
  178. data/ext/ffi_c/libffi/src/microblaze/sysv.S +302 -0
  179. data/ext/ffi_c/libffi/src/mips/ffi.c +135 -37
  180. data/ext/ffi_c/libffi/src/mips/ffitarget.h +16 -14
  181. data/ext/ffi_c/libffi/src/mips/n32.S +128 -56
  182. data/ext/ffi_c/libffi/src/mips/o32.S +150 -27
  183. data/ext/ffi_c/libffi/src/moxie/eabi.S +55 -82
  184. data/ext/ffi_c/libffi/src/moxie/ffi.c +55 -46
  185. data/ext/ffi_c/libffi/src/moxie/ffitarget.h +52 -0
  186. data/ext/ffi_c/libffi/src/nios2/ffi.c +304 -0
  187. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +52 -0
  188. data/ext/ffi_c/libffi/src/nios2/sysv.S +136 -0
  189. data/ext/ffi_c/libffi/src/or1k/ffi.c +328 -0
  190. data/ext/ffi_c/libffi/src/or1k/ffitarget.h +58 -0
  191. data/ext/ffi_c/libffi/src/or1k/sysv.S +107 -0
  192. data/ext/ffi_c/libffi/src/pa/ffi.c +46 -91
  193. data/ext/ffi_c/libffi/src/pa/ffitarget.h +9 -7
  194. data/ext/ffi_c/libffi/src/pa/hpux32.S +4 -2
  195. data/ext/ffi_c/libffi/src/pa/linux.S +27 -4
  196. data/ext/ffi_c/libffi/src/powerpc/aix.S +245 -7
  197. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +253 -4
  198. data/ext/ffi_c/libffi/src/powerpc/asm.h +2 -2
  199. data/ext/ffi_c/libffi/src/powerpc/darwin.S +2 -7
  200. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +22 -26
  201. data/ext/ffi_c/libffi/src/powerpc/ffi.c +105 -1378
  202. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +123 -30
  203. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +1153 -0
  204. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +105 -0
  205. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
  206. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +110 -45
  207. data/ext/ffi_c/libffi/src/powerpc/linux64.S +189 -85
  208. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +436 -108
  209. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +138 -68
  210. data/ext/ffi_c/libffi/src/powerpc/sysv.S +73 -119
  211. data/ext/ffi_c/libffi/src/prep_cif.c +111 -25
  212. data/ext/ffi_c/libffi/src/raw_api.c +18 -5
  213. data/ext/ffi_c/libffi/src/riscv/ffi.c +481 -0
  214. data/ext/ffi_c/libffi/src/riscv/ffitarget.h +69 -0
  215. data/ext/ffi_c/libffi/src/riscv/sysv.S +293 -0
  216. data/ext/ffi_c/libffi/src/s390/ffi.c +294 -318
  217. data/ext/ffi_c/libffi/src/s390/ffitarget.h +9 -1
  218. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  219. data/ext/ffi_c/libffi/src/s390/sysv.S +257 -366
  220. data/ext/ffi_c/libffi/src/sh/ffi.c +4 -3
  221. data/ext/ffi_c/libffi/src/sh/ffitarget.h +6 -1
  222. data/ext/ffi_c/libffi/src/sh64/ffi.c +3 -2
  223. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +6 -1
  224. data/ext/ffi_c/libffi/src/sparc/ffi.c +326 -527
  225. data/ext/ffi_c/libffi/src/sparc/ffi64.c +608 -0
  226. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +20 -7
  227. data/ext/ffi_c/libffi/src/sparc/internal.h +26 -0
  228. data/ext/ffi_c/libffi/src/sparc/v8.S +364 -234
  229. data/ext/ffi_c/libffi/src/sparc/v9.S +340 -207
  230. data/ext/ffi_c/libffi/src/tile/ffi.c +355 -0
  231. data/ext/ffi_c/libffi/src/tile/ffitarget.h +65 -0
  232. data/ext/ffi_c/libffi/src/tile/tile.S +360 -0
  233. data/ext/ffi_c/libffi/src/types.c +46 -15
  234. data/ext/ffi_c/libffi/src/vax/elfbsd.S +195 -0
  235. data/ext/ffi_c/libffi/src/vax/ffi.c +276 -0
  236. data/ext/ffi_c/libffi/src/vax/ffitarget.h +49 -0
  237. data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
  238. data/ext/ffi_c/libffi/src/x86/ffi.c +624 -498
  239. data/ext/ffi_c/libffi/src/x86/ffi64.c +379 -119
  240. data/ext/ffi_c/libffi/src/x86/ffitarget.h +74 -35
  241. data/ext/ffi_c/libffi/src/x86/ffiw64.c +318 -0
  242. data/ext/ffi_c/libffi/src/x86/internal.h +29 -0
  243. data/ext/ffi_c/libffi/src/x86/internal64.h +22 -0
  244. data/ext/ffi_c/libffi/src/x86/sysv.S +1070 -400
  245. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +995 -0
  246. data/ext/ffi_c/libffi/src/x86/unix64.S +494 -299
  247. data/ext/ffi_c/libffi/src/x86/win64.S +231 -458
  248. data/ext/ffi_c/libffi/src/x86/win64_intel.S +238 -0
  249. data/ext/ffi_c/libffi/src/xtensa/ffi.c +298 -0
  250. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +53 -0
  251. data/ext/ffi_c/libffi/src/xtensa/sysv.S +258 -0
  252. data/ext/ffi_c/libffi/stamp-h.in +1 -0
  253. data/ext/ffi_c/libffi/testsuite/Makefile.am +115 -73
  254. data/ext/ffi_c/libffi/testsuite/Makefile.in +262 -114
  255. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +334 -24
  256. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +21 -1
  257. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/Makefile +28 -0
  258. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/README +78 -0
  259. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/alignof.h +50 -0
  260. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +63 -0
  261. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +1745 -0
  262. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2885 -0
  263. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +743 -0
  264. data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
  265. data/ext/ffi_c/libffi/testsuite/libffi.call/align_stdcall.c +46 -0
  266. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +28 -6
  267. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +2 -2
  268. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +25 -40
  269. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +3 -1
  270. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +15 -12
  271. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +4 -2
  272. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +107 -0
  273. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +6 -16
  274. data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +57 -0
  275. data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +70 -0
  276. data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +78 -0
  277. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +0 -1
  278. data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +46 -0
  279. data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +127 -0
  280. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +1 -0
  281. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
  282. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +1 -1
  283. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +1 -1
  284. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +2 -2
  285. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +49 -0
  286. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +49 -0
  287. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +55 -0
  288. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +9 -7
  289. data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +57 -0
  290. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +7 -7
  291. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +7 -6
  292. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +9 -8
  293. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +9 -8
  294. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +9 -9
  295. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +9 -9
  296. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +9 -8
  297. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +9 -8
  298. data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
  299. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +196 -0
  300. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +121 -0
  301. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +123 -0
  302. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +125 -0
  303. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure.exp +67 -0
  304. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn0.c +0 -0
  305. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn1.c +0 -0
  306. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn2.c +0 -0
  307. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn3.c +0 -0
  308. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn4.c +0 -0
  309. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn5.c +0 -0
  310. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn6.c +0 -0
  311. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_loc_fn0.c +0 -0
  312. data/ext/ffi_c/libffi/testsuite/{libffi.call/closure_stdcall.c → libffi.closures/closure_simple.c} +7 -16
  313. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_12byte.c +4 -4
  314. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_16byte.c +4 -4
  315. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_18byte.c +4 -4
  316. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_19byte.c +4 -4
  317. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_1_1byte.c +4 -4
  318. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_20byte.c +4 -4
  319. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_20byte1.c +4 -4
  320. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_24byte.c +5 -5
  321. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_2byte.c +4 -4
  322. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3_1byte.c +4 -4
  323. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3byte1.c +4 -4
  324. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3byte2.c +4 -4
  325. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3float.c +95 -0
  326. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_4_1byte.c +4 -4
  327. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_4byte.c +4 -4
  328. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_5_1_byte.c +4 -4
  329. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_5byte.c +4 -4
  330. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_64byte.c +5 -5
  331. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_6_1_byte.c +4 -4
  332. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_6byte.c +4 -4
  333. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_7_1_byte.c +4 -4
  334. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_7byte.c +4 -4
  335. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_8byte.c +4 -4
  336. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_9byte1.c +4 -4
  337. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_9byte2.c +4 -4
  338. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_double.c +4 -4
  339. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_float.c +4 -4
  340. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble.c +4 -4
  341. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble_split.c +4 -6
  342. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble_split2.c +4 -6
  343. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_pointer.c +4 -4
  344. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint16.c +4 -4
  345. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint32.c +4 -4
  346. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint64.c +4 -4
  347. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint16.c +4 -4
  348. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint32.c +4 -4
  349. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint64.c +4 -4
  350. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_dbls_struct.c +4 -4
  351. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_double.c +0 -0
  352. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_double_va.c +10 -9
  353. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_float.c +0 -0
  354. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_longdouble.c +3 -3
  355. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_longdouble_va.c +10 -9
  356. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_args.c +70 -0
  357. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_float_double.c +55 -0
  358. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_schar.c +0 -0
  359. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_sshort.c +0 -0
  360. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_sshortchar.c +0 -0
  361. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_uchar.c +0 -0
  362. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_ushort.c +0 -0
  363. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_ushortchar.c +0 -0
  364. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_pointer.c +1 -1
  365. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_pointer_stack.c +11 -9
  366. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_schar.c +0 -0
  367. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_sint.c +0 -0
  368. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_sshort.c +0 -0
  369. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_struct_va1.c +114 -0
  370. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uchar.c +0 -0
  371. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uchar_va.c +44 -0
  372. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uint.c +0 -0
  373. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint_va.c +45 -0
  374. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulong_va.c +45 -0
  375. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ulonglong.c +5 -5
  376. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ushort.c +0 -0
  377. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ushort_va.c +44 -0
  378. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/err_bad_abi.c +0 -0
  379. data/ext/ffi_c/libffi/testsuite/libffi.closures/ffitest.h +138 -0
  380. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/huge_struct.c +20 -19
  381. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct.c +6 -6
  382. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct1.c +8 -8
  383. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct10.c +7 -6
  384. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct11.c +121 -0
  385. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct2.c +5 -5
  386. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct3.c +5 -5
  387. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct4.c +5 -5
  388. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct5.c +5 -5
  389. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct6.c +6 -6
  390. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct7.c +5 -5
  391. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct8.c +6 -6
  392. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct9.c +6 -6
  393. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/problem1.c +0 -0
  394. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_large.c +7 -7
  395. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_large2.c +7 -7
  396. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_medium.c +5 -5
  397. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_medium2.c +5 -5
  398. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/testclosure.c +2 -2
  399. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.closures}/unwindtest.cc +3 -10
  400. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.closures}/unwindtest_ffi_call.cc +3 -2
  401. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +91 -0
  402. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +10 -0
  403. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +10 -0
  404. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +10 -0
  405. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +42 -0
  406. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +10 -0
  407. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +10 -0
  408. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +10 -0
  409. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +71 -0
  410. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +10 -0
  411. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +10 -0
  412. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +10 -0
  413. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +80 -0
  414. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +10 -0
  415. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +16 -0
  416. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +10 -0
  417. data/ext/ffi_c/libffi/testsuite/{libffi.special/special.exp → libffi.complex/complex.exp} +9 -8
  418. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +51 -0
  419. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +7 -0
  420. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +7 -0
  421. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +7 -0
  422. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +10 -0
  423. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +10 -0
  424. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +86 -0
  425. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +10 -0
  426. data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +1 -0
  427. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +78 -0
  428. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +10 -0
  429. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +10 -0
  430. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +10 -0
  431. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +37 -0
  432. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +41 -0
  433. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +10 -0
  434. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +10 -0
  435. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +10 -0
  436. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +44 -0
  437. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +10 -0
  438. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +10 -0
  439. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +10 -0
  440. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +10 -0
  441. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +10 -0
  442. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +10 -0
  443. data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +34 -0
  444. data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +28 -0
  445. data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +1 -0
  446. data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +36 -0
  447. data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +19 -0
  448. data/ext/ffi_c/libffi.bsd.mk +12 -6
  449. data/ext/ffi_c/libffi.darwin.mk +21 -9
  450. data/ext/ffi_c/libffi.gnu.mk +3 -2
  451. data/ext/ffi_c/libffi.mk +11 -6
  452. data/ext/ffi_c/libffi.vc.mk +1 -1
  453. data/ext/ffi_c/libffi.vc64.mk +1 -1
  454. data/ext/ffi_c/rbffi.h +22 -14
  455. data/ext/ffi_c/rbffi_endian.h +11 -2
  456. data/ffi.gemspec +42 -0
  457. data/lib/ffi/abstract_memory.rb +44 -0
  458. data/lib/ffi/autopointer.rb +70 -50
  459. data/lib/ffi/data_converter.rb +67 -0
  460. data/lib/ffi/enum.rb +159 -24
  461. data/lib/ffi/errno.rb +21 -11
  462. data/lib/ffi/ffi.rb +25 -11
  463. data/lib/ffi/io.rb +24 -14
  464. data/lib/ffi/library.rb +174 -67
  465. data/lib/ffi/managedstruct.rb +63 -34
  466. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  467. data/lib/ffi/platform/aarch64-freebsd/types.conf +128 -0
  468. data/lib/ffi/platform/aarch64-freebsd12/types.conf +181 -0
  469. data/lib/ffi/platform/aarch64-linux/types.conf +104 -0
  470. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  471. data/lib/ffi/platform/arm-freebsd/types.conf +152 -0
  472. data/lib/ffi/platform/arm-freebsd12/types.conf +152 -0
  473. data/lib/ffi/platform/arm-linux/types.conf +110 -82
  474. data/lib/ffi/platform/i386-cygwin/types.conf +3 -0
  475. data/lib/ffi/platform/i386-darwin/types.conf +63 -63
  476. data/lib/ffi/platform/i386-freebsd/types.conf +89 -89
  477. data/lib/ffi/platform/i386-freebsd12/types.conf +152 -0
  478. data/lib/ffi/platform/{i486-gnu → i386-gnu}/types.conf +84 -84
  479. data/lib/ffi/platform/i386-linux/types.conf +77 -77
  480. data/lib/ffi/platform/i386-netbsd/types.conf +87 -87
  481. data/lib/ffi/platform/i386-openbsd/types.conf +89 -87
  482. data/lib/ffi/platform/i386-solaris/types.conf +96 -96
  483. data/lib/ffi/platform/i386-windows/types.conf +43 -96
  484. data/lib/ffi/platform/ia64-linux/types.conf +79 -79
  485. data/lib/ffi/platform/mips-linux/types.conf +79 -79
  486. data/lib/ffi/platform/mips64-linux/types.conf +104 -0
  487. data/lib/ffi/platform/mips64el-linux/types.conf +104 -0
  488. data/lib/ffi/platform/mipsel-linux/types.conf +79 -79
  489. data/lib/ffi/platform/mipsisa32r6-linux/types.conf +102 -0
  490. data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +102 -0
  491. data/lib/ffi/platform/mipsisa64r6-linux/types.conf +104 -0
  492. data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +104 -0
  493. data/lib/ffi/platform/powerpc-aix/types.conf +155 -155
  494. data/lib/ffi/platform/powerpc-darwin/types.conf +63 -63
  495. data/lib/ffi/platform/powerpc-linux/types.conf +108 -78
  496. data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
  497. data/lib/ffi/platform/powerpc64-linux/types.conf +104 -0
  498. data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
  499. data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
  500. data/lib/ffi/platform/s390-linux/types.conf +79 -79
  501. data/lib/ffi/platform/s390x-linux/types.conf +79 -79
  502. data/lib/ffi/platform/sparc-linux/types.conf +79 -79
  503. data/lib/ffi/platform/sparc-solaris/types.conf +103 -103
  504. data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
  505. data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
  506. data/lib/ffi/platform/sparcv9-solaris/types.conf +103 -103
  507. data/lib/ffi/platform/x86_64-cygwin/types.conf +3 -0
  508. data/lib/ffi/platform/x86_64-darwin/types.conf +93 -63
  509. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +130 -0
  510. data/lib/ffi/platform/x86_64-freebsd/types.conf +90 -88
  511. data/lib/ffi/platform/x86_64-freebsd12/types.conf +158 -0
  512. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  513. data/lib/ffi/platform/x86_64-linux/types.conf +107 -77
  514. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  515. data/lib/ffi/platform/x86_64-netbsd/types.conf +89 -87
  516. data/lib/ffi/platform/x86_64-openbsd/types.conf +100 -92
  517. data/lib/ffi/platform/x86_64-solaris/types.conf +96 -96
  518. data/lib/ffi/platform/x86_64-windows/types.conf +52 -0
  519. data/lib/ffi/platform.rb +81 -26
  520. data/lib/ffi/pointer.rb +72 -27
  521. data/lib/ffi/struct.rb +99 -66
  522. data/lib/ffi/struct_by_reference.rb +72 -0
  523. data/lib/ffi/struct_layout.rb +96 -0
  524. data/lib/ffi/struct_layout_builder.rb +82 -17
  525. data/lib/ffi/tools/const_generator.rb +11 -8
  526. data/lib/ffi/tools/generator.rb +48 -1
  527. data/lib/ffi/tools/generator_task.rb +13 -16
  528. data/lib/ffi/tools/struct_generator.rb +6 -5
  529. data/lib/ffi/tools/types_generator.rb +14 -10
  530. data/lib/ffi/types.rb +31 -14
  531. data/lib/ffi/union.rb +23 -12
  532. data/lib/ffi/variadic.rb +25 -21
  533. data/lib/ffi/version.rb +3 -0
  534. data/lib/ffi.rb +20 -8
  535. data/rakelib/ffi_gem_helper.rb +65 -0
  536. data/samples/getlogin.rb +8 -0
  537. data/samples/getpid.rb +8 -0
  538. data/samples/gettimeofday.rb +18 -0
  539. data/samples/hello.rb +8 -0
  540. data/samples/inotify.rb +60 -0
  541. data/samples/pty.rb +75 -0
  542. data/samples/qsort.rb +20 -0
  543. metadata +413 -263
  544. data/History.txt +0 -1
  545. data/README.rdoc +0 -102
  546. data/ext/ffi_c/DataConverter.c +0 -91
  547. data/ext/ffi_c/Ffi_c.iml +0 -12
  548. data/ext/ffi_c/StructByReference.c +0 -158
  549. data/ext/ffi_c/StructByReference.h +0 -50
  550. data/ext/ffi_c/libffi/ChangeLog.libffi +0 -584
  551. data/ext/ffi_c/libffi/ChangeLog.libgcj +0 -40
  552. data/ext/ffi_c/libffi/ChangeLog.v1 +0 -764
  553. data/ext/ffi_c/libffi/Makefile.vc +0 -141
  554. data/ext/ffi_c/libffi/Makefile.vc64 +0 -141
  555. data/ext/ffi_c/libffi/README +0 -342
  556. data/ext/ffi_c/libffi/aclocal.m4 +0 -1873
  557. data/ext/ffi_c/libffi/build-ios.sh +0 -67
  558. data/ext/ffi_c/libffi/compile +0 -143
  559. data/ext/ffi_c/libffi/depcomp +0 -630
  560. data/ext/ffi_c/libffi/doc/libffi.info +0 -593
  561. data/ext/ffi_c/libffi/doc/stamp-vti +0 -4
  562. data/ext/ffi_c/libffi/include/ffi.h.vc +0 -427
  563. data/ext/ffi_c/libffi/m4/ax_check_compiler_flags.m4 +0 -76
  564. data/ext/ffi_c/libffi/m4/libtool.m4 +0 -7831
  565. data/ext/ffi_c/libffi/m4/ltoptions.m4 +0 -369
  566. data/ext/ffi_c/libffi/m4/ltsugar.m4 +0 -123
  567. data/ext/ffi_c/libffi/m4/ltversion.m4 +0 -23
  568. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +0 -98
  569. data/ext/ffi_c/libffi/mdate-sh +0 -201
  570. data/ext/ffi_c/libffi/src/arm/gentramp.sh +0 -118
  571. data/ext/ffi_c/libffi/src/arm/trampoline.S +0 -4450
  572. data/ext/ffi_c/libffi/src/x86/darwin.S +0 -444
  573. data/ext/ffi_c/libffi/src/x86/darwin64.S +0 -416
  574. data/ext/ffi_c/libffi/src/x86/freebsd.S +0 -458
  575. data/ext/ffi_c/libffi/src/x86/win32.S +0 -1065
  576. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +0 -300
  577. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +0 -63
  578. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +0 -44
  579. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +0 -96
  580. data/ext/ffi_c/libffi/texinfo.tex +0 -7210
  581. data/ext/ffi_c/win32/stdint.h +0 -199
  582. data/gen/Rakefile +0 -30
  583. data/gen/log +0 -1
  584. data/lib/Lib.iml +0 -13
  585. data/spec/ffi/Ffi.iml +0 -12
  586. data/spec/ffi/async_callback_spec.rb +0 -46
  587. data/spec/ffi/bool_spec.rb +0 -40
  588. data/spec/ffi/buffer_spec.rb +0 -215
  589. data/spec/ffi/callback_spec.rb +0 -668
  590. data/spec/ffi/custom_param_type.rb +0 -47
  591. data/spec/ffi/custom_type_spec.rb +0 -85
  592. data/spec/ffi/dup_spec.rb +0 -65
  593. data/spec/ffi/enum_spec.rb +0 -227
  594. data/spec/ffi/errno_spec.rb +0 -29
  595. data/spec/ffi/ffi_spec.rb +0 -40
  596. data/spec/ffi/function_spec.rb +0 -87
  597. data/spec/ffi/library_spec.rb +0 -208
  598. data/spec/ffi/long_double.rb +0 -41
  599. data/spec/ffi/managed_struct_spec.rb +0 -72
  600. data/spec/ffi/number_spec.rb +0 -247
  601. data/spec/ffi/pointer_spec.rb +0 -214
  602. data/spec/ffi/rbx/attach_function_spec.rb +0 -28
  603. data/spec/ffi/rbx/memory_pointer_spec.rb +0 -115
  604. data/spec/ffi/rbx/spec_helper.rb +0 -1
  605. data/spec/ffi/rbx/struct_spec.rb +0 -13
  606. data/spec/ffi/spec_helper.rb +0 -35
  607. data/spec/ffi/string_spec.rb +0 -119
  608. data/spec/ffi/strptr_spec.rb +0 -61
  609. data/spec/ffi/struct_callback_spec.rb +0 -80
  610. data/spec/ffi/struct_initialize_spec.rb +0 -46
  611. data/spec/ffi/struct_packed_spec.rb +0 -62
  612. data/spec/ffi/struct_spec.rb +0 -719
  613. data/spec/ffi/typedef_spec.rb +0 -89
  614. data/spec/ffi/union_spec.rb +0 -76
  615. data/spec/ffi/variadic_spec.rb +0 -103
  616. data/spec/spec.opts +0 -4
  617. data/tasks/ann.rake +0 -80
  618. data/tasks/extension.rake +0 -32
  619. data/tasks/gem.rake +0 -199
  620. data/tasks/git.rake +0 -41
  621. data/tasks/notes.rake +0 -27
  622. data/tasks/post_load.rake +0 -34
  623. data/tasks/rdoc.rake +0 -50
  624. data/tasks/rubyforge.rake +0 -55
  625. data/tasks/setup.rb +0 -301
  626. data/tasks/spec.rake +0 -54
  627. data/tasks/svn.rake +0 -47
  628. data/tasks/test.rake +0 -40
  629. data/tasks/yard.rake +0 -11
@@ -1,5 +1,6 @@
1
1
  /* -----------------------------------------------------------------------
2
- ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
2
+ ffi.c - Copyright (c) 2017 Anthony Green
3
+ Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
3
4
  Copyright (c) 2002 Ranjit Mathew
4
5
  Copyright (c) 2002 Bo Thorsen
5
6
  Copyright (c) 2002 Roger Sayle
@@ -28,478 +29,504 @@
28
29
  DEALINGS IN THE SOFTWARE.
29
30
  ----------------------------------------------------------------------- */
30
31
 
31
- #if !defined(__x86_64__) || defined(_WIN64)
32
-
33
- #ifdef _WIN64
34
- #include <windows.h>
35
- #endif
36
-
32
+ #if defined(__i386__) || defined(_M_IX86)
37
33
  #include <ffi.h>
38
34
  #include <ffi_common.h>
39
-
35
+ #include <stdint.h>
40
36
  #include <stdlib.h>
41
-
42
- /* ffi_prep_args is called by the assembly routine once stack space
43
- has been allocated for the function's arguments */
44
-
45
- void ffi_prep_args(char *stack, extended_cif *ecif)
46
- {
47
- register unsigned int i;
48
- register void **p_argv;
49
- register char *argp;
50
- register ffi_type **p_arg;
51
-
52
- argp = stack;
53
-
54
- if (ecif->cif->flags == FFI_TYPE_STRUCT
55
- #ifdef X86_WIN64
56
- && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
57
- && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
37
+ #include "internal.h"
38
+
39
+ /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
40
+ all further uses in this file will refer to the 80-bit type. */
41
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
42
+ # if FFI_TYPE_LONGDOUBLE != 4
43
+ # error FFI_TYPE_LONGDOUBLE out of date
44
+ # endif
45
+ #else
46
+ # undef FFI_TYPE_LONGDOUBLE
47
+ # define FFI_TYPE_LONGDOUBLE 4
58
48
  #endif
59
- )
60
- {
61
- *(void **) argp = ecif->rvalue;
62
- argp += sizeof(void*);
63
- }
64
-
65
- p_argv = ecif->avalue;
66
49
 
67
- for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
68
- i != 0;
69
- i--, p_arg++)
70
- {
71
- size_t z;
72
-
73
- /* Align if necessary */
74
- if ((sizeof(void*) - 1) & (size_t) argp)
75
- argp = (char *) ALIGN(argp, sizeof(void*));
76
-
77
- z = (*p_arg)->size;
78
- #ifdef X86_WIN64
79
- if (z > sizeof(ffi_arg)
80
- || ((*p_arg)->type == FFI_TYPE_STRUCT
81
- && (z != 1 && z != 2 && z != 4 && z != 8))
82
- #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
83
- || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
50
+ #if defined(__GNUC__) && !defined(__declspec)
51
+ # define __declspec(x) __attribute__((x))
84
52
  #endif
85
- )
86
- {
87
- z = sizeof(ffi_arg);
88
- *(void **)argp = *p_argv;
89
- }
90
- else if ((*p_arg)->type == FFI_TYPE_FLOAT)
91
- {
92
- memcpy(argp, *p_argv, z);
93
- }
94
- else
95
- #endif
96
- if (z < sizeof(ffi_arg))
97
- {
98
- z = sizeof(ffi_arg);
99
- switch ((*p_arg)->type)
100
- {
101
- case FFI_TYPE_SINT8:
102
- *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
103
- break;
104
-
105
- case FFI_TYPE_UINT8:
106
- *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
107
- break;
108
-
109
- case FFI_TYPE_SINT16:
110
- *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
111
- break;
112
-
113
- case FFI_TYPE_UINT16:
114
- *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
115
- break;
116
-
117
- case FFI_TYPE_SINT32:
118
- *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
119
- break;
120
-
121
- case FFI_TYPE_UINT32:
122
- *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
123
- break;
124
-
125
- case FFI_TYPE_STRUCT:
126
- *(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
127
- break;
128
-
129
- default:
130
- FFI_ASSERT(0);
131
- }
132
- }
133
- else
134
- {
135
- memcpy(argp, *p_argv, z);
136
- }
137
- p_argv++;
138
- #ifdef X86_WIN64
139
- argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
53
+
54
+ #if defined(_MSC_VER) && defined(_M_IX86)
55
+ /* Stack is not 16-byte aligned on Windows. */
56
+ #define STACK_ALIGN(bytes) (bytes)
140
57
  #else
141
- argp += z;
58
+ #define STACK_ALIGN(bytes) FFI_ALIGN (bytes, 16)
142
59
  #endif
143
- }
144
-
145
- return;
146
- }
147
60
 
148
- /* Perform machine dependent cif processing */
149
- ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
61
+ /* Perform machine dependent cif processing. */
62
+ ffi_status FFI_HIDDEN
63
+ ffi_prep_cif_machdep(ffi_cif *cif)
150
64
  {
151
- unsigned int i;
152
- ffi_type **ptr;
65
+ size_t bytes = 0;
66
+ int i, n, flags, cabi = cif->abi;
67
+
68
+ switch (cabi)
69
+ {
70
+ case FFI_SYSV:
71
+ case FFI_STDCALL:
72
+ case FFI_THISCALL:
73
+ case FFI_FASTCALL:
74
+ case FFI_MS_CDECL:
75
+ case FFI_PASCAL:
76
+ case FFI_REGISTER:
77
+ break;
78
+ default:
79
+ return FFI_BAD_ABI;
80
+ }
153
81
 
154
- /* Set the return type flag */
155
82
  switch (cif->rtype->type)
156
83
  {
157
84
  case FFI_TYPE_VOID:
85
+ flags = X86_RET_VOID;
86
+ break;
87
+ case FFI_TYPE_FLOAT:
88
+ flags = X86_RET_FLOAT;
89
+ break;
90
+ case FFI_TYPE_DOUBLE:
91
+ flags = X86_RET_DOUBLE;
92
+ break;
93
+ case FFI_TYPE_LONGDOUBLE:
94
+ flags = X86_RET_LDOUBLE;
95
+ break;
158
96
  case FFI_TYPE_UINT8:
97
+ flags = X86_RET_UINT8;
98
+ break;
159
99
  case FFI_TYPE_UINT16:
100
+ flags = X86_RET_UINT16;
101
+ break;
160
102
  case FFI_TYPE_SINT8:
103
+ flags = X86_RET_SINT8;
104
+ break;
161
105
  case FFI_TYPE_SINT16:
162
- #ifdef X86_WIN64
163
- case FFI_TYPE_UINT32:
106
+ flags = X86_RET_SINT16;
107
+ break;
108
+ case FFI_TYPE_INT:
164
109
  case FFI_TYPE_SINT32:
165
- #endif
166
- case FFI_TYPE_SINT64:
167
- case FFI_TYPE_FLOAT:
168
- case FFI_TYPE_DOUBLE:
169
- #ifndef X86_WIN64
170
- #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
171
- case FFI_TYPE_LONGDOUBLE:
172
- #endif
173
- #endif
174
- cif->flags = (unsigned) cif->rtype->type;
110
+ case FFI_TYPE_UINT32:
111
+ case FFI_TYPE_POINTER:
112
+ flags = X86_RET_INT32;
175
113
  break;
176
-
114
+ case FFI_TYPE_SINT64:
177
115
  case FFI_TYPE_UINT64:
178
- #ifdef X86_WIN64
179
- case FFI_TYPE_POINTER:
180
- #endif
181
- cif->flags = FFI_TYPE_SINT64;
116
+ flags = X86_RET_INT64;
182
117
  break;
183
-
184
118
  case FFI_TYPE_STRUCT:
185
119
  #ifndef X86
120
+ /* ??? This should be a different ABI rather than an ifdef. */
186
121
  if (cif->rtype->size == 1)
187
- {
188
- cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
189
- }
122
+ flags = X86_RET_STRUCT_1B;
190
123
  else if (cif->rtype->size == 2)
191
- {
192
- cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
193
- }
124
+ flags = X86_RET_STRUCT_2B;
194
125
  else if (cif->rtype->size == 4)
195
- {
196
- #ifdef X86_WIN64
197
- cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
198
- #else
199
- cif->flags = FFI_TYPE_INT; /* same as int type */
200
- #endif
201
- }
126
+ flags = X86_RET_INT32;
202
127
  else if (cif->rtype->size == 8)
203
- {
204
- cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
205
- }
128
+ flags = X86_RET_INT64;
206
129
  else
207
130
  #endif
208
- {
209
- cif->flags = FFI_TYPE_STRUCT;
210
- /* allocate space for return value pointer */
211
- cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
212
- }
131
+ {
132
+ do_struct:
133
+ switch (cabi)
134
+ {
135
+ case FFI_THISCALL:
136
+ case FFI_FASTCALL:
137
+ case FFI_STDCALL:
138
+ case FFI_MS_CDECL:
139
+ flags = X86_RET_STRUCTARG;
140
+ break;
141
+ default:
142
+ flags = X86_RET_STRUCTPOP;
143
+ break;
144
+ }
145
+ /* Allocate space for return value pointer. */
146
+ bytes += FFI_ALIGN (sizeof(void*), FFI_SIZEOF_ARG);
147
+ }
213
148
  break;
214
-
215
- default:
216
- #ifdef X86_WIN64
217
- cif->flags = FFI_TYPE_SINT64;
218
- break;
219
- case FFI_TYPE_INT:
220
- cif->flags = FFI_TYPE_SINT32;
221
- #else
222
- cif->flags = FFI_TYPE_INT;
223
- #endif
149
+ case FFI_TYPE_COMPLEX:
150
+ switch (cif->rtype->elements[0]->type)
151
+ {
152
+ case FFI_TYPE_DOUBLE:
153
+ case FFI_TYPE_LONGDOUBLE:
154
+ case FFI_TYPE_SINT64:
155
+ case FFI_TYPE_UINT64:
156
+ goto do_struct;
157
+ case FFI_TYPE_FLOAT:
158
+ case FFI_TYPE_INT:
159
+ case FFI_TYPE_SINT32:
160
+ case FFI_TYPE_UINT32:
161
+ flags = X86_RET_INT64;
162
+ break;
163
+ case FFI_TYPE_SINT16:
164
+ case FFI_TYPE_UINT16:
165
+ flags = X86_RET_INT32;
166
+ break;
167
+ case FFI_TYPE_SINT8:
168
+ case FFI_TYPE_UINT8:
169
+ flags = X86_RET_STRUCT_2B;
170
+ break;
171
+ default:
172
+ return FFI_BAD_TYPEDEF;
173
+ }
224
174
  break;
175
+ default:
176
+ return FFI_BAD_TYPEDEF;
225
177
  }
178
+ cif->flags = flags;
226
179
 
227
- for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
180
+ for (i = 0, n = cif->nargs; i < n; i++)
228
181
  {
229
- if (((*ptr)->alignment - 1) & cif->bytes)
230
- cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
231
- cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
182
+ ffi_type *t = cif->arg_types[i];
183
+
184
+ bytes = FFI_ALIGN (bytes, t->alignment);
185
+ bytes += FFI_ALIGN (t->size, FFI_SIZEOF_ARG);
232
186
  }
187
+ cif->bytes = bytes;
233
188
 
234
- #ifdef X86_WIN64
235
- /* ensure space for storing four registers */
236
- cif->bytes += 4 * sizeof(ffi_arg);
237
- #endif
189
+ return FFI_OK;
190
+ }
238
191
 
239
- #ifdef X86_DARWIN
240
- cif->bytes = (cif->bytes + 15) & ~0xF;
241
- #endif
192
+ static ffi_arg
193
+ extend_basic_type(void *arg, int type)
194
+ {
195
+ switch (type)
196
+ {
197
+ case FFI_TYPE_SINT8:
198
+ return *(SINT8 *)arg;
199
+ case FFI_TYPE_UINT8:
200
+ return *(UINT8 *)arg;
201
+ case FFI_TYPE_SINT16:
202
+ return *(SINT16 *)arg;
203
+ case FFI_TYPE_UINT16:
204
+ return *(UINT16 *)arg;
242
205
 
243
- return FFI_OK;
206
+ case FFI_TYPE_SINT32:
207
+ case FFI_TYPE_UINT32:
208
+ case FFI_TYPE_POINTER:
209
+ case FFI_TYPE_FLOAT:
210
+ return *(UINT32 *)arg;
211
+
212
+ default:
213
+ abort();
214
+ }
244
215
  }
245
216
 
246
- #ifdef X86_WIN64
247
- extern int
248
- ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
249
- unsigned, unsigned, unsigned *, void (*fn)(void));
250
- #elif defined(X86_WIN32)
251
- extern void
252
- ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
253
- unsigned, unsigned, unsigned *, void (*fn)(void));
217
+ struct call_frame
218
+ {
219
+ void *ebp; /* 0 */
220
+ void *retaddr; /* 4 */
221
+ void (*fn)(void); /* 8 */
222
+ int flags; /* 12 */
223
+ void *rvalue; /* 16 */
224
+ unsigned regs[3]; /* 20-28 */
225
+ };
226
+
227
+ struct abi_params
228
+ {
229
+ int dir; /* parameter growth direction */
230
+ int static_chain; /* the static chain register used by gcc */
231
+ int nregs; /* number of register parameters */
232
+ int regs[3];
233
+ };
234
+
235
+ static const struct abi_params abi_params[FFI_LAST_ABI] = {
236
+ [FFI_SYSV] = { 1, R_ECX, 0 },
237
+ [FFI_THISCALL] = { 1, R_EAX, 1, { R_ECX } },
238
+ [FFI_FASTCALL] = { 1, R_EAX, 2, { R_ECX, R_EDX } },
239
+ [FFI_STDCALL] = { 1, R_ECX, 0 },
240
+ [FFI_PASCAL] = { -1, R_ECX, 0 },
241
+ /* ??? No defined static chain; gcc does not support REGISTER. */
242
+ [FFI_REGISTER] = { -1, R_ECX, 3, { R_EAX, R_EDX, R_ECX } },
243
+ [FFI_MS_CDECL] = { 1, R_ECX, 0 }
244
+ };
245
+
246
+ #ifdef HAVE_FASTCALL
247
+ #ifdef _MSC_VER
248
+ #define FFI_DECLARE_FASTCALL __fastcall
249
+ #else
250
+ #define FFI_DECLARE_FASTCALL __declspec(fastcall)
251
+ #endif
254
252
  #else
255
- extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
256
- unsigned, unsigned, unsigned *, void (*fn)(void));
253
+ #define FFI_DECLARE_FASTCALL
257
254
  #endif
258
255
 
259
- void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
256
+ extern void FFI_DECLARE_FASTCALL ffi_call_i386(struct call_frame *, char *) FFI_HIDDEN;
257
+
258
+ static void
259
+ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
260
+ void **avalue, void *closure)
260
261
  {
261
- extended_cif ecif;
262
-
263
- ecif.cif = cif;
264
- ecif.avalue = avalue;
265
-
266
- /* If the return value is a struct and we don't have a return */
267
- /* value address then we need to make one */
268
-
269
- #ifdef X86_WIN64
270
- if (rvalue == NULL
271
- && cif->flags == FFI_TYPE_STRUCT
272
- && cif->rtype->size != 1 && cif->rtype->size != 2
273
- && cif->rtype->size != 4 && cif->rtype->size != 8)
274
- {
275
- ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
276
- }
277
- #else
278
- if (rvalue == NULL
279
- && cif->flags == FFI_TYPE_STRUCT)
262
+ size_t rsize, bytes;
263
+ struct call_frame *frame;
264
+ char *stack, *argp;
265
+ ffi_type **arg_types;
266
+ int flags, cabi, i, n, dir, narg_reg;
267
+ const struct abi_params *pabi;
268
+
269
+ flags = cif->flags;
270
+ cabi = cif->abi;
271
+ pabi = &abi_params[cabi];
272
+ dir = pabi->dir;
273
+
274
+ rsize = 0;
275
+ if (rvalue == NULL)
280
276
  {
281
- ecif.rvalue = alloca(cif->rtype->size);
277
+ switch (flags)
278
+ {
279
+ case X86_RET_FLOAT:
280
+ case X86_RET_DOUBLE:
281
+ case X86_RET_LDOUBLE:
282
+ case X86_RET_STRUCTPOP:
283
+ case X86_RET_STRUCTARG:
284
+ /* The float cases need to pop the 387 stack.
285
+ The struct cases need to pass a valid pointer to the callee. */
286
+ rsize = cif->rtype->size;
287
+ break;
288
+ default:
289
+ /* We can pretend that the callee returns nothing. */
290
+ flags = X86_RET_VOID;
291
+ break;
292
+ }
282
293
  }
283
- #endif
284
- else
285
- ecif.rvalue = rvalue;
286
-
287
-
288
- switch (cif->abi)
294
+
295
+ bytes = STACK_ALIGN (cif->bytes);
296
+ stack = alloca(bytes + sizeof(*frame) + rsize);
297
+ argp = (dir < 0 ? stack + bytes : stack);
298
+ frame = (struct call_frame *)(stack + bytes);
299
+ if (rsize)
300
+ rvalue = frame + 1;
301
+
302
+ frame->fn = fn;
303
+ frame->flags = flags;
304
+ frame->rvalue = rvalue;
305
+ frame->regs[pabi->static_chain] = (unsigned)closure;
306
+
307
+ narg_reg = 0;
308
+ switch (flags)
289
309
  {
290
- #ifdef X86_WIN64
291
- case FFI_WIN64:
292
- ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
293
- cif->flags, ecif.rvalue, fn);
294
- break;
295
- #elif defined(X86_WIN32)
296
- case FFI_SYSV:
297
- case FFI_STDCALL:
298
- ffi_call_win32(ffi_prep_args, &ecif, cif->bytes, cif->flags,
299
- ecif.rvalue, fn);
300
- break;
301
- #else
302
- case FFI_SYSV:
303
- ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
304
- fn);
305
- break;
306
- #endif
307
- default:
308
- FFI_ASSERT(0);
310
+ case X86_RET_STRUCTARG:
311
+ /* The pointer is passed as the first argument. */
312
+ if (pabi->nregs > 0)
313
+ {
314
+ frame->regs[pabi->regs[0]] = (unsigned)rvalue;
315
+ narg_reg = 1;
316
+ break;
317
+ }
318
+ /* fallthru */
319
+ case X86_RET_STRUCTPOP:
320
+ *(void **)argp = rvalue;
321
+ argp += sizeof(void *);
309
322
  break;
310
323
  }
311
- }
312
324
 
325
+ arg_types = cif->arg_types;
326
+ for (i = 0, n = cif->nargs; i < n; i++)
327
+ {
328
+ ffi_type *ty = arg_types[i];
329
+ void *valp = avalue[i];
330
+ size_t z = ty->size;
331
+ int t = ty->type;
313
332
 
314
- /** private members **/
315
-
316
- /* The following __attribute__((regparm(1))) decorations will have no effect
317
- on MSVC - standard cdecl convention applies. */
318
- static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
319
- void** args, ffi_cif* cif);
320
- void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
321
- __attribute__ ((regparm(1)));
322
- unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
323
- __attribute__ ((regparm(1)));
324
- void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
325
- __attribute__ ((regparm(1)));
326
- #ifdef X86_WIN32
327
- void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
328
- __attribute__ ((regparm(1)));
329
- #endif
330
- #ifdef X86_WIN64
331
- void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
332
- #endif
333
+ if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
334
+ {
335
+ ffi_arg val = extend_basic_type (valp, t);
336
+
337
+ if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
338
+ frame->regs[pabi->regs[narg_reg++]] = val;
339
+ else if (dir < 0)
340
+ {
341
+ argp -= 4;
342
+ *(ffi_arg *)argp = val;
343
+ }
344
+ else
345
+ {
346
+ *(ffi_arg *)argp = val;
347
+ argp += 4;
348
+ }
349
+ }
350
+ else
351
+ {
352
+ size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
353
+ size_t align = FFI_SIZEOF_ARG;
354
+
355
+ /* Issue 434: For thiscall and fastcall, if the paramter passed
356
+ as 64-bit integer or struct, all following integer parameters
357
+ will be passed on stack. */
358
+ if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
359
+ && (t == FFI_TYPE_SINT64
360
+ || t == FFI_TYPE_UINT64
361
+ || t == FFI_TYPE_STRUCT))
362
+ narg_reg = 2;
363
+
364
+ /* Alignment rules for arguments are quite complex. Vectors and
365
+ structures with 16 byte alignment get it. Note that long double
366
+ on Darwin does have 16 byte alignment, and does not get this
367
+ alignment if passed directly; a structure with a long double
368
+ inside, however, would get 16 byte alignment. Since libffi does
369
+ not support vectors, we need non concern ourselves with other
370
+ cases. */
371
+ if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
372
+ align = 16;
373
+
374
+ if (dir < 0)
375
+ {
376
+ /* ??? These reverse argument ABIs are probably too old
377
+ to have cared about alignment. Someone should check. */
378
+ argp -= za;
379
+ memcpy (argp, valp, z);
380
+ }
381
+ else
382
+ {
383
+ argp = (char *)FFI_ALIGN (argp, align);
384
+ memcpy (argp, valp, z);
385
+ argp += za;
386
+ }
387
+ }
388
+ }
389
+ FFI_ASSERT (dir > 0 || argp == stack);
333
390
 
334
- /* This function is jumped to by the trampoline */
335
-
336
- #ifdef X86_WIN64
337
- void * FFI_HIDDEN
338
- ffi_closure_win64_inner (ffi_closure *closure, void *args) {
339
- ffi_cif *cif;
340
- void **arg_area;
341
- void *result;
342
- void *resp = &result;
343
-
344
- cif = closure->cif;
345
- arg_area = (void**) alloca (cif->nargs * sizeof (void*));
346
-
347
- /* this call will initialize ARG_AREA, such that each
348
- * element in that array points to the corresponding
349
- * value on the stack; and if the function returns
350
- * a structure, it will change RESP to point to the
351
- * structure return address. */
352
-
353
- ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
354
-
355
- (closure->fun) (cif, resp, arg_area, closure->user_data);
356
-
357
- /* The result is returned in rax. This does the right thing for
358
- result types except for floats; we have to 'mov xmm0, rax' in the
359
- caller to correct this.
360
- TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
361
- */
362
- return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
391
+ ffi_call_i386 (frame, stack);
363
392
  }
364
393
 
365
- #else
366
- unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
367
- ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
394
+ void
395
+ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
368
396
  {
369
- /* our various things... */
370
- ffi_cif *cif;
371
- void **arg_area;
372
-
373
- cif = closure->cif;
374
- arg_area = (void**) alloca (cif->nargs * sizeof (void*));
375
-
376
- /* this call will initialize ARG_AREA, such that each
377
- * element in that array points to the corresponding
378
- * value on the stack; and if the function returns
379
- * a structure, it will change RESP to point to the
380
- * structure return address. */
381
-
382
- ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
383
-
384
- (closure->fun) (cif, *respp, arg_area, closure->user_data);
385
-
386
- return cif->flags;
397
+ ffi_call_int (cif, fn, rvalue, avalue, NULL);
387
398
  }
388
- #endif /* !X86_WIN64 */
389
399
 
390
- static void
391
- ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
392
- ffi_cif *cif)
400
+ #ifdef FFI_GO_CLOSURES
401
+ void
402
+ ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
403
+ void **avalue, void *closure)
393
404
  {
394
- register unsigned int i;
395
- register void **p_argv;
396
- register char *argp;
397
- register ffi_type **p_arg;
398
-
399
- argp = stack;
400
-
401
- #ifdef X86_WIN64
402
- if (cif->rtype->size > sizeof(ffi_arg)
403
- || (cif->flags == FFI_TYPE_STRUCT
404
- && (cif->rtype->size != 1 && cif->rtype->size != 2
405
- && cif->rtype->size != 4 && cif->rtype->size != 8))) {
406
- *rvalue = *(void **) argp;
407
- argp += sizeof(void *);
408
- }
409
- #else
410
- if ( cif->flags == FFI_TYPE_STRUCT ) {
411
- *rvalue = *(void **) argp;
412
- argp += sizeof(void *);
413
- }
405
+ ffi_call_int (cif, fn, rvalue, avalue, closure);
406
+ }
414
407
  #endif
415
408
 
416
- p_argv = avalue;
409
+ /** private members **/
410
+
411
+ void FFI_HIDDEN ffi_closure_i386(void);
412
+ void FFI_HIDDEN ffi_closure_STDCALL(void);
413
+ void FFI_HIDDEN ffi_closure_REGISTER(void);
417
414
 
418
- for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
415
+ struct closure_frame
416
+ {
417
+ unsigned rettemp[4]; /* 0 */
418
+ unsigned regs[3]; /* 16-24 */
419
+ ffi_cif *cif; /* 28 */
420
+ void (*fun)(ffi_cif*,void*,void**,void*); /* 32 */
421
+ void *user_data; /* 36 */
422
+ };
423
+
424
+ int FFI_HIDDEN FFI_DECLARE_FASTCALL
425
+ ffi_closure_inner (struct closure_frame *frame, char *stack)
426
+ {
427
+ ffi_cif *cif = frame->cif;
428
+ int cabi, i, n, flags, dir, narg_reg;
429
+ const struct abi_params *pabi;
430
+ ffi_type **arg_types;
431
+ char *argp;
432
+ void *rvalue;
433
+ void **avalue;
434
+
435
+ cabi = cif->abi;
436
+ flags = cif->flags;
437
+ narg_reg = 0;
438
+ rvalue = frame->rettemp;
439
+ pabi = &abi_params[cabi];
440
+ dir = pabi->dir;
441
+ argp = (dir < 0 ? stack + STACK_ALIGN (cif->bytes) : stack);
442
+
443
+ switch (flags)
419
444
  {
420
- size_t z;
445
+ case X86_RET_STRUCTARG:
446
+ if (pabi->nregs > 0)
447
+ {
448
+ rvalue = (void *)frame->regs[pabi->regs[0]];
449
+ narg_reg = 1;
450
+ frame->rettemp[0] = (unsigned)rvalue;
451
+ break;
452
+ }
453
+ /* fallthru */
454
+ case X86_RET_STRUCTPOP:
455
+ rvalue = *(void **)argp;
456
+ argp += sizeof(void *);
457
+ frame->rettemp[0] = (unsigned)rvalue;
458
+ break;
459
+ }
421
460
 
422
- /* Align if necessary */
423
- if ((sizeof(void*) - 1) & (size_t) argp) {
424
- argp = (char *) ALIGN(argp, sizeof(void*));
425
- }
461
+ n = cif->nargs;
462
+ avalue = alloca(sizeof(void *) * n);
426
463
 
427
- #ifdef X86_WIN64
428
- if ((*p_arg)->size > sizeof(ffi_arg)
429
- || ((*p_arg)->type == FFI_TYPE_STRUCT
430
- && ((*p_arg)->size != 1 && (*p_arg)->size != 2
431
- && (*p_arg)->size != 4 && (*p_arg)->size != 8)))
432
- {
433
- z = sizeof(void *);
434
- *p_argv = *(void **)argp;
435
- }
464
+ arg_types = cif->arg_types;
465
+ for (i = 0; i < n; ++i)
466
+ {
467
+ ffi_type *ty = arg_types[i];
468
+ size_t z = ty->size;
469
+ int t = ty->type;
470
+ void *valp;
471
+
472
+ if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
473
+ {
474
+ if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
475
+ valp = &frame->regs[pabi->regs[narg_reg++]];
476
+ else if (dir < 0)
477
+ {
478
+ argp -= 4;
479
+ valp = argp;
480
+ }
481
+ else
482
+ {
483
+ valp = argp;
484
+ argp += 4;
485
+ }
486
+ }
436
487
  else
437
- #endif
438
- {
439
- z = (*p_arg)->size;
440
-
441
- /* because we're little endian, this is what it turns into. */
442
-
443
- *p_argv = (void*) argp;
444
- }
445
-
446
- p_argv++;
447
- #ifdef X86_WIN64
448
- argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
449
- #else
450
- argp += z;
451
- #endif
488
+ {
489
+ size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
490
+ size_t align = FFI_SIZEOF_ARG;
491
+
492
+ /* See the comment in ffi_call_int. */
493
+ if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
494
+ align = 16;
495
+
496
+ /* Issue 434: For thiscall and fastcall, if the paramter passed
497
+ as 64-bit integer or struct, all following integer parameters
498
+ will be passed on stack. */
499
+ if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
500
+ && (t == FFI_TYPE_SINT64
501
+ || t == FFI_TYPE_UINT64
502
+ || t == FFI_TYPE_STRUCT))
503
+ narg_reg = 2;
504
+
505
+ if (dir < 0)
506
+ {
507
+ /* ??? These reverse argument ABIs are probably too old
508
+ to have cared about alignment. Someone should check. */
509
+ argp -= za;
510
+ valp = argp;
511
+ }
512
+ else
513
+ {
514
+ argp = (char *)FFI_ALIGN (argp, align);
515
+ valp = argp;
516
+ argp += za;
517
+ }
518
+ }
519
+
520
+ avalue[i] = valp;
452
521
  }
453
-
454
- return;
455
- }
456
522
 
457
- #define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
458
- { unsigned char *__tramp = (unsigned char*)(TRAMP); \
459
- void* __fun = (void*)(FUN); \
460
- void* __ctx = (void*)(CTX); \
461
- *(unsigned char*) &__tramp[0] = 0x41; \
462
- *(unsigned char*) &__tramp[1] = 0xbb; \
463
- *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
464
- *(unsigned char*) &__tramp[6] = 0x48; \
465
- *(unsigned char*) &__tramp[7] = 0xb8; \
466
- *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
467
- *(unsigned char *) &__tramp[16] = 0x49; \
468
- *(unsigned char *) &__tramp[17] = 0xba; \
469
- *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
470
- *(unsigned char *) &__tramp[26] = 0x41; \
471
- *(unsigned char *) &__tramp[27] = 0xff; \
472
- *(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
473
- }
474
-
475
- /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
476
-
477
- #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
478
- { unsigned char *__tramp = (unsigned char*)(TRAMP); \
479
- unsigned int __fun = (unsigned int)(FUN); \
480
- unsigned int __ctx = (unsigned int)(CTX); \
481
- unsigned int __dis = __fun - (__ctx + 10); \
482
- *(unsigned char*) &__tramp[0] = 0xb8; \
483
- *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
484
- *(unsigned char *) &__tramp[5] = 0xe9; \
485
- *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
486
- }
487
-
488
- #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
489
- { unsigned char *__tramp = (unsigned char*)(TRAMP); \
490
- unsigned int __fun = (unsigned int)(FUN); \
491
- unsigned int __ctx = (unsigned int)(CTX); \
492
- unsigned int __dis = __fun - (__ctx + 10); \
493
- unsigned short __size = (unsigned short)(SIZE); \
494
- *(unsigned char*) &__tramp[0] = 0xb8; \
495
- *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
496
- *(unsigned char *) &__tramp[5] = 0xe8; \
497
- *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
498
- *(unsigned char *) &__tramp[10] = 0xc2; \
499
- *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
500
- }
501
-
502
- /* the cif must already be prep'ed */
523
+ frame->fun (cif, rvalue, avalue, frame->user_data);
524
+
525
+ if (cabi == FFI_STDCALL)
526
+ return flags + (cif->bytes << X86_RET_POP_SHIFT);
527
+ else
528
+ return flags;
529
+ }
503
530
 
504
531
  ffi_status
505
532
  ffi_prep_closure_loc (ffi_closure* closure,
@@ -508,137 +535,236 @@ ffi_prep_closure_loc (ffi_closure* closure,
508
535
  void *user_data,
509
536
  void *codeloc)
510
537
  {
511
- #ifdef X86_WIN64
512
- #define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
513
- #define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
514
- if (cif->abi == FFI_WIN64)
515
- {
516
- int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
517
- FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
518
- &ffi_closure_win64,
519
- codeloc, mask);
520
- /* make sure we can execute here */
521
- }
522
- #else
523
- if (cif->abi == FFI_SYSV)
524
- {
525
- FFI_INIT_TRAMPOLINE (&closure->tramp[0],
526
- &ffi_closure_SYSV,
527
- (void*)codeloc);
528
- }
529
- #ifdef X86_WIN32
530
- else if (cif->abi == FFI_STDCALL)
538
+ char *tramp = closure->tramp;
539
+ void (*dest)(void);
540
+ int op = 0xb8; /* movl imm, %eax */
541
+
542
+ switch (cif->abi)
531
543
  {
532
- FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
533
- &ffi_closure_STDCALL,
534
- (void*)codeloc, cif->bytes);
544
+ case FFI_SYSV:
545
+ case FFI_THISCALL:
546
+ case FFI_FASTCALL:
547
+ case FFI_MS_CDECL:
548
+ dest = ffi_closure_i386;
549
+ break;
550
+ case FFI_STDCALL:
551
+ case FFI_PASCAL:
552
+ dest = ffi_closure_STDCALL;
553
+ break;
554
+ case FFI_REGISTER:
555
+ dest = ffi_closure_REGISTER;
556
+ op = 0x68; /* pushl imm */
557
+ break;
558
+ default:
559
+ return FFI_BAD_ABI;
535
560
  }
536
- #endif /* X86_WIN32 */
537
- #endif /* !X86_WIN64 */
538
- else
561
+
562
+ /* endbr32. */
563
+ *(UINT32 *) tramp = 0xfb1e0ff3;
564
+
565
+ /* movl or pushl immediate. */
566
+ tramp[4] = op;
567
+ *(void **)(tramp + 5) = codeloc;
568
+
569
+ /* jmp dest */
570
+ tramp[9] = 0xe9;
571
+ *(unsigned *)(tramp + 10) = (unsigned)dest - ((unsigned)codeloc + 14);
572
+
573
+ closure->cif = cif;
574
+ closure->fun = fun;
575
+ closure->user_data = user_data;
576
+
577
+ return FFI_OK;
578
+ }
579
+
580
+ #ifdef FFI_GO_CLOSURES
581
+
582
+ void FFI_HIDDEN ffi_go_closure_EAX(void);
583
+ void FFI_HIDDEN ffi_go_closure_ECX(void);
584
+ void FFI_HIDDEN ffi_go_closure_STDCALL(void);
585
+
586
+ ffi_status
587
+ ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
588
+ void (*fun)(ffi_cif*,void*,void**,void*))
589
+ {
590
+ void (*dest)(void);
591
+
592
+ switch (cif->abi)
539
593
  {
594
+ case FFI_SYSV:
595
+ case FFI_MS_CDECL:
596
+ dest = ffi_go_closure_ECX;
597
+ break;
598
+ case FFI_THISCALL:
599
+ case FFI_FASTCALL:
600
+ dest = ffi_go_closure_EAX;
601
+ break;
602
+ case FFI_STDCALL:
603
+ case FFI_PASCAL:
604
+ dest = ffi_go_closure_STDCALL;
605
+ break;
606
+ case FFI_REGISTER:
607
+ default:
540
608
  return FFI_BAD_ABI;
541
609
  }
542
-
543
- closure->cif = cif;
544
- closure->user_data = user_data;
545
- closure->fun = fun;
610
+
611
+ closure->tramp = dest;
612
+ closure->cif = cif;
613
+ closure->fun = fun;
546
614
 
547
615
  return FFI_OK;
548
616
  }
549
617
 
618
+ #endif /* FFI_GO_CLOSURES */
619
+
550
620
  /* ------- Native raw API support -------------------------------- */
551
621
 
552
622
  #if !FFI_NO_RAW_API
553
623
 
624
+ void FFI_HIDDEN ffi_closure_raw_SYSV(void);
625
+ void FFI_HIDDEN ffi_closure_raw_THISCALL(void);
626
+
554
627
  ffi_status
555
- ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
556
- ffi_cif* cif,
628
+ ffi_prep_raw_closure_loc (ffi_raw_closure *closure,
629
+ ffi_cif *cif,
557
630
  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
558
631
  void *user_data,
559
632
  void *codeloc)
560
633
  {
634
+ char *tramp = closure->tramp;
635
+ void (*dest)(void);
561
636
  int i;
562
637
 
563
- if (cif->abi != FFI_SYSV) {
564
- return FFI_BAD_ABI;
565
- }
566
-
567
- /* we currently don't support certain kinds of arguments for raw
638
+ /* We currently don't support certain kinds of arguments for raw
568
639
  closures. This should be implemented by a separate assembly
569
640
  language routine, since it would require argument processing,
570
641
  something we don't do now for performance. */
571
-
572
642
  for (i = cif->nargs-1; i >= 0; i--)
643
+ switch (cif->arg_types[i]->type)
644
+ {
645
+ case FFI_TYPE_STRUCT:
646
+ case FFI_TYPE_LONGDOUBLE:
647
+ return FFI_BAD_TYPEDEF;
648
+ }
649
+
650
+ switch (cif->abi)
573
651
  {
574
- FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
575
- FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
652
+ case FFI_THISCALL:
653
+ dest = ffi_closure_raw_THISCALL;
654
+ break;
655
+ case FFI_SYSV:
656
+ dest = ffi_closure_raw_SYSV;
657
+ break;
658
+ default:
659
+ return FFI_BAD_ABI;
576
660
  }
577
-
578
661
 
579
- FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
580
- codeloc);
581
-
582
- closure->cif = cif;
662
+ /* movl imm, %eax. */
663
+ tramp[0] = 0xb8;
664
+ *(void **)(tramp + 1) = codeloc;
665
+
666
+ /* jmp dest */
667
+ tramp[5] = 0xe9;
668
+ *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
669
+
670
+ closure->cif = cif;
671
+ closure->fun = fun;
583
672
  closure->user_data = user_data;
584
- closure->fun = fun;
585
673
 
586
674
  return FFI_OK;
587
675
  }
588
676
 
589
- static void
590
- ffi_prep_args_raw(char *stack, extended_cif *ecif)
591
- {
592
- memcpy (stack, ecif->avalue, ecif->cif->bytes);
593
- }
594
-
595
- /* we borrow this routine from libffi (it must be changed, though, to
596
- * actually call the function passed in the first argument. as of
597
- * libffi-1.20, this is not the case.)
598
- */
599
-
600
677
  void
601
- ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
678
+ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
602
679
  {
603
- extended_cif ecif;
604
- void **avalue = (void **)fake_avalue;
605
-
606
- ecif.cif = cif;
607
- ecif.avalue = avalue;
608
-
609
- /* If the return value is a struct and we don't have a return */
610
- /* value address then we need to make one */
611
-
612
- if ((rvalue == NULL) &&
613
- (cif->rtype->type == FFI_TYPE_STRUCT))
680
+ size_t rsize, bytes;
681
+ struct call_frame *frame;
682
+ char *stack, *argp;
683
+ ffi_type **arg_types;
684
+ int flags, cabi, i, n, narg_reg;
685
+ const struct abi_params *pabi;
686
+
687
+ flags = cif->flags;
688
+ cabi = cif->abi;
689
+ pabi = &abi_params[cabi];
690
+
691
+ rsize = 0;
692
+ if (rvalue == NULL)
614
693
  {
615
- ecif.rvalue = alloca(cif->rtype->size);
694
+ switch (flags)
695
+ {
696
+ case X86_RET_FLOAT:
697
+ case X86_RET_DOUBLE:
698
+ case X86_RET_LDOUBLE:
699
+ case X86_RET_STRUCTPOP:
700
+ case X86_RET_STRUCTARG:
701
+ /* The float cases need to pop the 387 stack.
702
+ The struct cases need to pass a valid pointer to the callee. */
703
+ rsize = cif->rtype->size;
704
+ break;
705
+ default:
706
+ /* We can pretend that the callee returns nothing. */
707
+ flags = X86_RET_VOID;
708
+ break;
709
+ }
616
710
  }
617
- else
618
- ecif.rvalue = rvalue;
619
-
620
-
621
- switch (cif->abi)
711
+
712
+ bytes = STACK_ALIGN (cif->bytes);
713
+ argp = stack =
714
+ (void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);
715
+ frame = (struct call_frame *)(stack + bytes);
716
+ if (rsize)
717
+ rvalue = frame + 1;
718
+
719
+ frame->fn = fn;
720
+ frame->flags = flags;
721
+ frame->rvalue = rvalue;
722
+
723
+ narg_reg = 0;
724
+ switch (flags)
622
725
  {
623
- #ifdef X86_WIN32
624
- case FFI_SYSV:
625
- case FFI_STDCALL:
626
- ffi_call_win32(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
627
- ecif.rvalue, fn);
628
- break;
629
- #else
630
- case FFI_SYSV:
631
- ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
632
- ecif.rvalue, fn);
633
- break;
634
- #endif
635
- default:
636
- FFI_ASSERT(0);
726
+ case X86_RET_STRUCTARG:
727
+ /* The pointer is passed as the first argument. */
728
+ if (pabi->nregs > 0)
729
+ {
730
+ frame->regs[pabi->regs[0]] = (unsigned)rvalue;
731
+ narg_reg = 1;
732
+ break;
733
+ }
734
+ /* fallthru */
735
+ case X86_RET_STRUCTPOP:
736
+ *(void **)argp = rvalue;
737
+ argp += sizeof(void *);
738
+ bytes -= sizeof(void *);
637
739
  break;
638
740
  }
639
- }
640
-
641
- #endif
642
741
 
643
- #endif /* !__x86_64__ || X86_WIN64 */
742
+ arg_types = cif->arg_types;
743
+ for (i = 0, n = cif->nargs; narg_reg < pabi->nregs && i < n; i++)
744
+ {
745
+ ffi_type *ty = arg_types[i];
746
+ size_t z = ty->size;
747
+ int t = ty->type;
748
+
749
+ if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT && t != FFI_TYPE_FLOAT)
750
+ {
751
+ ffi_arg val = extend_basic_type (avalue, t);
752
+ frame->regs[pabi->regs[narg_reg++]] = val;
753
+ z = FFI_SIZEOF_ARG;
754
+ }
755
+ else
756
+ {
757
+ memcpy (argp, avalue, z);
758
+ z = FFI_ALIGN (z, FFI_SIZEOF_ARG);
759
+ argp += z;
760
+ }
761
+ avalue += z;
762
+ bytes -= z;
763
+ }
764
+ if (i < n)
765
+ memcpy (argp, avalue, bytes);
644
766
 
767
+ ffi_call_i386 (frame, stack);
768
+ }
769
+ #endif /* !FFI_NO_RAW_API */
770
+ #endif /* __i386__ */