ffi 1.9.18-x86-mingw32 → 1.9.21-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ffi might be problematic. Click here for more details.

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