ffi 1.9.18 → 1.9.23

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 (468) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +22 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +52 -0
  5. data/.yardopts +5 -0
  6. data/Gemfile +15 -0
  7. data/{spec/ffi/LICENSE.SPECS → LICENSE.SPECS} +1 -1
  8. data/README.md +3 -4
  9. data/Rakefile +41 -5
  10. data/appveyor.yml +22 -0
  11. data/ext/ffi_c/AbstractMemory.c +6 -1
  12. data/ext/ffi_c/Call.c +1 -22
  13. data/ext/ffi_c/Call.h +0 -9
  14. data/ext/ffi_c/Closure.c +54 -0
  15. data/ext/ffi_c/{ClosurePool.h → Closure.h} +13 -23
  16. data/ext/ffi_c/Function.c +16 -25
  17. data/ext/ffi_c/Function.h +1 -2
  18. data/ext/ffi_c/FunctionInfo.c +0 -4
  19. data/ext/ffi_c/MethodHandle.c +33 -268
  20. data/ext/ffi_c/Platform.c +10 -2
  21. data/ext/ffi_c/extconf.rb +10 -5
  22. data/ext/ffi_c/ffi.c +2 -2
  23. data/ext/ffi_c/libffi/.appveyor.yml +48 -0
  24. data/ext/ffi_c/libffi/.gitignore +36 -0
  25. data/ext/ffi_c/libffi/.travis/install.sh +14 -0
  26. data/ext/ffi_c/libffi/.travis.yml +30 -0
  27. data/ext/ffi_c/libffi/ChangeLog.libffi +2 -2
  28. data/ext/ffi_c/libffi/{ChangeLog → ChangeLog.libffi-3.1} +1402 -2
  29. data/ext/ffi_c/libffi/ChangeLog.v1 +1 -1
  30. data/ext/ffi_c/libffi/LICENSE +1 -1
  31. data/ext/ffi_c/libffi/Makefile.am +169 -158
  32. data/ext/ffi_c/libffi/Makefile.in +927 -938
  33. data/ext/ffi_c/libffi/README +164 -52
  34. data/ext/ffi_c/libffi/acinclude.m4 +387 -0
  35. data/ext/ffi_c/libffi/autogen.sh +2 -0
  36. data/ext/ffi_c/libffi/config.guess +336 -371
  37. data/ext/ffi_c/libffi/config.sub +246 -115
  38. data/ext/ffi_c/libffi/configure +6976 -2189
  39. data/ext/ffi_c/libffi/configure.ac +148 -256
  40. data/ext/ffi_c/libffi/configure.host +277 -4
  41. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  42. data/ext/ffi_c/libffi/doc/Makefile.in +811 -0
  43. data/ext/ffi_c/libffi/doc/libffi.texi +430 -45
  44. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  45. data/ext/ffi_c/libffi/fficonfig.h.in +24 -13
  46. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +203 -0
  47. data/ext/ffi_c/libffi/include/Makefile.am +3 -3
  48. data/ext/ffi_c/libffi/include/Makefile.in +188 -71
  49. data/ext/ffi_c/libffi/include/ffi.h.in +112 -50
  50. data/ext/ffi_c/libffi/include/ffi_cfi.h +55 -0
  51. data/ext/ffi_c/libffi/include/ffi_common.h +32 -11
  52. data/ext/ffi_c/libffi/install-sh +190 -202
  53. data/ext/ffi_c/libffi/libffi.map.in +80 -0
  54. data/ext/ffi_c/libffi/libffi.pc.in +3 -2
  55. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +1043 -0
  56. data/ext/ffi_c/libffi/libtool-ldflags +106 -0
  57. data/ext/ffi_c/libffi/libtool-version +1 -1
  58. data/ext/ffi_c/libffi/ltmain.sh +3553 -2033
  59. data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
  60. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +69 -0
  61. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +13 -8
  62. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +31 -104
  63. data/ext/ffi_c/libffi/m4/{ax_check_compiler_flags.m4 → ax_check_compile_flag.m4} +30 -34
  64. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +32 -11
  65. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +6 -5
  66. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +31 -21
  67. data/ext/ffi_c/libffi/man/Makefile.am +2 -2
  68. data/ext/ffi_c/libffi/man/Makefile.in +141 -49
  69. data/ext/ffi_c/libffi/man/ffi.3 +10 -0
  70. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +6 -4
  71. data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +73 -0
  72. data/ext/ffi_c/libffi/missing +150 -311
  73. data/ext/ffi_c/libffi/msvcc.sh +72 -9
  74. data/ext/ffi_c/libffi/src/aarch64/ffi.c +964 -0
  75. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +81 -0
  76. data/ext/ffi_c/libffi/src/aarch64/internal.h +67 -0
  77. data/ext/ffi_c/libffi/src/aarch64/sysv.S +438 -0
  78. data/ext/ffi_c/libffi/src/alpha/ffi.c +335 -98
  79. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +10 -1
  80. data/ext/ffi_c/libffi/src/alpha/internal.h +23 -0
  81. data/ext/ffi_c/libffi/src/alpha/osf.S +161 -266
  82. data/ext/ffi_c/libffi/src/arc/arcompact.S +135 -0
  83. data/ext/ffi_c/libffi/src/arc/ffi.c +266 -0
  84. data/ext/ffi_c/libffi/src/arc/ffitarget.h +53 -0
  85. data/ext/ffi_c/libffi/src/arm/ffi.c +608 -517
  86. data/ext/ffi_c/libffi/src/arm/ffitarget.h +24 -7
  87. data/ext/ffi_c/libffi/src/arm/internal.h +7 -0
  88. data/ext/ffi_c/libffi/src/arm/sysv.S +303 -417
  89. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +6 -1
  90. data/ext/ffi_c/libffi/src/bfin/ffi.c +196 -0
  91. data/ext/ffi_c/libffi/src/bfin/ffitarget.h +43 -0
  92. data/ext/ffi_c/libffi/src/bfin/sysv.S +179 -0
  93. data/ext/ffi_c/libffi/src/closures.c +366 -45
  94. data/ext/ffi_c/libffi/src/cris/ffi.c +10 -7
  95. data/ext/ffi_c/libffi/src/cris/ffitarget.h +6 -1
  96. data/ext/ffi_c/libffi/src/debug.c +6 -1
  97. data/ext/ffi_c/libffi/src/dlmalloc.c +16 -11
  98. data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
  99. data/ext/ffi_c/libffi/src/frv/ffitarget.h +6 -1
  100. data/ext/ffi_c/libffi/src/ia64/ffi.c +11 -7
  101. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +6 -1
  102. data/ext/ffi_c/libffi/src/ia64/unix.S +2 -0
  103. data/ext/ffi_c/libffi/src/java_raw_api.c +23 -5
  104. data/ext/ffi_c/libffi/src/m32r/ffi.c +1 -1
  105. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +6 -1
  106. data/ext/ffi_c/libffi/src/m68k/ffi.c +87 -13
  107. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +6 -1
  108. data/ext/ffi_c/libffi/src/m68k/sysv.S +119 -32
  109. data/ext/ffi_c/libffi/src/m88k/ffi.c +400 -0
  110. data/ext/ffi_c/libffi/src/m88k/ffitarget.h +49 -0
  111. data/ext/ffi_c/libffi/src/m88k/obsd.S +209 -0
  112. data/ext/ffi_c/libffi/src/metag/ffi.c +330 -0
  113. data/ext/ffi_c/libffi/{fficonfig.hw → src/metag/ffitarget.h} +22 -26
  114. data/ext/ffi_c/libffi/src/metag/sysv.S +311 -0
  115. data/ext/ffi_c/libffi/src/microblaze/ffi.c +321 -0
  116. data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +53 -0
  117. data/ext/ffi_c/libffi/src/microblaze/sysv.S +302 -0
  118. data/ext/ffi_c/libffi/src/mips/ffi.c +103 -28
  119. data/ext/ffi_c/libffi/src/mips/ffitarget.h +10 -3
  120. data/ext/ffi_c/libffi/src/mips/n32.S +128 -56
  121. data/ext/ffi_c/libffi/src/mips/o32.S +148 -27
  122. data/ext/ffi_c/libffi/src/moxie/eabi.S +55 -82
  123. data/ext/ffi_c/libffi/src/moxie/ffi.c +40 -44
  124. data/ext/ffi_c/libffi/src/moxie/ffitarget.h +52 -0
  125. data/ext/ffi_c/libffi/src/nios2/ffi.c +304 -0
  126. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +52 -0
  127. data/ext/ffi_c/libffi/src/nios2/sysv.S +136 -0
  128. data/ext/ffi_c/libffi/src/or1k/ffi.c +328 -0
  129. data/ext/ffi_c/libffi/src/or1k/ffitarget.h +58 -0
  130. data/ext/ffi_c/libffi/src/or1k/sysv.S +107 -0
  131. data/ext/ffi_c/libffi/src/pa/ffitarget.h +8 -1
  132. data/ext/ffi_c/libffi/src/powerpc/aix.S +245 -7
  133. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +253 -4
  134. data/ext/ffi_c/libffi/src/powerpc/asm.h +2 -2
  135. data/ext/ffi_c/libffi/src/powerpc/darwin.S +2 -7
  136. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +22 -26
  137. data/ext/ffi_c/libffi/src/powerpc/ffi.c +103 -1378
  138. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +111 -30
  139. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +945 -0
  140. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +94 -0
  141. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
  142. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +103 -44
  143. data/ext/ffi_c/libffi/src/powerpc/linux64.S +100 -59
  144. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +360 -108
  145. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +138 -68
  146. data/ext/ffi_c/libffi/src/powerpc/sysv.S +68 -112
  147. data/ext/ffi_c/libffi/src/prep_cif.c +108 -24
  148. data/ext/ffi_c/libffi/src/raw_api.c +18 -5
  149. data/ext/ffi_c/libffi/src/s390/ffi.c +294 -318
  150. data/ext/ffi_c/libffi/src/s390/ffitarget.h +9 -1
  151. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  152. data/ext/ffi_c/libffi/src/s390/sysv.S +257 -366
  153. data/ext/ffi_c/libffi/src/sh/ffi.c +4 -3
  154. data/ext/ffi_c/libffi/src/sh/ffitarget.h +6 -1
  155. data/ext/ffi_c/libffi/src/sh64/ffi.c +3 -2
  156. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +6 -1
  157. data/ext/ffi_c/libffi/src/sparc/ffi.c +326 -527
  158. data/ext/ffi_c/libffi/src/sparc/ffi64.c +608 -0
  159. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +20 -7
  160. data/ext/ffi_c/libffi/src/sparc/internal.h +26 -0
  161. data/ext/ffi_c/libffi/src/sparc/v8.S +364 -234
  162. data/ext/ffi_c/libffi/src/sparc/v9.S +340 -207
  163. data/ext/ffi_c/libffi/src/tile/ffi.c +355 -0
  164. data/ext/ffi_c/libffi/src/tile/ffitarget.h +65 -0
  165. data/ext/ffi_c/libffi/src/tile/tile.S +360 -0
  166. data/ext/ffi_c/libffi/src/types.c +43 -14
  167. data/ext/ffi_c/libffi/src/vax/elfbsd.S +195 -0
  168. data/ext/ffi_c/libffi/src/vax/ffi.c +276 -0
  169. data/ext/ffi_c/libffi/src/vax/ffitarget.h +49 -0
  170. data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
  171. data/ext/ffi_c/libffi/src/x86/ffi.c +591 -500
  172. data/ext/ffi_c/libffi/src/x86/ffi64.c +359 -116
  173. data/ext/ffi_c/libffi/src/x86/ffitarget.h +55 -35
  174. data/ext/ffi_c/libffi/src/x86/ffiw64.c +287 -0
  175. data/ext/ffi_c/libffi/src/x86/internal.h +29 -0
  176. data/ext/ffi_c/libffi/src/x86/internal64.h +22 -0
  177. data/ext/ffi_c/libffi/src/x86/sysv.S +975 -400
  178. data/ext/ffi_c/libffi/src/x86/unix64.S +398 -299
  179. data/ext/ffi_c/libffi/src/x86/win64.S +222 -458
  180. data/ext/ffi_c/libffi/src/x86/win64_intel.S +237 -0
  181. data/ext/ffi_c/libffi/src/xtensa/ffi.c +298 -0
  182. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +53 -0
  183. data/ext/ffi_c/libffi/src/xtensa/sysv.S +253 -0
  184. data/ext/ffi_c/libffi/stamp-h.in +1 -0
  185. data/ext/ffi_c/libffi/testsuite/Makefile.am +79 -73
  186. data/ext/ffi_c/libffi/testsuite/Makefile.in +219 -111
  187. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +121 -25
  188. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +21 -1
  189. data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
  190. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +4 -6
  191. data/ext/ffi_c/libffi/testsuite/libffi.call/{closure_stdcall.c → closure_simple.c} +7 -16
  192. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +4 -4
  193. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +4 -4
  194. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +4 -4
  195. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +4 -4
  196. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +4 -4
  197. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +4 -4
  198. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +4 -4
  199. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +5 -5
  200. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +4 -4
  201. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +4 -4
  202. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +4 -4
  203. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +4 -4
  204. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
  205. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +4 -4
  206. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +4 -4
  207. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +4 -4
  208. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +4 -4
  209. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +5 -5
  210. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +4 -4
  211. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +4 -4
  212. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +4 -4
  213. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +4 -4
  214. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +4 -4
  215. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +4 -4
  216. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +4 -4
  217. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +4 -4
  218. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +4 -4
  219. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +4 -4
  220. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +4 -6
  221. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +4 -6
  222. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +4 -4
  223. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +4 -4
  224. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +4 -4
  225. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +4 -4
  226. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +4 -4
  227. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +4 -4
  228. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +4 -4
  229. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +4 -4
  230. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +10 -9
  231. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +3 -3
  232. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +10 -9
  233. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_args.c +70 -0
  234. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c +55 -0
  235. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +1 -1
  236. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +11 -9
  237. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_struct_va1.c +114 -0
  238. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar_va.c +44 -0
  239. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint_va.c +45 -0
  240. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulong_va.c +45 -0
  241. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +5 -5
  242. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort_va.c +44 -0
  243. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +2 -2
  244. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +23 -40
  245. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +3 -1
  246. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +6 -4
  247. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +4 -2
  248. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +107 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +18 -19
  250. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +6 -16
  251. data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +57 -0
  252. data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +70 -0
  253. data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +78 -0
  254. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +0 -1
  255. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +6 -6
  256. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +8 -8
  257. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +6 -6
  258. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct11.c +121 -0
  259. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +5 -5
  260. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +5 -5
  261. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +5 -5
  262. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +5 -5
  263. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +6 -6
  264. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +5 -5
  265. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +6 -6
  266. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +6 -6
  267. data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +46 -0
  268. data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +127 -0
  269. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +1 -0
  270. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
  271. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +1 -1
  272. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +1 -1
  273. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +7 -7
  274. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +7 -7
  275. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +5 -5
  276. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +5 -5
  277. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +2 -2
  278. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +49 -0
  279. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +49 -0
  280. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +55 -0
  281. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +9 -7
  282. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +7 -7
  283. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +7 -6
  284. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +9 -8
  285. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +9 -8
  286. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +9 -9
  287. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +9 -9
  288. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +9 -8
  289. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +9 -8
  290. data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +2 -2
  291. data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
  292. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.call}/unwindtest.cc +3 -10
  293. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.call}/unwindtest_ffi_call.cc +2 -1
  294. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +196 -0
  295. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +121 -0
  296. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +123 -0
  297. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +125 -0
  298. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +91 -0
  299. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +10 -0
  300. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +10 -0
  301. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +10 -0
  302. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +42 -0
  303. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +10 -0
  304. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +10 -0
  305. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +10 -0
  306. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +71 -0
  307. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +10 -0
  308. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +10 -0
  309. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +10 -0
  310. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +80 -0
  311. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +10 -0
  312. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +16 -0
  313. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +10 -0
  314. data/ext/ffi_c/libffi/testsuite/{libffi.special/special.exp → libffi.complex/complex.exp} +9 -8
  315. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +51 -0
  316. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +7 -0
  317. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +7 -0
  318. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +7 -0
  319. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +10 -0
  320. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +10 -0
  321. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +86 -0
  322. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +10 -0
  323. data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +1 -0
  324. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +78 -0
  325. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +10 -0
  326. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +10 -0
  327. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +10 -0
  328. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +37 -0
  329. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +41 -0
  330. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +10 -0
  331. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +10 -0
  332. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +10 -0
  333. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +44 -0
  334. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +10 -0
  335. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +10 -0
  336. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +10 -0
  337. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +10 -0
  338. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +10 -0
  339. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +10 -0
  340. data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +34 -0
  341. data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +28 -0
  342. data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +1 -0
  343. data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +36 -0
  344. data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +19 -0
  345. data/ext/ffi_c/libffi.bsd.mk +11 -5
  346. data/ext/ffi_c/libffi.darwin.mk +14 -4
  347. data/ext/ffi_c/libffi.gnu.mk +3 -2
  348. data/ext/ffi_c/libffi.mk +10 -5
  349. data/ext/ffi_c/libffi.vc.mk +1 -1
  350. data/ext/ffi_c/libffi.vc64.mk +1 -1
  351. data/ffi.gemspec +16 -3
  352. data/lib/ffi/enum.rb +124 -0
  353. data/lib/ffi/library.rb +66 -14
  354. data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
  355. data/lib/ffi/platform/x86_64-windows/types.conf +113 -20
  356. data/lib/ffi/platform.rb +7 -2
  357. data/lib/ffi/pointer.rb +1 -0
  358. data/lib/ffi/struct.rb +0 -2
  359. data/lib/ffi/version.rb +1 -2
  360. data/samples/getlogin.rb +8 -0
  361. data/samples/getpid.rb +8 -0
  362. data/samples/gettimeofday.rb +18 -0
  363. data/samples/hello.rb +7 -0
  364. data/samples/inotify.rb +60 -0
  365. data/samples/pty.rb +76 -0
  366. data/samples/qsort.rb +21 -0
  367. data/samples/sample_helper.rb +6 -0
  368. metadata +164 -115
  369. data/ext/ffi_c/ClosurePool.c +0 -283
  370. data/ext/ffi_c/libffi/Makefile.vc +0 -141
  371. data/ext/ffi_c/libffi/Makefile.vc64 +0 -141
  372. data/ext/ffi_c/libffi/aclocal.m4 +0 -1873
  373. data/ext/ffi_c/libffi/build-ios.sh +0 -67
  374. data/ext/ffi_c/libffi/compile +0 -143
  375. data/ext/ffi_c/libffi/depcomp +0 -630
  376. data/ext/ffi_c/libffi/doc/libffi.info +0 -593
  377. data/ext/ffi_c/libffi/doc/stamp-vti +0 -4
  378. data/ext/ffi_c/libffi/include/ffi.h.vc +0 -427
  379. data/ext/ffi_c/libffi/include/ffi.h.vc64 +0 -427
  380. data/ext/ffi_c/libffi/m4/libtool.m4 +0 -7831
  381. data/ext/ffi_c/libffi/m4/ltoptions.m4 +0 -369
  382. data/ext/ffi_c/libffi/m4/ltsugar.m4 +0 -123
  383. data/ext/ffi_c/libffi/m4/ltversion.m4 +0 -23
  384. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +0 -98
  385. data/ext/ffi_c/libffi/mdate-sh +0 -201
  386. data/ext/ffi_c/libffi/src/arm/gentramp.sh +0 -118
  387. data/ext/ffi_c/libffi/src/arm/trampoline.S +0 -4450
  388. data/ext/ffi_c/libffi/src/x86/darwin.S +0 -444
  389. data/ext/ffi_c/libffi/src/x86/darwin64.S +0 -416
  390. data/ext/ffi_c/libffi/src/x86/freebsd.S +0 -458
  391. data/ext/ffi_c/libffi/src/x86/win32.S +0 -1065
  392. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +0 -300
  393. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +0 -63
  394. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +0 -44
  395. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +0 -96
  396. data/ext/ffi_c/libffi/texinfo.tex +0 -7210
  397. data/gen/Rakefile +0 -30
  398. data/libtest/Benchmark.c +0 -52
  399. data/libtest/BoolTest.c +0 -34
  400. data/libtest/BufferTest.c +0 -31
  401. data/libtest/ClosureTest.c +0 -205
  402. data/libtest/EnumTest.c +0 -51
  403. data/libtest/FunctionTest.c +0 -70
  404. data/libtest/GNUmakefile +0 -149
  405. data/libtest/GlobalVariable.c +0 -62
  406. data/libtest/LastErrorTest.c +0 -21
  407. data/libtest/NumberTest.c +0 -132
  408. data/libtest/PointerTest.c +0 -63
  409. data/libtest/ReferenceTest.c +0 -23
  410. data/libtest/StringTest.c +0 -34
  411. data/libtest/StructTest.c +0 -243
  412. data/libtest/UnionTest.c +0 -43
  413. data/libtest/VariadicTest.c +0 -99
  414. data/spec/ffi/async_callback_spec.rb +0 -35
  415. data/spec/ffi/bool_spec.rb +0 -32
  416. data/spec/ffi/buffer_spec.rb +0 -279
  417. data/spec/ffi/callback_spec.rb +0 -773
  418. data/spec/ffi/custom_param_type.rb +0 -37
  419. data/spec/ffi/custom_type_spec.rb +0 -74
  420. data/spec/ffi/dup_spec.rb +0 -52
  421. data/spec/ffi/enum_spec.rb +0 -423
  422. data/spec/ffi/errno_spec.rb +0 -20
  423. data/spec/ffi/ffi_spec.rb +0 -28
  424. data/spec/ffi/fixtures/Benchmark.c +0 -52
  425. data/spec/ffi/fixtures/BoolTest.c +0 -34
  426. data/spec/ffi/fixtures/BufferTest.c +0 -31
  427. data/spec/ffi/fixtures/ClosureTest.c +0 -205
  428. data/spec/ffi/fixtures/EnumTest.c +0 -51
  429. data/spec/ffi/fixtures/FunctionTest.c +0 -142
  430. data/spec/ffi/fixtures/GNUmakefile +0 -149
  431. data/spec/ffi/fixtures/GlobalVariable.c +0 -62
  432. data/spec/ffi/fixtures/LastErrorTest.c +0 -21
  433. data/spec/ffi/fixtures/NumberTest.c +0 -132
  434. data/spec/ffi/fixtures/PipeHelper.h +0 -21
  435. data/spec/ffi/fixtures/PipeHelperPosix.c +0 -41
  436. data/spec/ffi/fixtures/PipeHelperWindows.c +0 -72
  437. data/spec/ffi/fixtures/PointerTest.c +0 -63
  438. data/spec/ffi/fixtures/ReferenceTest.c +0 -23
  439. data/spec/ffi/fixtures/StringTest.c +0 -34
  440. data/spec/ffi/fixtures/StructTest.c +0 -243
  441. data/spec/ffi/fixtures/UnionTest.c +0 -43
  442. data/spec/ffi/fixtures/VariadicTest.c +0 -99
  443. data/spec/ffi/fixtures/classes.rb +0 -438
  444. data/spec/ffi/function_spec.rb +0 -97
  445. data/spec/ffi/io_spec.rb +0 -16
  446. data/spec/ffi/library_spec.rb +0 -286
  447. data/spec/ffi/long_double.rb +0 -30
  448. data/spec/ffi/managed_struct_spec.rb +0 -68
  449. data/spec/ffi/memorypointer_spec.rb +0 -78
  450. data/spec/ffi/number_spec.rb +0 -247
  451. data/spec/ffi/platform_spec.rb +0 -114
  452. data/spec/ffi/pointer_spec.rb +0 -285
  453. data/spec/ffi/rbx/attach_function_spec.rb +0 -34
  454. data/spec/ffi/rbx/memory_pointer_spec.rb +0 -194
  455. data/spec/ffi/rbx/spec_helper.rb +0 -6
  456. data/spec/ffi/rbx/struct_spec.rb +0 -18
  457. data/spec/ffi/spec_helper.rb +0 -93
  458. data/spec/ffi/string_spec.rb +0 -118
  459. data/spec/ffi/strptr_spec.rb +0 -50
  460. data/spec/ffi/struct_by_ref_spec.rb +0 -43
  461. data/spec/ffi/struct_callback_spec.rb +0 -69
  462. data/spec/ffi/struct_initialize_spec.rb +0 -35
  463. data/spec/ffi/struct_packed_spec.rb +0 -50
  464. data/spec/ffi/struct_spec.rb +0 -886
  465. data/spec/ffi/typedef_spec.rb +0 -91
  466. data/spec/ffi/union_spec.rb +0 -67
  467. data/spec/ffi/variadic_spec.rb +0 -132
  468. data/spec/spec.opts +0 -4
@@ -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,477 @@
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
+ #ifndef __x86_64__
37
33
  #include <ffi.h>
38
34
  #include <ffi_common.h>
39
-
35
+ #include <stdint.h>
40
36
  #include <stdlib.h>
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
48
+ #endif
41
49
 
42
- /* ffi_prep_args is called by the assembly routine once stack space
43
- has been allocated for the function's arguments */
50
+ #if defined(__GNUC__) && !defined(__declspec)
51
+ # define __declspec(x) __attribute__((x))
52
+ #endif
44
53
 
45
- void ffi_prep_args(char *stack, extended_cif *ecif)
54
+ /* Perform machine dependent cif processing. */
55
+ ffi_status FFI_HIDDEN
56
+ ffi_prep_cif_machdep(ffi_cif *cif)
46
57
  {
47
- register unsigned int i;
48
- register void **p_argv;
49
- register char *argp;
50
- register ffi_type **p_arg;
58
+ size_t bytes = 0;
59
+ int i, n, flags, cabi = cif->abi;
51
60
 
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)
58
- #endif
59
- )
61
+ switch (cabi)
60
62
  {
61
- *(void **) argp = ecif->rvalue;
62
- argp += sizeof(void*);
63
+ case FFI_SYSV:
64
+ case FFI_STDCALL:
65
+ case FFI_THISCALL:
66
+ case FFI_FASTCALL:
67
+ case FFI_MS_CDECL:
68
+ case FFI_PASCAL:
69
+ case FFI_REGISTER:
70
+ break;
71
+ default:
72
+ return FFI_BAD_ABI;
63
73
  }
64
74
 
65
- p_argv = ecif->avalue;
66
-
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)
84
- #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);
140
- #else
141
- argp += z;
142
- #endif
143
- }
144
-
145
- return;
146
- }
147
-
148
- /* Perform machine dependent cif processing */
149
- ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
150
- {
151
- unsigned int i;
152
- ffi_type **ptr;
153
-
154
- /* Set the return type flag */
155
75
  switch (cif->rtype->type)
156
76
  {
157
77
  case FFI_TYPE_VOID:
78
+ flags = X86_RET_VOID;
79
+ break;
80
+ case FFI_TYPE_FLOAT:
81
+ flags = X86_RET_FLOAT;
82
+ break;
83
+ case FFI_TYPE_DOUBLE:
84
+ flags = X86_RET_DOUBLE;
85
+ break;
86
+ case FFI_TYPE_LONGDOUBLE:
87
+ flags = X86_RET_LDOUBLE;
88
+ break;
158
89
  case FFI_TYPE_UINT8:
90
+ flags = X86_RET_UINT8;
91
+ break;
159
92
  case FFI_TYPE_UINT16:
93
+ flags = X86_RET_UINT16;
94
+ break;
160
95
  case FFI_TYPE_SINT8:
96
+ flags = X86_RET_SINT8;
97
+ break;
161
98
  case FFI_TYPE_SINT16:
162
- #ifdef X86_WIN64
163
- case FFI_TYPE_UINT32:
99
+ flags = X86_RET_SINT16;
100
+ break;
101
+ case FFI_TYPE_INT:
164
102
  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;
103
+ case FFI_TYPE_UINT32:
104
+ case FFI_TYPE_POINTER:
105
+ flags = X86_RET_INT32;
175
106
  break;
176
-
107
+ case FFI_TYPE_SINT64:
177
108
  case FFI_TYPE_UINT64:
178
- #ifdef X86_WIN64
179
- case FFI_TYPE_POINTER:
180
- #endif
181
- cif->flags = FFI_TYPE_SINT64;
109
+ flags = X86_RET_INT64;
182
110
  break;
183
-
184
111
  case FFI_TYPE_STRUCT:
185
112
  #ifndef X86
113
+ /* ??? This should be a different ABI rather than an ifdef. */
186
114
  if (cif->rtype->size == 1)
187
- {
188
- cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
189
- }
115
+ flags = X86_RET_STRUCT_1B;
190
116
  else if (cif->rtype->size == 2)
191
- {
192
- cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
193
- }
117
+ flags = X86_RET_STRUCT_2B;
194
118
  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
- }
119
+ flags = X86_RET_INT32;
202
120
  else if (cif->rtype->size == 8)
203
- {
204
- cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
205
- }
121
+ flags = X86_RET_INT64;
206
122
  else
207
123
  #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
- }
124
+ {
125
+ do_struct:
126
+ switch (cabi)
127
+ {
128
+ case FFI_THISCALL:
129
+ case FFI_FASTCALL:
130
+ case FFI_STDCALL:
131
+ case FFI_MS_CDECL:
132
+ flags = X86_RET_STRUCTARG;
133
+ break;
134
+ default:
135
+ flags = X86_RET_STRUCTPOP;
136
+ break;
137
+ }
138
+ /* Allocate space for return value pointer. */
139
+ bytes += FFI_ALIGN (sizeof(void*), FFI_SIZEOF_ARG);
140
+ }
213
141
  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
142
+ case FFI_TYPE_COMPLEX:
143
+ switch (cif->rtype->elements[0]->type)
144
+ {
145
+ case FFI_TYPE_DOUBLE:
146
+ case FFI_TYPE_LONGDOUBLE:
147
+ case FFI_TYPE_SINT64:
148
+ case FFI_TYPE_UINT64:
149
+ goto do_struct;
150
+ case FFI_TYPE_FLOAT:
151
+ case FFI_TYPE_INT:
152
+ case FFI_TYPE_SINT32:
153
+ case FFI_TYPE_UINT32:
154
+ flags = X86_RET_INT64;
155
+ break;
156
+ case FFI_TYPE_SINT16:
157
+ case FFI_TYPE_UINT16:
158
+ flags = X86_RET_INT32;
159
+ break;
160
+ case FFI_TYPE_SINT8:
161
+ case FFI_TYPE_UINT8:
162
+ flags = X86_RET_STRUCT_2B;
163
+ break;
164
+ default:
165
+ return FFI_BAD_TYPEDEF;
166
+ }
224
167
  break;
168
+ default:
169
+ return FFI_BAD_TYPEDEF;
225
170
  }
171
+ cif->flags = flags;
226
172
 
227
- for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
173
+ for (i = 0, n = cif->nargs; i < n; i++)
228
174
  {
229
- if (((*ptr)->alignment - 1) & cif->bytes)
230
- cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
231
- cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
175
+ ffi_type *t = cif->arg_types[i];
176
+
177
+ bytes = FFI_ALIGN (bytes, t->alignment);
178
+ bytes += FFI_ALIGN (t->size, FFI_SIZEOF_ARG);
232
179
  }
180
+ cif->bytes = FFI_ALIGN (bytes, 16);
233
181
 
234
- #ifdef X86_WIN64
235
- /* ensure space for storing four registers */
236
- cif->bytes += 4 * sizeof(ffi_arg);
237
- #endif
182
+ return FFI_OK;
183
+ }
238
184
 
239
- #ifdef X86_DARWIN
240
- cif->bytes = (cif->bytes + 15) & ~0xF;
241
- #endif
185
+ static ffi_arg
186
+ extend_basic_type(void *arg, int type)
187
+ {
188
+ switch (type)
189
+ {
190
+ case FFI_TYPE_SINT8:
191
+ return *(SINT8 *)arg;
192
+ case FFI_TYPE_UINT8:
193
+ return *(UINT8 *)arg;
194
+ case FFI_TYPE_SINT16:
195
+ return *(SINT16 *)arg;
196
+ case FFI_TYPE_UINT16:
197
+ return *(UINT16 *)arg;
242
198
 
243
- return FFI_OK;
199
+ case FFI_TYPE_SINT32:
200
+ case FFI_TYPE_UINT32:
201
+ case FFI_TYPE_POINTER:
202
+ case FFI_TYPE_FLOAT:
203
+ return *(UINT32 *)arg;
204
+
205
+ default:
206
+ abort();
207
+ }
244
208
  }
245
209
 
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));
210
+ struct call_frame
211
+ {
212
+ void *ebp; /* 0 */
213
+ void *retaddr; /* 4 */
214
+ void (*fn)(void); /* 8 */
215
+ int flags; /* 12 */
216
+ void *rvalue; /* 16 */
217
+ unsigned regs[3]; /* 20-28 */
218
+ };
219
+
220
+ struct abi_params
221
+ {
222
+ int dir; /* parameter growth direction */
223
+ int static_chain; /* the static chain register used by gcc */
224
+ int nregs; /* number of register parameters */
225
+ int regs[3];
226
+ };
227
+
228
+ static const struct abi_params abi_params[FFI_LAST_ABI] = {
229
+ [FFI_SYSV] = { 1, R_ECX, 0 },
230
+ [FFI_THISCALL] = { 1, R_EAX, 1, { R_ECX } },
231
+ [FFI_FASTCALL] = { 1, R_EAX, 2, { R_ECX, R_EDX } },
232
+ [FFI_STDCALL] = { 1, R_ECX, 0 },
233
+ [FFI_PASCAL] = { -1, R_ECX, 0 },
234
+ /* ??? No defined static chain; gcc does not support REGISTER. */
235
+ [FFI_REGISTER] = { -1, R_ECX, 3, { R_EAX, R_EDX, R_ECX } },
236
+ [FFI_MS_CDECL] = { 1, R_ECX, 0 }
237
+ };
238
+
239
+ #ifdef HAVE_FASTCALL
240
+ #ifdef _MSC_VER
241
+ #define FFI_DECLARE_FASTCALL __fastcall
242
+ #else
243
+ #define FFI_DECLARE_FASTCALL __declspec(fastcall)
244
+ #endif
254
245
  #else
255
- extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
256
- unsigned, unsigned, unsigned *, void (*fn)(void));
246
+ #define FFI_DECLARE_FASTCALL
257
247
  #endif
258
248
 
259
- void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
249
+ extern void FFI_DECLARE_FASTCALL ffi_call_i386(struct call_frame *, char *) FFI_HIDDEN;
250
+
251
+ static void
252
+ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
253
+ void **avalue, void *closure)
260
254
  {
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)
255
+ size_t rsize, bytes;
256
+ struct call_frame *frame;
257
+ char *stack, *argp;
258
+ ffi_type **arg_types;
259
+ int flags, cabi, i, n, dir, narg_reg;
260
+ const struct abi_params *pabi;
261
+
262
+ flags = cif->flags;
263
+ cabi = cif->abi;
264
+ pabi = &abi_params[cabi];
265
+ dir = pabi->dir;
266
+
267
+ rsize = 0;
268
+ if (rvalue == NULL)
274
269
  {
275
- ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
270
+ switch (flags)
271
+ {
272
+ case X86_RET_FLOAT:
273
+ case X86_RET_DOUBLE:
274
+ case X86_RET_LDOUBLE:
275
+ case X86_RET_STRUCTPOP:
276
+ case X86_RET_STRUCTARG:
277
+ /* The float cases need to pop the 387 stack.
278
+ The struct cases need to pass a valid pointer to the callee. */
279
+ rsize = cif->rtype->size;
280
+ break;
281
+ default:
282
+ /* We can pretend that the callee returns nothing. */
283
+ flags = X86_RET_VOID;
284
+ break;
285
+ }
276
286
  }
277
- #else
278
- if (rvalue == NULL
279
- && cif->flags == FFI_TYPE_STRUCT)
280
- {
281
- ecif.rvalue = alloca(cif->rtype->size);
282
- }
283
- #endif
284
- else
285
- ecif.rvalue = rvalue;
286
-
287
-
288
- switch (cif->abi)
287
+
288
+ bytes = cif->bytes;
289
+ stack = alloca(bytes + sizeof(*frame) + rsize);
290
+ argp = (dir < 0 ? stack + bytes : stack);
291
+ frame = (struct call_frame *)(stack + bytes);
292
+ if (rsize)
293
+ rvalue = frame + 1;
294
+
295
+ frame->fn = fn;
296
+ frame->flags = flags;
297
+ frame->rvalue = rvalue;
298
+ frame->regs[pabi->static_chain] = (unsigned)closure;
299
+
300
+ narg_reg = 0;
301
+ switch (flags)
289
302
  {
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);
303
+ case X86_RET_STRUCTARG:
304
+ /* The pointer is passed as the first argument. */
305
+ if (pabi->nregs > 0)
306
+ {
307
+ frame->regs[pabi->regs[0]] = (unsigned)rvalue;
308
+ narg_reg = 1;
309
+ break;
310
+ }
311
+ /* fallthru */
312
+ case X86_RET_STRUCTPOP:
313
+ *(void **)argp = rvalue;
314
+ argp += sizeof(void *);
309
315
  break;
310
316
  }
311
- }
312
-
313
317
 
314
- /** private members **/
318
+ arg_types = cif->arg_types;
319
+ for (i = 0, n = cif->nargs; i < n; i++)
320
+ {
321
+ ffi_type *ty = arg_types[i];
322
+ void *valp = avalue[i];
323
+ size_t z = ty->size;
324
+ int t = ty->type;
315
325
 
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
326
+ if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
327
+ {
328
+ ffi_arg val = extend_basic_type (valp, t);
329
+
330
+ if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
331
+ frame->regs[pabi->regs[narg_reg++]] = val;
332
+ else if (dir < 0)
333
+ {
334
+ argp -= 4;
335
+ *(ffi_arg *)argp = val;
336
+ }
337
+ else
338
+ {
339
+ *(ffi_arg *)argp = val;
340
+ argp += 4;
341
+ }
342
+ }
343
+ else
344
+ {
345
+ size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
346
+ size_t align = FFI_SIZEOF_ARG;
347
+
348
+ /* Alignment rules for arguments are quite complex. Vectors and
349
+ structures with 16 byte alignment get it. Note that long double
350
+ on Darwin does have 16 byte alignment, and does not get this
351
+ alignment if passed directly; a structure with a long double
352
+ inside, however, would get 16 byte alignment. Since libffi does
353
+ not support vectors, we need non concern ourselves with other
354
+ cases. */
355
+ if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
356
+ align = 16;
357
+
358
+ if (dir < 0)
359
+ {
360
+ /* ??? These reverse argument ABIs are probably too old
361
+ to have cared about alignment. Someone should check. */
362
+ argp -= za;
363
+ memcpy (argp, valp, z);
364
+ }
365
+ else
366
+ {
367
+ argp = (char *)FFI_ALIGN (argp, align);
368
+ memcpy (argp, valp, z);
369
+ argp += za;
370
+ }
371
+ }
372
+ }
373
+ FFI_ASSERT (dir > 0 || argp == stack);
333
374
 
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;
375
+ ffi_call_i386 (frame, stack);
363
376
  }
364
377
 
365
- #else
366
- unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
367
- ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
378
+ void
379
+ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
368
380
  {
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;
381
+ ffi_call_int (cif, fn, rvalue, avalue, NULL);
387
382
  }
388
- #endif /* !X86_WIN64 */
389
383
 
390
- static void
391
- ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
392
- ffi_cif *cif)
384
+ void
385
+ ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
386
+ void **avalue, void *closure)
393
387
  {
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
- }
414
- #endif
388
+ ffi_call_int (cif, fn, rvalue, avalue, closure);
389
+ }
390
+
391
+ /** private members **/
415
392
 
416
- p_argv = avalue;
393
+ void FFI_HIDDEN ffi_closure_i386(void);
394
+ void FFI_HIDDEN ffi_closure_STDCALL(void);
395
+ void FFI_HIDDEN ffi_closure_REGISTER(void);
417
396
 
418
- for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
397
+ struct closure_frame
398
+ {
399
+ unsigned rettemp[4]; /* 0 */
400
+ unsigned regs[3]; /* 16-24 */
401
+ ffi_cif *cif; /* 28 */
402
+ void (*fun)(ffi_cif*,void*,void**,void*); /* 32 */
403
+ void *user_data; /* 36 */
404
+ };
405
+
406
+ int FFI_HIDDEN FFI_DECLARE_FASTCALL
407
+ ffi_closure_inner (struct closure_frame *frame, char *stack)
408
+ {
409
+ ffi_cif *cif = frame->cif;
410
+ int cabi, i, n, flags, dir, narg_reg;
411
+ const struct abi_params *pabi;
412
+ ffi_type **arg_types;
413
+ char *argp;
414
+ void *rvalue;
415
+ void **avalue;
416
+
417
+ cabi = cif->abi;
418
+ flags = cif->flags;
419
+ narg_reg = 0;
420
+ rvalue = frame->rettemp;
421
+ pabi = &abi_params[cabi];
422
+ dir = pabi->dir;
423
+ argp = (dir < 0 ? stack + cif->bytes : stack);
424
+
425
+ switch (flags)
419
426
  {
420
- size_t z;
427
+ case X86_RET_STRUCTARG:
428
+ if (pabi->nregs > 0)
429
+ {
430
+ rvalue = (void *)frame->regs[pabi->regs[0]];
431
+ narg_reg = 1;
432
+ frame->rettemp[0] = (unsigned)rvalue;
433
+ break;
434
+ }
435
+ /* fallthru */
436
+ case X86_RET_STRUCTPOP:
437
+ rvalue = *(void **)argp;
438
+ argp += sizeof(void *);
439
+ frame->rettemp[0] = (unsigned)rvalue;
440
+ break;
441
+ }
421
442
 
422
- /* Align if necessary */
423
- if ((sizeof(void*) - 1) & (size_t) argp) {
424
- argp = (char *) ALIGN(argp, sizeof(void*));
425
- }
443
+ n = cif->nargs;
444
+ avalue = alloca(sizeof(void *) * n);
426
445
 
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
- }
446
+ arg_types = cif->arg_types;
447
+ for (i = 0; i < n; ++i)
448
+ {
449
+ ffi_type *ty = arg_types[i];
450
+ size_t z = ty->size;
451
+ int t = ty->type;
452
+ void *valp;
453
+
454
+ if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
455
+ {
456
+ if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
457
+ valp = &frame->regs[pabi->regs[narg_reg++]];
458
+ else if (dir < 0)
459
+ {
460
+ argp -= 4;
461
+ valp = argp;
462
+ }
463
+ else
464
+ {
465
+ valp = argp;
466
+ argp += 4;
467
+ }
468
+ }
436
469
  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
470
+ {
471
+ size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
472
+ size_t align = FFI_SIZEOF_ARG;
473
+
474
+ /* See the comment in ffi_call_int. */
475
+ if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
476
+ align = 16;
477
+
478
+ if (dir < 0)
479
+ {
480
+ /* ??? These reverse argument ABIs are probably too old
481
+ to have cared about alignment. Someone should check. */
482
+ argp -= za;
483
+ valp = argp;
484
+ }
485
+ else
486
+ {
487
+ argp = (char *)FFI_ALIGN (argp, align);
488
+ valp = argp;
489
+ argp += za;
490
+ }
491
+ }
492
+
493
+ avalue[i] = valp;
452
494
  }
453
-
454
- return;
455
- }
456
495
 
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 */
496
+ frame->fun (cif, rvalue, avalue, frame->user_data);
497
+
498
+ if (cabi == FFI_STDCALL)
499
+ return flags + (cif->bytes << X86_RET_POP_SHIFT);
500
+ else
501
+ return flags;
502
+ }
503
503
 
504
504
  ffi_status
505
505
  ffi_prep_closure_loc (ffi_closure* closure,
@@ -508,41 +508,76 @@ ffi_prep_closure_loc (ffi_closure* closure,
508
508
  void *user_data,
509
509
  void *codeloc)
510
510
  {
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)
511
+ char *tramp = closure->tramp;
512
+ void (*dest)(void);
513
+ int op = 0xb8; /* movl imm, %eax */
514
+
515
+ switch (cif->abi)
531
516
  {
532
- FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
533
- &ffi_closure_STDCALL,
534
- (void*)codeloc, cif->bytes);
517
+ case FFI_SYSV:
518
+ case FFI_THISCALL:
519
+ case FFI_FASTCALL:
520
+ case FFI_MS_CDECL:
521
+ dest = ffi_closure_i386;
522
+ break;
523
+ case FFI_STDCALL:
524
+ case FFI_PASCAL:
525
+ dest = ffi_closure_STDCALL;
526
+ break;
527
+ case FFI_REGISTER:
528
+ dest = ffi_closure_REGISTER;
529
+ op = 0x68; /* pushl imm */
530
+ default:
531
+ return FFI_BAD_ABI;
535
532
  }
536
- #endif /* X86_WIN32 */
537
- #endif /* !X86_WIN64 */
538
- else
533
+
534
+ /* movl or pushl immediate. */
535
+ tramp[0] = op;
536
+ *(void **)(tramp + 1) = codeloc;
537
+
538
+ /* jmp dest */
539
+ tramp[5] = 0xe9;
540
+ *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
541
+
542
+ closure->cif = cif;
543
+ closure->fun = fun;
544
+ closure->user_data = user_data;
545
+
546
+ return FFI_OK;
547
+ }
548
+
549
+ void FFI_HIDDEN ffi_go_closure_EAX(void);
550
+ void FFI_HIDDEN ffi_go_closure_ECX(void);
551
+ void FFI_HIDDEN ffi_go_closure_STDCALL(void);
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
+ void (*dest)(void);
558
+
559
+ switch (cif->abi)
539
560
  {
561
+ case FFI_SYSV:
562
+ case FFI_MS_CDECL:
563
+ dest = ffi_go_closure_ECX;
564
+ break;
565
+ case FFI_THISCALL:
566
+ case FFI_FASTCALL:
567
+ dest = ffi_go_closure_EAX;
568
+ break;
569
+ case FFI_STDCALL:
570
+ case FFI_PASCAL:
571
+ dest = ffi_go_closure_STDCALL;
572
+ break;
573
+ case FFI_REGISTER:
574
+ default:
540
575
  return FFI_BAD_ABI;
541
576
  }
542
-
543
- closure->cif = cif;
544
- closure->user_data = user_data;
545
- closure->fun = fun;
577
+
578
+ closure->tramp = dest;
579
+ closure->cif = cif;
580
+ closure->fun = fun;
546
581
 
547
582
  return FFI_OK;
548
583
  }
@@ -551,94 +586,150 @@ ffi_prep_closure_loc (ffi_closure* closure,
551
586
 
552
587
  #if !FFI_NO_RAW_API
553
588
 
589
+ void FFI_HIDDEN ffi_closure_raw_SYSV(void);
590
+ void FFI_HIDDEN ffi_closure_raw_THISCALL(void);
591
+
554
592
  ffi_status
555
- ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
556
- ffi_cif* cif,
593
+ ffi_prep_raw_closure_loc (ffi_raw_closure *closure,
594
+ ffi_cif *cif,
557
595
  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
558
596
  void *user_data,
559
597
  void *codeloc)
560
598
  {
599
+ char *tramp = closure->tramp;
600
+ void (*dest)(void);
561
601
  int i;
562
602
 
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
603
+ /* We currently don't support certain kinds of arguments for raw
568
604
  closures. This should be implemented by a separate assembly
569
605
  language routine, since it would require argument processing,
570
606
  something we don't do now for performance. */
571
-
572
607
  for (i = cif->nargs-1; i >= 0; i--)
608
+ switch (cif->arg_types[i]->type)
609
+ {
610
+ case FFI_TYPE_STRUCT:
611
+ case FFI_TYPE_LONGDOUBLE:
612
+ return FFI_BAD_TYPEDEF;
613
+ }
614
+
615
+ switch (cif->abi)
573
616
  {
574
- FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
575
- FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
617
+ case FFI_THISCALL:
618
+ dest = ffi_closure_raw_THISCALL;
619
+ break;
620
+ case FFI_SYSV:
621
+ dest = ffi_closure_raw_SYSV;
622
+ break;
623
+ default:
624
+ return FFI_BAD_ABI;
576
625
  }
577
-
578
626
 
579
- FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
580
- codeloc);
581
-
582
- closure->cif = cif;
627
+ /* movl imm, %eax. */
628
+ tramp[0] = 0xb8;
629
+ *(void **)(tramp + 1) = codeloc;
630
+
631
+ /* jmp dest */
632
+ tramp[5] = 0xe9;
633
+ *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
634
+
635
+ closure->cif = cif;
636
+ closure->fun = fun;
583
637
  closure->user_data = user_data;
584
- closure->fun = fun;
585
638
 
586
639
  return FFI_OK;
587
640
  }
588
641
 
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
642
  void
601
- ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
643
+ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
602
644
  {
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))
645
+ size_t rsize, bytes;
646
+ struct call_frame *frame;
647
+ char *stack, *argp;
648
+ ffi_type **arg_types;
649
+ int flags, cabi, i, n, narg_reg;
650
+ const struct abi_params *pabi;
651
+
652
+ flags = cif->flags;
653
+ cabi = cif->abi;
654
+ pabi = &abi_params[cabi];
655
+
656
+ rsize = 0;
657
+ if (rvalue == NULL)
614
658
  {
615
- ecif.rvalue = alloca(cif->rtype->size);
659
+ switch (flags)
660
+ {
661
+ case X86_RET_FLOAT:
662
+ case X86_RET_DOUBLE:
663
+ case X86_RET_LDOUBLE:
664
+ case X86_RET_STRUCTPOP:
665
+ case X86_RET_STRUCTARG:
666
+ /* The float cases need to pop the 387 stack.
667
+ The struct cases need to pass a valid pointer to the callee. */
668
+ rsize = cif->rtype->size;
669
+ break;
670
+ default:
671
+ /* We can pretend that the callee returns nothing. */
672
+ flags = X86_RET_VOID;
673
+ break;
674
+ }
616
675
  }
617
- else
618
- ecif.rvalue = rvalue;
619
-
620
-
621
- switch (cif->abi)
676
+
677
+ bytes = cif->bytes;
678
+ argp = stack =
679
+ (void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);
680
+ frame = (struct call_frame *)(stack + bytes);
681
+ if (rsize)
682
+ rvalue = frame + 1;
683
+
684
+ frame->fn = fn;
685
+ frame->flags = flags;
686
+ frame->rvalue = rvalue;
687
+
688
+ narg_reg = 0;
689
+ switch (flags)
622
690
  {
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);
691
+ case X86_RET_STRUCTARG:
692
+ /* The pointer is passed as the first argument. */
693
+ if (pabi->nregs > 0)
694
+ {
695
+ frame->regs[pabi->regs[0]] = (unsigned)rvalue;
696
+ narg_reg = 1;
697
+ break;
698
+ }
699
+ /* fallthru */
700
+ case X86_RET_STRUCTPOP:
701
+ *(void **)argp = rvalue;
702
+ argp += sizeof(void *);
703
+ bytes -= sizeof(void *);
637
704
  break;
638
705
  }
639
- }
640
706
 
641
- #endif
642
-
643
- #endif /* !__x86_64__ || X86_WIN64 */
707
+ arg_types = cif->arg_types;
708
+ for (i = 0, n = cif->nargs; narg_reg < pabi->nregs && i < n; i++)
709
+ {
710
+ ffi_type *ty = arg_types[i];
711
+ size_t z = ty->size;
712
+ int t = ty->type;
713
+
714
+ if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT && t != FFI_TYPE_FLOAT)
715
+ {
716
+ ffi_arg val = extend_basic_type (avalue, t);
717
+ frame->regs[pabi->regs[narg_reg++]] = val;
718
+ z = FFI_SIZEOF_ARG;
719
+ }
720
+ else
721
+ {
722
+ memcpy (argp, avalue, z);
723
+ z = FFI_ALIGN (z, FFI_SIZEOF_ARG);
724
+ argp += z;
725
+ }
726
+ avalue += z;
727
+ bytes -= z;
728
+ }
729
+ if (i < n)
730
+ memcpy (argp, avalue, bytes);
644
731
 
732
+ ffi_call_i386 (frame, stack);
733
+ }
734
+ #endif /* !FFI_NO_RAW_API */
735
+ #endif /* !__x86_64__ */