ffi 1.9.18 → 1.9.21

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 (366) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/Rakefile +14 -3
  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/README +164 -52
  17. data/ext/ffi_c/libffi/acinclude.m4 +381 -0
  18. data/ext/ffi_c/libffi/autogen.sh +2 -0
  19. data/ext/ffi_c/libffi/configure.ac +148 -256
  20. data/ext/ffi_c/libffi/configure.host +265 -4
  21. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  22. data/ext/ffi_c/libffi/doc/libffi.texi +430 -45
  23. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  24. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +207 -0
  25. data/ext/ffi_c/libffi/include/Makefile.am +3 -3
  26. data/ext/ffi_c/libffi/include/ffi.h.in +107 -50
  27. data/ext/ffi_c/libffi/include/ffi_cfi.h +55 -0
  28. data/ext/ffi_c/libffi/include/ffi_common.h +32 -11
  29. data/ext/ffi_c/libffi/libffi.map.in +80 -0
  30. data/ext/ffi_c/libffi/libffi.pc.in +3 -2
  31. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +637 -0
  32. data/ext/ffi_c/libffi/libtool-ldflags +106 -0
  33. data/ext/ffi_c/libffi/libtool-version +1 -1
  34. data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
  35. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +69 -0
  36. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +13 -8
  37. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +31 -104
  38. data/ext/ffi_c/libffi/m4/{ax_check_compiler_flags.m4 → ax_check_compile_flag.m4} +30 -34
  39. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +32 -11
  40. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +6 -5
  41. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +31 -21
  42. data/ext/ffi_c/libffi/man/Makefile.am +2 -2
  43. data/ext/ffi_c/libffi/man/ffi.3 +10 -0
  44. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +6 -4
  45. data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +73 -0
  46. data/ext/ffi_c/libffi/msvcc.sh +72 -9
  47. data/ext/ffi_c/libffi/src/aarch64/ffi.c +941 -0
  48. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +81 -0
  49. data/ext/ffi_c/libffi/src/aarch64/internal.h +67 -0
  50. data/ext/ffi_c/libffi/src/aarch64/sysv.S +438 -0
  51. data/ext/ffi_c/libffi/src/alpha/ffi.c +335 -98
  52. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +10 -1
  53. data/ext/ffi_c/libffi/src/alpha/internal.h +23 -0
  54. data/ext/ffi_c/libffi/src/alpha/osf.S +161 -266
  55. data/ext/ffi_c/libffi/src/arc/arcompact.S +135 -0
  56. data/ext/ffi_c/libffi/src/arc/ffi.c +266 -0
  57. data/ext/ffi_c/libffi/src/arc/ffitarget.h +53 -0
  58. data/ext/ffi_c/libffi/src/arm/ffi.c +597 -517
  59. data/ext/ffi_c/libffi/src/arm/ffitarget.h +24 -7
  60. data/ext/ffi_c/libffi/src/arm/internal.h +7 -0
  61. data/ext/ffi_c/libffi/src/arm/sysv.S +303 -417
  62. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +6 -1
  63. data/ext/ffi_c/libffi/src/bfin/ffi.c +196 -0
  64. data/ext/ffi_c/libffi/src/bfin/ffitarget.h +43 -0
  65. data/ext/ffi_c/libffi/src/bfin/sysv.S +179 -0
  66. data/ext/ffi_c/libffi/src/closures.c +319 -44
  67. data/ext/ffi_c/libffi/src/cris/ffi.c +10 -7
  68. data/ext/ffi_c/libffi/src/cris/ffitarget.h +6 -1
  69. data/ext/ffi_c/libffi/src/debug.c +6 -1
  70. data/ext/ffi_c/libffi/src/dlmalloc.c +16 -11
  71. data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
  72. data/ext/ffi_c/libffi/src/frv/ffitarget.h +6 -1
  73. data/ext/ffi_c/libffi/src/ia64/ffi.c +11 -7
  74. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +6 -1
  75. data/ext/ffi_c/libffi/src/java_raw_api.c +23 -5
  76. data/ext/ffi_c/libffi/src/m32r/ffi.c +1 -1
  77. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +6 -1
  78. data/ext/ffi_c/libffi/src/m68k/ffi.c +87 -13
  79. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +6 -1
  80. data/ext/ffi_c/libffi/src/m68k/sysv.S +119 -32
  81. data/ext/ffi_c/libffi/src/m88k/ffi.c +400 -0
  82. data/ext/ffi_c/libffi/src/m88k/ffitarget.h +49 -0
  83. data/ext/ffi_c/libffi/src/m88k/obsd.S +209 -0
  84. data/ext/ffi_c/libffi/src/metag/ffi.c +330 -0
  85. data/ext/ffi_c/libffi/{fficonfig.hw → src/metag/ffitarget.h} +22 -26
  86. data/ext/ffi_c/libffi/src/metag/sysv.S +311 -0
  87. data/ext/ffi_c/libffi/src/microblaze/ffi.c +321 -0
  88. data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +53 -0
  89. data/ext/ffi_c/libffi/src/microblaze/sysv.S +302 -0
  90. data/ext/ffi_c/libffi/src/mips/ffi.c +95 -28
  91. data/ext/ffi_c/libffi/src/mips/ffitarget.h +9 -2
  92. data/ext/ffi_c/libffi/src/mips/n32.S +126 -56
  93. data/ext/ffi_c/libffi/src/mips/o32.S +148 -27
  94. data/ext/ffi_c/libffi/src/moxie/eabi.S +55 -82
  95. data/ext/ffi_c/libffi/src/moxie/ffi.c +40 -44
  96. data/ext/ffi_c/libffi/src/moxie/ffitarget.h +52 -0
  97. data/ext/ffi_c/libffi/src/nios2/ffi.c +304 -0
  98. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +52 -0
  99. data/ext/ffi_c/libffi/src/nios2/sysv.S +136 -0
  100. data/ext/ffi_c/libffi/src/or1k/ffi.c +328 -0
  101. data/ext/ffi_c/libffi/src/or1k/ffitarget.h +58 -0
  102. data/ext/ffi_c/libffi/src/or1k/sysv.S +107 -0
  103. data/ext/ffi_c/libffi/src/pa/ffitarget.h +8 -1
  104. data/ext/ffi_c/libffi/src/powerpc/aix.S +6 -6
  105. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +3 -1
  106. data/ext/ffi_c/libffi/src/powerpc/asm.h +2 -2
  107. data/ext/ffi_c/libffi/src/powerpc/darwin.S +2 -7
  108. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +22 -26
  109. data/ext/ffi_c/libffi/src/powerpc/ffi.c +103 -1378
  110. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +25 -25
  111. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +945 -0
  112. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +94 -0
  113. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
  114. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +100 -44
  115. data/ext/ffi_c/libffi/src/powerpc/linux64.S +100 -59
  116. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +360 -108
  117. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +138 -68
  118. data/ext/ffi_c/libffi/src/powerpc/sysv.S +68 -112
  119. data/ext/ffi_c/libffi/src/prep_cif.c +108 -24
  120. data/ext/ffi_c/libffi/src/raw_api.c +18 -5
  121. data/ext/ffi_c/libffi/src/s390/ffi.c +294 -318
  122. data/ext/ffi_c/libffi/src/s390/ffitarget.h +9 -1
  123. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  124. data/ext/ffi_c/libffi/src/s390/sysv.S +257 -366
  125. data/ext/ffi_c/libffi/src/sh/ffi.c +4 -3
  126. data/ext/ffi_c/libffi/src/sh/ffitarget.h +6 -1
  127. data/ext/ffi_c/libffi/src/sh64/ffi.c +3 -2
  128. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +6 -1
  129. data/ext/ffi_c/libffi/src/sparc/ffi.c +326 -527
  130. data/ext/ffi_c/libffi/src/sparc/ffi64.c +608 -0
  131. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +20 -7
  132. data/ext/ffi_c/libffi/src/sparc/internal.h +26 -0
  133. data/ext/ffi_c/libffi/src/sparc/v8.S +364 -234
  134. data/ext/ffi_c/libffi/src/sparc/v9.S +340 -207
  135. data/ext/ffi_c/libffi/src/tile/ffi.c +355 -0
  136. data/ext/ffi_c/libffi/src/tile/ffitarget.h +65 -0
  137. data/ext/ffi_c/libffi/src/tile/tile.S +360 -0
  138. data/ext/ffi_c/libffi/src/types.c +43 -14
  139. data/ext/ffi_c/libffi/src/vax/elfbsd.S +195 -0
  140. data/ext/ffi_c/libffi/src/vax/ffi.c +276 -0
  141. data/ext/ffi_c/libffi/src/vax/ffitarget.h +49 -0
  142. data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
  143. data/ext/ffi_c/libffi/src/x86/ffi.c +589 -500
  144. data/ext/ffi_c/libffi/src/x86/ffi64.c +338 -116
  145. data/ext/ffi_c/libffi/src/x86/ffitarget.h +55 -35
  146. data/ext/ffi_c/libffi/src/x86/ffiw64.c +287 -0
  147. data/ext/ffi_c/libffi/src/x86/internal.h +29 -0
  148. data/ext/ffi_c/libffi/src/x86/internal64.h +22 -0
  149. data/ext/ffi_c/libffi/src/x86/sysv.S +975 -400
  150. data/ext/ffi_c/libffi/src/x86/unix64.S +398 -299
  151. data/ext/ffi_c/libffi/src/x86/win64.S +222 -458
  152. data/ext/ffi_c/libffi/src/x86/win64_intel.S +237 -0
  153. data/ext/ffi_c/libffi/src/xtensa/ffi.c +298 -0
  154. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +53 -0
  155. data/ext/ffi_c/libffi/src/xtensa/sysv.S +253 -0
  156. data/ext/ffi_c/libffi/stamp-h.in +1 -0
  157. data/ext/ffi_c/libffi/testsuite/Makefile.am +78 -73
  158. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +120 -25
  159. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +21 -1
  160. data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
  161. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +4 -6
  162. data/ext/ffi_c/libffi/testsuite/libffi.call/{closure_stdcall.c → closure_simple.c} +7 -16
  163. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +4 -4
  164. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +4 -4
  165. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +4 -4
  166. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +4 -4
  167. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +4 -4
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +4 -4
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +4 -4
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +5 -5
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +4 -4
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +4 -4
  173. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +4 -4
  174. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +4 -4
  175. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +4 -4
  176. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +4 -4
  177. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +4 -4
  178. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +4 -4
  179. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +5 -5
  180. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +4 -4
  181. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +4 -4
  182. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +4 -4
  183. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +4 -4
  184. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +4 -4
  185. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +4 -4
  186. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +4 -4
  187. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +4 -4
  188. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +4 -4
  189. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +4 -4
  190. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +4 -6
  191. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +4 -6
  192. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +4 -4
  193. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +4 -4
  194. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +4 -4
  195. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +4 -4
  196. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +4 -4
  197. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +4 -4
  198. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +4 -4
  199. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +4 -4
  200. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +10 -9
  201. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +3 -3
  202. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +10 -9
  203. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_args.c +70 -0
  204. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c +55 -0
  205. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +1 -1
  206. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +11 -9
  207. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_struct_va1.c +114 -0
  208. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar_va.c +44 -0
  209. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint_va.c +45 -0
  210. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulong_va.c +45 -0
  211. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +5 -5
  212. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort_va.c +44 -0
  213. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +2 -2
  214. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +23 -40
  215. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +3 -1
  216. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +6 -4
  217. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +4 -2
  218. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +107 -0
  219. data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +18 -19
  220. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +6 -16
  221. data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +57 -0
  222. data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +70 -0
  223. data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +78 -0
  224. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +0 -1
  225. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +6 -6
  226. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +8 -8
  227. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +6 -6
  228. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct11.c +121 -0
  229. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +5 -5
  230. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +5 -5
  231. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +5 -5
  232. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +5 -5
  233. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +6 -6
  234. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +5 -5
  235. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +6 -6
  236. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +6 -6
  237. data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +46 -0
  238. data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +127 -0
  239. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +1 -0
  240. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
  241. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +1 -1
  242. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +1 -1
  243. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +7 -7
  244. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +7 -7
  245. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +5 -5
  246. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +5 -5
  247. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +2 -2
  248. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +49 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +49 -0
  250. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +55 -0
  251. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +9 -7
  252. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +7 -7
  253. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +7 -6
  254. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +9 -8
  255. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +9 -8
  256. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +9 -9
  257. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +9 -9
  258. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +9 -8
  259. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +9 -8
  260. data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +2 -2
  261. data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
  262. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.call}/unwindtest.cc +3 -10
  263. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.call}/unwindtest_ffi_call.cc +2 -1
  264. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +196 -0
  265. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +121 -0
  266. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +123 -0
  267. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +125 -0
  268. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +91 -0
  269. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +10 -0
  270. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +10 -0
  271. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +10 -0
  272. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +42 -0
  273. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +10 -0
  274. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +10 -0
  275. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +10 -0
  276. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +71 -0
  277. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +10 -0
  278. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +10 -0
  279. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +10 -0
  280. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +80 -0
  281. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +10 -0
  282. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +16 -0
  283. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +10 -0
  284. data/ext/ffi_c/libffi/testsuite/{libffi.special/special.exp → libffi.complex/complex.exp} +9 -8
  285. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +51 -0
  286. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +7 -0
  287. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +7 -0
  288. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +7 -0
  289. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +10 -0
  290. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +10 -0
  291. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +86 -0
  292. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +10 -0
  293. data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +1 -0
  294. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +78 -0
  295. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +10 -0
  296. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +10 -0
  297. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +10 -0
  298. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +37 -0
  299. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +41 -0
  300. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +10 -0
  301. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +10 -0
  302. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +10 -0
  303. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +44 -0
  304. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +10 -0
  305. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +10 -0
  306. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +10 -0
  307. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +10 -0
  308. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +10 -0
  309. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +10 -0
  310. data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +34 -0
  311. data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +28 -0
  312. data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +1 -0
  313. data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +36 -0
  314. data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +19 -0
  315. data/ffi.gemspec +2 -2
  316. data/lib/ffi/enum.rb +124 -0
  317. data/lib/ffi/library.rb +65 -13
  318. data/lib/ffi/platform.rb +7 -2
  319. data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
  320. data/lib/ffi/platform/x86_64-windows/types.conf +113 -20
  321. data/lib/ffi/pointer.rb +1 -0
  322. data/lib/ffi/struct.rb +0 -2
  323. data/lib/ffi/version.rb +1 -1
  324. data/spec/ffi/bitmask_spec.rb +575 -0
  325. data/spec/ffi/fixtures/BitmaskTest.c +51 -0
  326. data/spec/ffi/rbx/memory_pointer_spec.rb +4 -0
  327. data/spec/ffi/struct_spec.rb +0 -4
  328. metadata +143 -51
  329. data/ext/ffi_c/libffi/Makefile.in +0 -1820
  330. data/ext/ffi_c/libffi/Makefile.vc +0 -141
  331. data/ext/ffi_c/libffi/Makefile.vc64 +0 -141
  332. data/ext/ffi_c/libffi/aclocal.m4 +0 -1873
  333. data/ext/ffi_c/libffi/build-ios.sh +0 -67
  334. data/ext/ffi_c/libffi/compile +0 -143
  335. data/ext/ffi_c/libffi/config.guess +0 -1501
  336. data/ext/ffi_c/libffi/config.sub +0 -1705
  337. data/ext/ffi_c/libffi/configure +0 -17191
  338. data/ext/ffi_c/libffi/depcomp +0 -630
  339. data/ext/ffi_c/libffi/doc/libffi.info +0 -593
  340. data/ext/ffi_c/libffi/doc/stamp-vti +0 -4
  341. data/ext/ffi_c/libffi/fficonfig.h.in +0 -199
  342. data/ext/ffi_c/libffi/include/Makefile.in +0 -487
  343. data/ext/ffi_c/libffi/include/ffi.h.vc +0 -427
  344. data/ext/ffi_c/libffi/include/ffi.h.vc64 +0 -427
  345. data/ext/ffi_c/libffi/install-sh +0 -520
  346. data/ext/ffi_c/libffi/ltmain.sh +0 -9636
  347. data/ext/ffi_c/libffi/m4/libtool.m4 +0 -7831
  348. data/ext/ffi_c/libffi/m4/ltoptions.m4 +0 -369
  349. data/ext/ffi_c/libffi/m4/ltsugar.m4 +0 -123
  350. data/ext/ffi_c/libffi/m4/ltversion.m4 +0 -23
  351. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +0 -98
  352. data/ext/ffi_c/libffi/man/Makefile.in +0 -466
  353. data/ext/ffi_c/libffi/mdate-sh +0 -201
  354. data/ext/ffi_c/libffi/missing +0 -376
  355. data/ext/ffi_c/libffi/src/arm/gentramp.sh +0 -118
  356. data/ext/ffi_c/libffi/src/arm/trampoline.S +0 -4450
  357. data/ext/ffi_c/libffi/src/x86/darwin.S +0 -444
  358. data/ext/ffi_c/libffi/src/x86/darwin64.S +0 -416
  359. data/ext/ffi_c/libffi/src/x86/freebsd.S +0 -458
  360. data/ext/ffi_c/libffi/src/x86/win32.S +0 -1065
  361. data/ext/ffi_c/libffi/testsuite/Makefile.in +0 -500
  362. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +0 -300
  363. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +0 -63
  364. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +0 -44
  365. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +0 -96
  366. data/ext/ffi_c/libffi/texinfo.tex +0 -7210
@@ -1,5 +1,5 @@
1
1
  /* -----------------------------------------------------------------------
2
- prep_cif.c - Copyright (c) 2011 Anthony Green
2
+ prep_cif.c - Copyright (c) 2011, 2012 Anthony Green
3
3
  Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
@@ -29,12 +29,12 @@
29
29
 
30
30
  /* Round up to FFI_SIZEOF_ARG. */
31
31
 
32
- #define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
32
+ #define STACK_ARG_SIZE(x) FFI_ALIGN(x, FFI_SIZEOF_ARG)
33
33
 
34
34
  /* Perform machine independent initialization of aggregate type
35
35
  specifications. */
36
36
 
37
- static ffi_status initialize_aggregate(ffi_type *arg)
37
+ static ffi_status initialize_aggregate(ffi_type *arg, size_t *offsets)
38
38
  {
39
39
  ffi_type **ptr;
40
40
 
@@ -52,13 +52,15 @@ static ffi_status initialize_aggregate(ffi_type *arg)
52
52
  while ((*ptr) != NULL)
53
53
  {
54
54
  if (UNLIKELY(((*ptr)->size == 0)
55
- && (initialize_aggregate((*ptr)) != FFI_OK)))
55
+ && (initialize_aggregate((*ptr), NULL) != FFI_OK)))
56
56
  return FFI_BAD_TYPEDEF;
57
57
 
58
58
  /* Perform a sanity check on the argument type */
59
59
  FFI_ASSERT_VALID_TYPE(*ptr);
60
60
 
61
- arg->size = ALIGN(arg->size, (*ptr)->alignment);
61
+ arg->size = FFI_ALIGN(arg->size, (*ptr)->alignment);
62
+ if (offsets)
63
+ *offsets++ = arg->size;
62
64
  arg->size += (*ptr)->size;
63
65
 
64
66
  arg->alignment = (arg->alignment > (*ptr)->alignment) ?
@@ -74,7 +76,14 @@ static ffi_status initialize_aggregate(ffi_type *arg)
74
76
  struct A { long a; char b; }; struct B { struct A x; char y; };
75
77
  should find y at an offset of 2*sizeof(long) and result in a
76
78
  total size of 3*sizeof(long). */
77
- arg->size = ALIGN (arg->size, arg->alignment);
79
+ arg->size = FFI_ALIGN (arg->size, arg->alignment);
80
+
81
+ /* On some targets, the ABI defines that structures have an additional
82
+ alignment beyond the "natural" one based on their elements. */
83
+ #ifdef FFI_AGGREGATE_ALIGNMENT
84
+ if (FFI_AGGREGATE_ALIGNMENT > arg->alignment)
85
+ arg->alignment = FFI_AGGREGATE_ALIGNMENT;
86
+ #endif
78
87
 
79
88
  if (arg->size == 0)
80
89
  return FFI_BAD_TYPEDEF;
@@ -90,37 +99,65 @@ static ffi_status initialize_aggregate(ffi_type *arg)
90
99
  /* Perform machine independent ffi_cif preparation, then call
91
100
  machine dependent routine. */
92
101
 
93
- ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
94
- ffi_type *rtype, ffi_type **atypes)
102
+ /* For non variadic functions isvariadic should be 0 and
103
+ nfixedargs==ntotalargs.
104
+
105
+ For variadic calls, isvariadic should be 1 and nfixedargs
106
+ and ntotalargs set as appropriate. nfixedargs must always be >=1 */
107
+
108
+
109
+ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
110
+ unsigned int isvariadic,
111
+ unsigned int nfixedargs,
112
+ unsigned int ntotalargs,
113
+ ffi_type *rtype, ffi_type **atypes)
95
114
  {
96
115
  unsigned bytes = 0;
97
116
  unsigned int i;
98
117
  ffi_type **ptr;
99
118
 
100
119
  FFI_ASSERT(cif != NULL);
120
+ FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));
121
+ FFI_ASSERT(nfixedargs <= ntotalargs);
122
+
101
123
  if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
102
124
  return FFI_BAD_ABI;
103
125
 
104
126
  cif->abi = abi;
105
127
  cif->arg_types = atypes;
106
- cif->nargs = nargs;
128
+ cif->nargs = ntotalargs;
107
129
  cif->rtype = rtype;
108
130
 
109
131
  cif->flags = 0;
110
132
 
133
+ #if HAVE_LONG_DOUBLE_VARIANT
134
+ ffi_prep_types (abi);
135
+ #endif
136
+
111
137
  /* Initialize the return type if necessary */
112
- if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
138
+ if ((cif->rtype->size == 0)
139
+ && (initialize_aggregate(cif->rtype, NULL) != FFI_OK))
113
140
  return FFI_BAD_TYPEDEF;
114
141
 
142
+ #ifndef FFI_TARGET_HAS_COMPLEX_TYPE
143
+ if (rtype->type == FFI_TYPE_COMPLEX)
144
+ abort();
145
+ #endif
115
146
  /* Perform a sanity check on the return type */
116
147
  FFI_ASSERT_VALID_TYPE(cif->rtype);
117
148
 
118
149
  /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
119
- #if !defined M68K && !defined X86_ANY && !defined S390 && !defined PA
150
+ #if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
120
151
  /* Make space for the return structure pointer */
121
152
  if (cif->rtype->type == FFI_TYPE_STRUCT
122
- #ifdef SPARC
123
- && (cif->abi != FFI_V9 || cif->rtype->size > 32)
153
+ #ifdef TILE
154
+ && (cif->rtype->size > 10 * FFI_SIZEOF_ARG)
155
+ #endif
156
+ #ifdef XTENSA
157
+ && (cif->rtype->size > 16)
158
+ #endif
159
+ #ifdef NIOS2
160
+ && (cif->rtype->size > 8)
124
161
  #endif
125
162
  )
126
163
  bytes = STACK_ARG_SIZE(sizeof(void*));
@@ -130,26 +167,37 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
130
167
  {
131
168
 
132
169
  /* Initialize any uninitialized aggregate type definitions */
133
- if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
170
+ if (((*ptr)->size == 0)
171
+ && (initialize_aggregate((*ptr), NULL) != FFI_OK))
134
172
  return FFI_BAD_TYPEDEF;
135
173
 
174
+ #ifndef FFI_TARGET_HAS_COMPLEX_TYPE
175
+ if ((*ptr)->type == FFI_TYPE_COMPLEX)
176
+ abort();
177
+ #endif
136
178
  /* Perform a sanity check on the argument type, do this
137
179
  check after the initialization. */
138
180
  FFI_ASSERT_VALID_TYPE(*ptr);
139
181
 
140
- #if !defined X86_ANY && !defined S390 && !defined PA
141
- #ifdef SPARC
142
- if (((*ptr)->type == FFI_TYPE_STRUCT
143
- && ((*ptr)->size > 16 || cif->abi != FFI_V9))
144
- || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
145
- && cif->abi != FFI_V9))
146
- bytes += sizeof(void*);
147
- else
148
- #endif
182
+ #if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
149
183
  {
150
184
  /* Add any padding if necessary */
151
185
  if (((*ptr)->alignment - 1) & bytes)
152
- bytes = ALIGN(bytes, (*ptr)->alignment);
186
+ bytes = (unsigned)FFI_ALIGN(bytes, (*ptr)->alignment);
187
+
188
+ #ifdef TILE
189
+ if (bytes < 10 * FFI_SIZEOF_ARG &&
190
+ bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG)
191
+ {
192
+ /* An argument is never split between the 10 parameter
193
+ registers and the stack. */
194
+ bytes = 10 * FFI_SIZEOF_ARG;
195
+ }
196
+ #endif
197
+ #ifdef XTENSA
198
+ if (bytes <= 6*4 && bytes + STACK_ARG_SIZE((*ptr)->size) > 6*4)
199
+ bytes = 6*4;
200
+ #endif
153
201
 
154
202
  bytes += STACK_ARG_SIZE((*ptr)->size);
155
203
  }
@@ -159,10 +207,31 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
159
207
  cif->bytes = bytes;
160
208
 
161
209
  /* Perform machine dependent cif processing */
210
+ #ifdef FFI_TARGET_SPECIFIC_VARIADIC
211
+ if (isvariadic)
212
+ return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs);
213
+ #endif
214
+
162
215
  return ffi_prep_cif_machdep(cif);
163
216
  }
164
217
  #endif /* not __CRIS__ */
165
218
 
219
+ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
220
+ ffi_type *rtype, ffi_type **atypes)
221
+ {
222
+ return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes);
223
+ }
224
+
225
+ ffi_status ffi_prep_cif_var(ffi_cif *cif,
226
+ ffi_abi abi,
227
+ unsigned int nfixedargs,
228
+ unsigned int ntotalargs,
229
+ ffi_type *rtype,
230
+ ffi_type **atypes)
231
+ {
232
+ return ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes);
233
+ }
234
+
166
235
  #if FFI_CLOSURES
167
236
 
168
237
  ffi_status
@@ -175,3 +244,18 @@ ffi_prep_closure (ffi_closure* closure,
175
244
  }
176
245
 
177
246
  #endif
247
+
248
+ ffi_status
249
+ ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets)
250
+ {
251
+ if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
252
+ return FFI_BAD_ABI;
253
+ if (struct_type->type != FFI_TYPE_STRUCT)
254
+ return FFI_BAD_TYPEDEF;
255
+
256
+ #if HAVE_LONG_DOUBLE_VARIANT
257
+ ffi_prep_types (abi);
258
+ #endif
259
+
260
+ return initialize_aggregate(struct_type, offsets);
261
+ }
@@ -43,10 +43,10 @@ ffi_raw_size (ffi_cif *cif)
43
43
  {
44
44
  #if !FFI_NO_STRUCTS
45
45
  if ((*at)->type == FFI_TYPE_STRUCT)
46
- result += ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
46
+ result += FFI_ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
47
47
  else
48
48
  #endif
49
- result += ALIGN ((*at)->size, FFI_SIZEOF_ARG);
49
+ result += FFI_ALIGN ((*at)->size, FFI_SIZEOF_ARG);
50
50
  }
51
51
 
52
52
  return result;
@@ -88,13 +88,17 @@ ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
88
88
  break;
89
89
  #endif
90
90
 
91
+ case FFI_TYPE_COMPLEX:
92
+ *args = (raw++)->ptr;
93
+ break;
94
+
91
95
  case FFI_TYPE_POINTER:
92
96
  *args = (void*) &(raw++)->ptr;
93
97
  break;
94
98
 
95
99
  default:
96
100
  *args = raw;
97
- raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
101
+ raw += FFI_ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
98
102
  }
99
103
  }
100
104
 
@@ -112,9 +116,14 @@ ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
112
116
  }
113
117
  else
114
118
  #endif
119
+ if ((*tp)->type == FFI_TYPE_COMPLEX)
120
+ {
121
+ *args = (raw++)->ptr;
122
+ }
123
+ else
115
124
  {
116
125
  *args = (void*) raw;
117
- raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
126
+ raw += FFI_ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
118
127
  }
119
128
  }
120
129
 
@@ -167,13 +176,17 @@ ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
167
176
  break;
168
177
  #endif
169
178
 
179
+ case FFI_TYPE_COMPLEX:
180
+ (raw++)->ptr = *args;
181
+ break;
182
+
170
183
  case FFI_TYPE_POINTER:
171
184
  (raw++)->ptr = **(void***) args;
172
185
  break;
173
186
 
174
187
  default:
175
188
  memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
176
- raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
189
+ raw += FFI_ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
177
190
  }
178
191
  }
179
192
  }
@@ -1,9 +1,9 @@
1
1
  /* -----------------------------------------------------------------------
2
2
  ffi.c - Copyright (c) 2000, 2007 Software AG
3
3
  Copyright (c) 2008 Red Hat, Inc
4
-
4
+
5
5
  S390 Foreign Function Interface
6
-
6
+
7
7
  Permission is hereby granted, free of charge, to any person obtaining
8
8
  a copy of this software and associated documentation files (the
9
9
  ``Software''), to deal in the Software without restriction, including
@@ -11,10 +11,10 @@
11
11
  distribute, sublicense, and/or sell copies of the Software, and to
12
12
  permit persons to whom the Software is furnished to do so, subject to
13
13
  the following conditions:
14
-
14
+
15
15
  The above copyright notice and this permission notice shall be included
16
16
  in all copies or substantial portions of the Software.
17
-
17
+
18
18
  THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
19
  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
20
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -27,24 +27,23 @@
27
27
  /* Includes */
28
28
  /* -------- */
29
29
  /*====================================================================*/
30
-
30
+
31
31
  #include <ffi.h>
32
32
  #include <ffi_common.h>
33
-
34
- #include <stdlib.h>
35
- #include <stdio.h>
36
-
33
+ #include <stdint.h>
34
+ #include "internal.h"
35
+
37
36
  /*====================== End of Includes =============================*/
38
-
37
+
39
38
  /*====================================================================*/
40
39
  /* Defines */
41
40
  /* ------- */
42
41
  /*====================================================================*/
43
42
 
44
- /* Maximum number of GPRs available for argument passing. */
43
+ /* Maximum number of GPRs available for argument passing. */
45
44
  #define MAX_GPRARGS 5
46
45
 
47
- /* Maximum number of FPRs available for argument passing. */
46
+ /* Maximum number of FPRs available for argument passing. */
48
47
  #ifdef __s390x__
49
48
  #define MAX_FPRARGS 4
50
49
  #else
@@ -54,47 +53,30 @@
54
53
  /* Round to multiple of 16. */
55
54
  #define ROUND_SIZE(size) (((size) + 15) & ~15)
56
55
 
57
- /* If these values change, sysv.S must be adapted! */
58
- #define FFI390_RET_VOID 0
59
- #define FFI390_RET_STRUCT 1
60
- #define FFI390_RET_FLOAT 2
61
- #define FFI390_RET_DOUBLE 3
62
- #define FFI390_RET_INT32 4
63
- #define FFI390_RET_INT64 5
64
-
65
56
  /*===================== End of Defines ===============================*/
66
-
67
- /*====================================================================*/
68
- /* Prototypes */
69
- /* ---------- */
70
- /*====================================================================*/
71
-
72
- static void ffi_prep_args (unsigned char *, extended_cif *);
73
- void
74
- #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
75
- __attribute__ ((visibility ("hidden")))
76
- #endif
77
- ffi_closure_helper_SYSV (ffi_closure *, unsigned long *,
78
- unsigned long long *, unsigned long *);
79
57
 
80
- /*====================== End of Prototypes ===========================*/
81
-
82
58
  /*====================================================================*/
83
59
  /* Externals */
84
60
  /* --------- */
85
61
  /*====================================================================*/
86
-
87
- extern void ffi_call_SYSV(unsigned,
88
- extended_cif *,
89
- void (*)(unsigned char *, extended_cif *),
90
- unsigned,
91
- void *,
92
- void (*fn)(void));
62
+
63
+ struct call_frame
64
+ {
65
+ void *back_chain;
66
+ void *eos;
67
+ unsigned long gpr_args[5];
68
+ unsigned long gpr_save[9];
69
+ unsigned long long fpr_args[4];
70
+ };
71
+
72
+ extern void FFI_HIDDEN ffi_call_SYSV(struct call_frame *, unsigned, void *,
73
+ void (*fn)(void), void *);
93
74
 
94
75
  extern void ffi_closure_SYSV(void);
95
-
76
+ extern void ffi_go_closure_SYSV(void);
77
+
96
78
  /*====================== End of Externals ============================*/
97
-
79
+
98
80
  /*====================================================================*/
99
81
  /* */
100
82
  /* Name - ffi_check_struct_type. */
@@ -103,7 +85,7 @@ extern void ffi_closure_SYSV(void);
103
85
  /* general purpose or floating point register. */
104
86
  /* */
105
87
  /*====================================================================*/
106
-
88
+
107
89
  static int
108
90
  ffi_check_struct_type (ffi_type *arg)
109
91
  {
@@ -111,7 +93,7 @@ ffi_check_struct_type (ffi_type *arg)
111
93
 
112
94
  /* If the struct has just one element, look at that element
113
95
  to find out whether to consider the struct as floating point. */
114
- while (arg->type == FFI_TYPE_STRUCT
96
+ while (arg->type == FFI_TYPE_STRUCT
115
97
  && arg->elements[0] && !arg->elements[1])
116
98
  arg = arg->elements[0];
117
99
 
@@ -144,190 +126,9 @@ ffi_check_struct_type (ffi_type *arg)
144
126
  /* Other structs are passed via a pointer to the data. */
145
127
  return FFI_TYPE_POINTER;
146
128
  }
147
-
148
- /*======================== End of Routine ============================*/
149
-
150
- /*====================================================================*/
151
- /* */
152
- /* Name - ffi_prep_args. */
153
- /* */
154
- /* Function - Prepare parameters for call to function. */
155
- /* */
156
- /* ffi_prep_args is called by the assembly routine once stack space */
157
- /* has been allocated for the function's arguments. */
158
- /* */
159
- /*====================================================================*/
160
-
161
- static void
162
- ffi_prep_args (unsigned char *stack, extended_cif *ecif)
163
- {
164
- /* The stack space will be filled with those areas:
165
-
166
- FPR argument register save area (highest addresses)
167
- GPR argument register save area
168
- temporary struct copies
169
- overflow argument area (lowest addresses)
170
-
171
- We set up the following pointers:
172
-
173
- p_fpr: bottom of the FPR area (growing upwards)
174
- p_gpr: bottom of the GPR area (growing upwards)
175
- p_ov: bottom of the overflow area (growing upwards)
176
- p_struct: top of the struct copy area (growing downwards)
177
-
178
- All areas are kept aligned to twice the word size. */
179
-
180
- int gpr_off = ecif->cif->bytes;
181
- int fpr_off = gpr_off + ROUND_SIZE (MAX_GPRARGS * sizeof (long));
182
-
183
- unsigned long long *p_fpr = (unsigned long long *)(stack + fpr_off);
184
- unsigned long *p_gpr = (unsigned long *)(stack + gpr_off);
185
- unsigned char *p_struct = (unsigned char *)p_gpr;
186
- unsigned long *p_ov = (unsigned long *)stack;
187
-
188
- int n_fpr = 0;
189
- int n_gpr = 0;
190
- int n_ov = 0;
191
-
192
- ffi_type **ptr;
193
- void **p_argv = ecif->avalue;
194
- int i;
195
-
196
- /* If we returning a structure then we set the first parameter register
197
- to the address of where we are returning this structure. */
198
-
199
- if (ecif->cif->flags == FFI390_RET_STRUCT)
200
- p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
201
-
202
- /* Now for the arguments. */
203
-
204
- for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
205
- i > 0;
206
- i--, ptr++, p_argv++)
207
- {
208
- void *arg = *p_argv;
209
- int type = (*ptr)->type;
210
-
211
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
212
- /* 16-byte long double is passed like a struct. */
213
- if (type == FFI_TYPE_LONGDOUBLE)
214
- type = FFI_TYPE_STRUCT;
215
- #endif
216
-
217
- /* Check how a structure type is passed. */
218
- if (type == FFI_TYPE_STRUCT)
219
- {
220
- type = ffi_check_struct_type (*ptr);
221
-
222
- /* If we pass the struct via pointer, copy the data. */
223
- if (type == FFI_TYPE_POINTER)
224
- {
225
- p_struct -= ROUND_SIZE ((*ptr)->size);
226
- memcpy (p_struct, (char *)arg, (*ptr)->size);
227
- arg = &p_struct;
228
- }
229
- }
230
-
231
- /* Now handle all primitive int/pointer/float data types. */
232
- switch (type)
233
- {
234
- case FFI_TYPE_DOUBLE:
235
- if (n_fpr < MAX_FPRARGS)
236
- p_fpr[n_fpr++] = *(unsigned long long *) arg;
237
- else
238
- #ifdef __s390x__
239
- p_ov[n_ov++] = *(unsigned long *) arg;
240
- #else
241
- p_ov[n_ov++] = ((unsigned long *) arg)[0],
242
- p_ov[n_ov++] = ((unsigned long *) arg)[1];
243
- #endif
244
- break;
245
-
246
- case FFI_TYPE_FLOAT:
247
- if (n_fpr < MAX_FPRARGS)
248
- p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
249
- else
250
- p_ov[n_ov++] = *(unsigned int *) arg;
251
- break;
252
-
253
- case FFI_TYPE_POINTER:
254
- if (n_gpr < MAX_GPRARGS)
255
- p_gpr[n_gpr++] = (unsigned long)*(unsigned char **) arg;
256
- else
257
- p_ov[n_ov++] = (unsigned long)*(unsigned char **) arg;
258
- break;
259
-
260
- case FFI_TYPE_UINT64:
261
- case FFI_TYPE_SINT64:
262
- #ifdef __s390x__
263
- if (n_gpr < MAX_GPRARGS)
264
- p_gpr[n_gpr++] = *(unsigned long *) arg;
265
- else
266
- p_ov[n_ov++] = *(unsigned long *) arg;
267
- #else
268
- if (n_gpr == MAX_GPRARGS-1)
269
- n_gpr = MAX_GPRARGS;
270
- if (n_gpr < MAX_GPRARGS)
271
- p_gpr[n_gpr++] = ((unsigned long *) arg)[0],
272
- p_gpr[n_gpr++] = ((unsigned long *) arg)[1];
273
- else
274
- p_ov[n_ov++] = ((unsigned long *) arg)[0],
275
- p_ov[n_ov++] = ((unsigned long *) arg)[1];
276
- #endif
277
- break;
278
-
279
- case FFI_TYPE_UINT32:
280
- if (n_gpr < MAX_GPRARGS)
281
- p_gpr[n_gpr++] = *(unsigned int *) arg;
282
- else
283
- p_ov[n_ov++] = *(unsigned int *) arg;
284
- break;
285
-
286
- case FFI_TYPE_INT:
287
- case FFI_TYPE_SINT32:
288
- if (n_gpr < MAX_GPRARGS)
289
- p_gpr[n_gpr++] = *(signed int *) arg;
290
- else
291
- p_ov[n_ov++] = *(signed int *) arg;
292
- break;
293
-
294
- case FFI_TYPE_UINT16:
295
- if (n_gpr < MAX_GPRARGS)
296
- p_gpr[n_gpr++] = *(unsigned short *) arg;
297
- else
298
- p_ov[n_ov++] = *(unsigned short *) arg;
299
- break;
300
-
301
- case FFI_TYPE_SINT16:
302
- if (n_gpr < MAX_GPRARGS)
303
- p_gpr[n_gpr++] = *(signed short *) arg;
304
- else
305
- p_ov[n_ov++] = *(signed short *) arg;
306
- break;
307
-
308
- case FFI_TYPE_UINT8:
309
- if (n_gpr < MAX_GPRARGS)
310
- p_gpr[n_gpr++] = *(unsigned char *) arg;
311
- else
312
- p_ov[n_ov++] = *(unsigned char *) arg;
313
- break;
314
-
315
- case FFI_TYPE_SINT8:
316
- if (n_gpr < MAX_GPRARGS)
317
- p_gpr[n_gpr++] = *(signed char *) arg;
318
- else
319
- p_ov[n_ov++] = *(signed char *) arg;
320
- break;
321
-
322
- default:
323
- FFI_ASSERT (0);
324
- break;
325
- }
326
- }
327
- }
328
129
 
329
130
  /*======================== End of Routine ============================*/
330
-
131
+
331
132
  /*====================================================================*/
332
133
  /* */
333
134
  /* Name - ffi_prep_cif_machdep. */
@@ -335,8 +136,8 @@ ffi_prep_args (unsigned char *stack, extended_cif *ecif)
335
136
  /* Function - Perform machine dependent CIF processing. */
336
137
  /* */
337
138
  /*====================================================================*/
338
-
339
- ffi_status
139
+
140
+ ffi_status FFI_HIDDEN
340
141
  ffi_prep_cif_machdep(ffi_cif *cif)
341
142
  {
342
143
  size_t struct_size = 0;
@@ -347,7 +148,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
347
148
  ffi_type **ptr;
348
149
  int i;
349
150
 
350
- /* Determine return value handling. */
151
+ /* Determine return value handling. */
351
152
 
352
153
  switch (cif->rtype->type)
353
154
  {
@@ -356,11 +157,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
356
157
  cif->flags = FFI390_RET_VOID;
357
158
  break;
358
159
 
359
- /* Structures are returned via a hidden pointer. */
160
+ /* Structures and complex are returned via a hidden pointer. */
360
161
  case FFI_TYPE_STRUCT:
162
+ case FFI_TYPE_COMPLEX:
361
163
  cif->flags = FFI390_RET_STRUCT;
362
164
  n_gpr++; /* We need one GPR to pass the pointer. */
363
- break;
165
+ break;
364
166
 
365
167
  /* Floating point values are returned in fpr 0. */
366
168
  case FFI_TYPE_FLOAT:
@@ -399,14 +201,14 @@ ffi_prep_cif_machdep(ffi_cif *cif)
399
201
  cif->flags = FFI390_RET_INT32;
400
202
  #endif
401
203
  break;
402
-
204
+
403
205
  default:
404
206
  FFI_ASSERT (0);
405
207
  break;
406
208
  }
407
209
 
408
210
  /* Now for the arguments. */
409
-
211
+
410
212
  for (ptr = cif->arg_types, i = cif->nargs;
411
213
  i > 0;
412
214
  i--, ptr++)
@@ -420,9 +222,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
420
222
  #endif
421
223
 
422
224
  /* Check how a structure type is passed. */
423
- if (type == FFI_TYPE_STRUCT)
225
+ if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
424
226
  {
425
- type = ffi_check_struct_type (*ptr);
227
+ if (type == FFI_TYPE_COMPLEX)
228
+ type = FFI_TYPE_POINTER;
229
+ else
230
+ type = ffi_check_struct_type (*ptr);
426
231
 
427
232
  /* If we pass the struct via pointer, we must reserve space
428
233
  to copy its data for proper call-by-value semantics. */
@@ -431,7 +236,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
431
236
  }
432
237
 
433
238
  /* Now handle all primitive int/float data types. */
434
- switch (type)
239
+ switch (type)
435
240
  {
436
241
  /* The first MAX_FPRARGS floating point arguments
437
242
  go in FPRs, the rest overflow to the stack. */
@@ -442,7 +247,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
442
247
  else
443
248
  n_ov += sizeof (double) / sizeof (long);
444
249
  break;
445
-
250
+
446
251
  case FFI_TYPE_FLOAT:
447
252
  if (n_fpr < MAX_FPRARGS)
448
253
  n_fpr++;
@@ -452,9 +257,9 @@ ffi_prep_cif_machdep(ffi_cif *cif)
452
257
 
453
258
  /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
454
259
  if one is still available, or else on the stack. If only one
455
- register is free, skip the register (it won't be used for any
260
+ register is free, skip the register (it won't be used for any
456
261
  subsequent argument either). */
457
-
262
+
458
263
  #ifndef __s390x__
459
264
  case FFI_TYPE_UINT64:
460
265
  case FFI_TYPE_SINT64:
@@ -470,7 +275,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
470
275
  /* Everything else is passed in GPRs (until MAX_GPRARGS
471
276
  have been used) or overflows to the stack. */
472
277
 
473
- default:
278
+ default:
474
279
  if (n_gpr < MAX_GPRARGS)
475
280
  n_gpr++;
476
281
  else
@@ -483,12 +288,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
483
288
  and temporary structure copies. */
484
289
 
485
290
  cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
486
-
291
+
487
292
  return FFI_OK;
488
293
  }
489
-
294
+
490
295
  /*======================== End of Routine ============================*/
491
-
296
+
492
297
  /*====================================================================*/
493
298
  /* */
494
299
  /* Name - ffi_call. */
@@ -496,42 +301,195 @@ ffi_prep_cif_machdep(ffi_cif *cif)
496
301
  /* Function - Call the FFI routine. */
497
302
  /* */
498
303
  /*====================================================================*/
499
-
500
- void
501
- ffi_call(ffi_cif *cif,
502
- void (*fn)(void),
503
- void *rvalue,
504
- void **avalue)
304
+
305
+ static void
306
+ ffi_call_int(ffi_cif *cif,
307
+ void (*fn)(void),
308
+ void *rvalue,
309
+ void **avalue,
310
+ void *closure)
505
311
  {
506
312
  int ret_type = cif->flags;
507
- extended_cif ecif;
508
-
509
- ecif.cif = cif;
510
- ecif.avalue = avalue;
511
- ecif.rvalue = rvalue;
313
+ size_t rsize = 0, bytes = cif->bytes;
314
+ unsigned char *stack, *p_struct;
315
+ struct call_frame *frame;
316
+ unsigned long *p_ov, *p_gpr;
317
+ unsigned long long *p_fpr;
318
+ int n_fpr, n_gpr, n_ov, i, n;
319
+ ffi_type **arg_types;
320
+
321
+ FFI_ASSERT (cif->abi == FFI_SYSV);
512
322
 
513
323
  /* If we don't have a return value, we need to fake one. */
514
324
  if (rvalue == NULL)
515
325
  {
516
- if (ret_type == FFI390_RET_STRUCT)
517
- ecif.rvalue = alloca (cif->rtype->size);
326
+ if (ret_type & FFI390_RET_IN_MEM)
327
+ rsize = cif->rtype->size;
518
328
  else
519
329
  ret_type = FFI390_RET_VOID;
520
- }
330
+ }
331
+
332
+ /* The stack space will be filled with those areas:
333
+
334
+ dummy structure return (highest addresses)
335
+ FPR argument register save area
336
+ GPR argument register save area
337
+ stack frame for ffi_call_SYSV
338
+ temporary struct copies
339
+ overflow argument area (lowest addresses)
340
+
341
+ We set up the following pointers:
342
+
343
+ p_fpr: bottom of the FPR area (growing upwards)
344
+ p_gpr: bottom of the GPR area (growing upwards)
345
+ p_ov: bottom of the overflow area (growing upwards)
346
+ p_struct: top of the struct copy area (growing downwards)
347
+
348
+ All areas are kept aligned to twice the word size.
349
+
350
+ Note that we're going to create the stack frame for both
351
+ ffi_call_SYSV _and_ the target function right here. This
352
+ works because we don't make any function calls with more
353
+ than 5 arguments (indeed only memcpy and ffi_call_SYSV),
354
+ and thus we don't have any stacked outgoing parameters. */
521
355
 
522
- switch (cif->abi)
356
+ stack = alloca (bytes + sizeof(struct call_frame) + rsize);
357
+ frame = (struct call_frame *)(stack + bytes);
358
+ if (rsize)
359
+ rvalue = frame + 1;
360
+
361
+ /* Link the new frame back to the one from this function. */
362
+ frame->back_chain = __builtin_frame_address (0);
363
+
364
+ /* Fill in all of the argument stuff. */
365
+ p_ov = (unsigned long *)stack;
366
+ p_struct = (unsigned char *)frame;
367
+ p_gpr = frame->gpr_args;
368
+ p_fpr = frame->fpr_args;
369
+ n_fpr = n_gpr = n_ov = 0;
370
+
371
+ /* If we returning a structure then we set the first parameter register
372
+ to the address of where we are returning this structure. */
373
+ if (cif->flags & FFI390_RET_IN_MEM)
374
+ p_gpr[n_gpr++] = (uintptr_t) rvalue;
375
+
376
+ /* Now for the arguments. */
377
+ arg_types = cif->arg_types;
378
+ for (i = 0, n = cif->nargs; i < n; ++i)
523
379
  {
524
- case FFI_SYSV:
525
- ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
526
- ret_type, ecif.rvalue, fn);
527
- break;
528
-
529
- default:
530
- FFI_ASSERT (0);
531
- break;
380
+ ffi_type *ty = arg_types[i];
381
+ void *arg = avalue[i];
382
+ int type = ty->type;
383
+ ffi_arg val;
384
+
385
+ restart:
386
+ switch (type)
387
+ {
388
+ case FFI_TYPE_SINT8:
389
+ val = *(SINT8 *)arg;
390
+ goto do_int;
391
+ case FFI_TYPE_UINT8:
392
+ val = *(UINT8 *)arg;
393
+ goto do_int;
394
+ case FFI_TYPE_SINT16:
395
+ val = *(SINT16 *)arg;
396
+ goto do_int;
397
+ case FFI_TYPE_UINT16:
398
+ val = *(UINT16 *)arg;
399
+ goto do_int;
400
+ case FFI_TYPE_INT:
401
+ case FFI_TYPE_SINT32:
402
+ val = *(SINT32 *)arg;
403
+ goto do_int;
404
+ case FFI_TYPE_UINT32:
405
+ val = *(UINT32 *)arg;
406
+ goto do_int;
407
+ case FFI_TYPE_POINTER:
408
+ val = *(uintptr_t *)arg;
409
+ do_int:
410
+ *(n_gpr < MAX_GPRARGS ? p_gpr + n_gpr++ : p_ov + n_ov++) = val;
411
+ break;
412
+
413
+ case FFI_TYPE_UINT64:
414
+ case FFI_TYPE_SINT64:
415
+ #ifdef __s390x__
416
+ val = *(UINT64 *)arg;
417
+ goto do_int;
418
+ #else
419
+ if (n_gpr == MAX_GPRARGS-1)
420
+ n_gpr = MAX_GPRARGS;
421
+ if (n_gpr < MAX_GPRARGS)
422
+ p_gpr[n_gpr++] = ((UINT32 *) arg)[0],
423
+ p_gpr[n_gpr++] = ((UINT32 *) arg)[1];
424
+ else
425
+ p_ov[n_ov++] = ((UINT32 *) arg)[0],
426
+ p_ov[n_ov++] = ((UINT32 *) arg)[1];
427
+ #endif
428
+ break;
429
+
430
+ case FFI_TYPE_DOUBLE:
431
+ if (n_fpr < MAX_FPRARGS)
432
+ p_fpr[n_fpr++] = *(UINT64 *) arg;
433
+ else
434
+ {
435
+ #ifdef __s390x__
436
+ p_ov[n_ov++] = *(UINT64 *) arg;
437
+ #else
438
+ p_ov[n_ov++] = ((UINT32 *) arg)[0],
439
+ p_ov[n_ov++] = ((UINT32 *) arg)[1];
440
+ #endif
441
+ }
442
+ break;
443
+
444
+ case FFI_TYPE_FLOAT:
445
+ val = *(UINT32 *)arg;
446
+ if (n_fpr < MAX_FPRARGS)
447
+ p_fpr[n_fpr++] = (UINT64)val << 32;
448
+ else
449
+ p_ov[n_ov++] = val;
450
+ break;
451
+
452
+ case FFI_TYPE_STRUCT:
453
+ /* Check how a structure type is passed. */
454
+ type = ffi_check_struct_type (ty);
455
+ /* Some structures are passed via a type they contain. */
456
+ if (type != FFI_TYPE_POINTER)
457
+ goto restart;
458
+ /* ... otherwise, passed by reference. fallthru. */
459
+
460
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
461
+ case FFI_TYPE_LONGDOUBLE:
462
+ /* 16-byte long double is passed via reference. */
463
+ #endif
464
+ case FFI_TYPE_COMPLEX:
465
+ /* Complex types are passed via reference. */
466
+ p_struct -= ROUND_SIZE (ty->size);
467
+ memcpy (p_struct, arg, ty->size);
468
+ val = (uintptr_t)p_struct;
469
+ goto do_int;
470
+
471
+ default:
472
+ FFI_ASSERT (0);
473
+ break;
474
+ }
532
475
  }
476
+
477
+ ffi_call_SYSV (frame, ret_type & FFI360_RET_MASK, rvalue, fn, closure);
533
478
  }
534
-
479
+
480
+ void
481
+ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
482
+ {
483
+ ffi_call_int(cif, fn, rvalue, avalue, NULL);
484
+ }
485
+
486
+ void
487
+ ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
488
+ void **avalue, void *closure)
489
+ {
490
+ ffi_call_int(cif, fn, rvalue, avalue, closure);
491
+ }
492
+
535
493
  /*======================== End of Routine ============================*/
536
494
 
537
495
  /*====================================================================*/
@@ -541,9 +499,11 @@ ffi_call(ffi_cif *cif,
541
499
  /* Function - Call a FFI closure target function. */
542
500
  /* */
543
501
  /*====================================================================*/
544
-
545
- void
546
- ffi_closure_helper_SYSV (ffi_closure *closure,
502
+
503
+ void FFI_HIDDEN
504
+ ffi_closure_helper_SYSV (ffi_cif *cif,
505
+ void (*fun)(ffi_cif*,void*,void**,void*),
506
+ void *user_data,
547
507
  unsigned long *p_gpr,
548
508
  unsigned long long *p_fpr,
549
509
  unsigned long *p_ov)
@@ -562,21 +522,16 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
562
522
  int i;
563
523
 
564
524
  /* Allocate buffer for argument list pointers. */
525
+ p_arg = avalue = alloca (cif->nargs * sizeof (void *));
565
526
 
566
- p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
567
-
568
- /* If we returning a structure, pass the structure address
569
- directly to the target function. Otherwise, have the target
527
+ /* If we returning a structure, pass the structure address
528
+ directly to the target function. Otherwise, have the target
570
529
  function store the return value to the GPR save area. */
571
-
572
- if (closure->cif->flags == FFI390_RET_STRUCT)
530
+ if (cif->flags & FFI390_RET_IN_MEM)
573
531
  rvalue = (void *) p_gpr[n_gpr++];
574
532
 
575
533
  /* Now for the arguments. */
576
-
577
- for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
578
- i > 0;
579
- i--, p_arg++, ptr++)
534
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, p_arg++, ptr++)
580
535
  {
581
536
  int deref_struct_pointer = 0;
582
537
  int type = (*ptr)->type;
@@ -588,11 +543,14 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
588
543
  #endif
589
544
 
590
545
  /* Check how a structure type is passed. */
591
- if (type == FFI_TYPE_STRUCT)
546
+ if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
592
547
  {
593
- type = ffi_check_struct_type (*ptr);
548
+ if (type == FFI_TYPE_COMPLEX)
549
+ type = FFI_TYPE_POINTER;
550
+ else
551
+ type = ffi_check_struct_type (*ptr);
594
552
 
595
- /* If we pass the struct via pointer, remember to
553
+ /* If we pass the struct via pointer, remember to
596
554
  retrieve the pointer later. */
597
555
  if (type == FFI_TYPE_POINTER)
598
556
  deref_struct_pointer = 1;
@@ -600,30 +558,32 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
600
558
 
601
559
  /* Pointers are passed like UINTs of the same size. */
602
560
  if (type == FFI_TYPE_POINTER)
561
+ {
603
562
  #ifdef __s390x__
604
- type = FFI_TYPE_UINT64;
563
+ type = FFI_TYPE_UINT64;
605
564
  #else
606
- type = FFI_TYPE_UINT32;
565
+ type = FFI_TYPE_UINT32;
607
566
  #endif
567
+ }
608
568
 
609
569
  /* Now handle all primitive int/float data types. */
610
- switch (type)
570
+ switch (type)
611
571
  {
612
572
  case FFI_TYPE_DOUBLE:
613
573
  if (n_fpr < MAX_FPRARGS)
614
574
  *p_arg = &p_fpr[n_fpr++];
615
575
  else
616
- *p_arg = &p_ov[n_ov],
576
+ *p_arg = &p_ov[n_ov],
617
577
  n_ov += sizeof (double) / sizeof (long);
618
578
  break;
619
-
579
+
620
580
  case FFI_TYPE_FLOAT:
621
581
  if (n_fpr < MAX_FPRARGS)
622
582
  *p_arg = &p_fpr[n_fpr++];
623
583
  else
624
584
  *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
625
585
  break;
626
-
586
+
627
587
  case FFI_TYPE_UINT64:
628
588
  case FFI_TYPE_SINT64:
629
589
  #ifdef __s390x__
@@ -640,7 +600,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
640
600
  *p_arg = &p_ov[n_ov], n_ov += 2;
641
601
  #endif
642
602
  break;
643
-
603
+
644
604
  case FFI_TYPE_INT:
645
605
  case FFI_TYPE_UINT32:
646
606
  case FFI_TYPE_SINT32:
@@ -649,7 +609,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
649
609
  else
650
610
  *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
651
611
  break;
652
-
612
+
653
613
  case FFI_TYPE_UINT16:
654
614
  case FFI_TYPE_SINT16:
655
615
  if (n_gpr < MAX_GPRARGS)
@@ -665,7 +625,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
665
625
  else
666
626
  *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
667
627
  break;
668
-
628
+
669
629
  default:
670
630
  FFI_ASSERT (0);
671
631
  break;
@@ -679,14 +639,15 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
679
639
 
680
640
 
681
641
  /* Call the target function. */
682
- (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
642
+ (fun) (cif, rvalue, avalue, user_data);
683
643
 
684
644
  /* Convert the return value. */
685
- switch (closure->cif->rtype->type)
645
+ switch (cif->rtype->type)
686
646
  {
687
647
  /* Void is easy, and so is struct. */
688
648
  case FFI_TYPE_VOID:
689
649
  case FFI_TYPE_STRUCT:
650
+ case FFI_TYPE_COMPLEX:
690
651
  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
691
652
  case FFI_TYPE_LONGDOUBLE:
692
653
  #endif
@@ -732,7 +693,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
732
693
  break;
733
694
  }
734
695
  }
735
-
696
+
736
697
  /*======================== End of Routine ============================*/
737
698
 
738
699
  /*====================================================================*/
@@ -742,7 +703,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
742
703
  /* Function - Prepare a FFI closure. */
743
704
  /* */
744
705
  /*====================================================================*/
745
-
706
+
746
707
  ffi_status
747
708
  ffi_prep_closure_loc (ffi_closure *closure,
748
709
  ffi_cif *cif,
@@ -750,31 +711,46 @@ ffi_prep_closure_loc (ffi_closure *closure,
750
711
  void *user_data,
751
712
  void *codeloc)
752
713
  {
753
- FFI_ASSERT (cif->abi == FFI_SYSV);
754
-
714
+ static unsigned short const template[] = {
715
+ 0x0d10, /* basr %r1,0 */
755
716
  #ifndef __s390x__
756
- *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
757
- *(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */
758
- *(short *)&closure->tramp [4] = 0x1006;
759
- *(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */
760
- *(long *)&closure->tramp [8] = (long)codeloc;
761
- *(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
717
+ 0x9801, 0x1006, /* lm %r0,%r1,6(%r1) */
762
718
  #else
763
- *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
764
- *(short *)&closure->tramp [2] = 0xeb01; /* lmg %r0,%r1,14(%r1) */
765
- *(short *)&closure->tramp [4] = 0x100e;
766
- *(short *)&closure->tramp [6] = 0x0004;
767
- *(short *)&closure->tramp [8] = 0x07f1; /* br %r1 */
768
- *(long *)&closure->tramp[16] = (long)codeloc;
769
- *(long *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
770
- #endif
771
-
719
+ 0xeb01, 0x100e, 0x0004, /* lmg %r0,%r1,14(%r1) */
720
+ #endif
721
+ 0x07f1 /* br %r1 */
722
+ };
723
+
724
+ unsigned long *tramp = (unsigned long *)&closure->tramp;
725
+
726
+ if (cif->abi != FFI_SYSV)
727
+ return FFI_BAD_ABI;
728
+
729
+ memcpy (tramp, template, sizeof(template));
730
+ tramp[2] = (unsigned long)codeloc;
731
+ tramp[3] = (unsigned long)&ffi_closure_SYSV;
732
+
772
733
  closure->cif = cif;
773
- closure->user_data = user_data;
774
734
  closure->fun = fun;
775
-
735
+ closure->user_data = user_data;
736
+
776
737
  return FFI_OK;
777
738
  }
778
739
 
779
740
  /*======================== End of Routine ============================*/
780
-
741
+
742
+ /* Build a Go language closure. */
743
+
744
+ ffi_status
745
+ ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
746
+ void (*fun)(ffi_cif*,void*,void**,void*))
747
+ {
748
+ if (cif->abi != FFI_SYSV)
749
+ return FFI_BAD_ABI;
750
+
751
+ closure->tramp = ffi_go_closure_SYSV;
752
+ closure->cif = cif;
753
+ closure->fun = fun;
754
+
755
+ return FFI_OK;
756
+ }