remogatto-ffi 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (324) hide show
  1. data/LICENSE +51 -0
  2. data/README.rdoc +69 -0
  3. data/Rakefile +144 -0
  4. data/ext/ffi_c/AbstractMemory.c +489 -0
  5. data/ext/ffi_c/AbstractMemory.h +160 -0
  6. data/ext/ffi_c/ArrayType.c +129 -0
  7. data/ext/ffi_c/ArrayType.h +58 -0
  8. data/ext/ffi_c/AutoPointer.c +61 -0
  9. data/ext/ffi_c/AutoPointer.h +18 -0
  10. data/ext/ffi_c/Buffer.c +187 -0
  11. data/ext/ffi_c/Call.c +431 -0
  12. data/ext/ffi_c/Call.h +77 -0
  13. data/ext/ffi_c/DynamicLibrary.c +216 -0
  14. data/ext/ffi_c/DynamicLibrary.h +22 -0
  15. data/ext/ffi_c/Function.c +498 -0
  16. data/ext/ffi_c/Function.h +73 -0
  17. data/ext/ffi_c/FunctionInfo.c +213 -0
  18. data/ext/ffi_c/LastError.c +159 -0
  19. data/ext/ffi_c/LastError.h +18 -0
  20. data/ext/ffi_c/MemoryPointer.c +178 -0
  21. data/ext/ffi_c/MemoryPointer.h +20 -0
  22. data/ext/ffi_c/MethodHandle.c +356 -0
  23. data/ext/ffi_c/MethodHandle.h +53 -0
  24. data/ext/ffi_c/Platform.c +59 -0
  25. data/ext/ffi_c/Platform.h +16 -0
  26. data/ext/ffi_c/Pointer.c +217 -0
  27. data/ext/ffi_c/Pointer.h +49 -0
  28. data/ext/ffi_c/Struct.c +770 -0
  29. data/ext/ffi_c/Struct.h +80 -0
  30. data/ext/ffi_c/StructByValue.c +140 -0
  31. data/ext/ffi_c/StructByValue.h +53 -0
  32. data/ext/ffi_c/StructLayout.c +450 -0
  33. data/ext/ffi_c/Type.c +329 -0
  34. data/ext/ffi_c/Type.h +57 -0
  35. data/ext/ffi_c/Types.c +103 -0
  36. data/ext/ffi_c/Types.h +85 -0
  37. data/ext/ffi_c/Variadic.c +260 -0
  38. data/ext/ffi_c/compat.h +72 -0
  39. data/ext/ffi_c/endian.h +40 -0
  40. data/ext/ffi_c/extconf.rb +34 -0
  41. data/ext/ffi_c/ffi.c +80 -0
  42. data/ext/ffi_c/libffi.bsd.mk +34 -0
  43. data/ext/ffi_c/libffi.darwin.mk +75 -0
  44. data/ext/ffi_c/libffi.gnu.mk +29 -0
  45. data/ext/ffi_c/libffi.mk +13 -0
  46. data/ext/ffi_c/libffi/ChangeLog +3243 -0
  47. data/ext/ffi_c/libffi/ChangeLog.libffi +347 -0
  48. data/ext/ffi_c/libffi/ChangeLog.libgcj +40 -0
  49. data/ext/ffi_c/libffi/ChangeLog.v1 +764 -0
  50. data/ext/ffi_c/libffi/LICENSE +21 -0
  51. data/ext/ffi_c/libffi/Makefile.am +177 -0
  52. data/ext/ffi_c/libffi/Makefile.in +1640 -0
  53. data/ext/ffi_c/libffi/README +328 -0
  54. data/ext/ffi_c/libffi/TODO +1 -0
  55. data/ext/ffi_c/libffi/acinclude.m4 +92 -0
  56. data/ext/ffi_c/libffi/aclocal.m4 +7516 -0
  57. data/ext/ffi_c/libffi/compile +142 -0
  58. data/ext/ffi_c/libffi/config.guess +1516 -0
  59. data/ext/ffi_c/libffi/config.sub +1626 -0
  60. data/ext/ffi_c/libffi/configure +24414 -0
  61. data/ext/ffi_c/libffi/configure.ac +365 -0
  62. data/ext/ffi_c/libffi/configure.host +11 -0
  63. data/ext/ffi_c/libffi/depcomp +584 -0
  64. data/ext/ffi_c/libffi/doc/libffi.info +533 -0
  65. data/ext/ffi_c/libffi/doc/libffi.texi +541 -0
  66. data/ext/ffi_c/libffi/doc/stamp-vti +4 -0
  67. data/ext/ffi_c/libffi/doc/version.texi +4 -0
  68. data/ext/ffi_c/libffi/fficonfig.h.in +160 -0
  69. data/ext/ffi_c/libffi/include/Makefile.am +9 -0
  70. data/ext/ffi_c/libffi/include/Makefile.in +422 -0
  71. data/ext/ffi_c/libffi/include/ffi.h.in +393 -0
  72. data/ext/ffi_c/libffi/include/ffi_common.h +98 -0
  73. data/ext/ffi_c/libffi/install-sh +323 -0
  74. data/ext/ffi_c/libffi/libffi.pc.in +10 -0
  75. data/ext/ffi_c/libffi/libtool-version +29 -0
  76. data/ext/ffi_c/libffi/ltcf-c.sh +861 -0
  77. data/ext/ffi_c/libffi/ltcf-cxx.sh +1069 -0
  78. data/ext/ffi_c/libffi/ltcf-gcj.sh +700 -0
  79. data/ext/ffi_c/libffi/ltconfig +2862 -0
  80. data/ext/ffi_c/libffi/ltmain.sh +6930 -0
  81. data/ext/ffi_c/libffi/man/Makefile.am +8 -0
  82. data/ext/ffi_c/libffi/man/Makefile.in +395 -0
  83. data/ext/ffi_c/libffi/man/ffi.3 +31 -0
  84. data/ext/ffi_c/libffi/man/ffi_call.3 +103 -0
  85. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +66 -0
  86. data/ext/ffi_c/libffi/mdate-sh +201 -0
  87. data/ext/ffi_c/libffi/missing +353 -0
  88. data/ext/ffi_c/libffi/mkinstalldirs +158 -0
  89. data/ext/ffi_c/libffi/src/alpha/ffi.c +284 -0
  90. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +48 -0
  91. data/ext/ffi_c/libffi/src/alpha/osf.S +366 -0
  92. data/ext/ffi_c/libffi/src/arm/ffi.c +309 -0
  93. data/ext/ffi_c/libffi/src/arm/ffitarget.h +49 -0
  94. data/ext/ffi_c/libffi/src/arm/sysv.S +299 -0
  95. data/ext/ffi_c/libffi/src/closures.c +596 -0
  96. data/ext/ffi_c/libffi/src/cris/ffi.c +383 -0
  97. data/ext/ffi_c/libffi/src/cris/ffitarget.h +51 -0
  98. data/ext/ffi_c/libffi/src/cris/sysv.S +215 -0
  99. data/ext/ffi_c/libffi/src/debug.c +59 -0
  100. data/ext/ffi_c/libffi/src/dlmalloc.c +5099 -0
  101. data/ext/ffi_c/libffi/src/frv/eabi.S +128 -0
  102. data/ext/ffi_c/libffi/src/frv/ffi.c +292 -0
  103. data/ext/ffi_c/libffi/src/frv/ffitarget.h +61 -0
  104. data/ext/ffi_c/libffi/src/ia64/ffi.c +580 -0
  105. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +50 -0
  106. data/ext/ffi_c/libffi/src/ia64/ia64_flags.h +40 -0
  107. data/ext/ffi_c/libffi/src/ia64/unix.S +560 -0
  108. data/ext/ffi_c/libffi/src/java_raw_api.c +359 -0
  109. data/ext/ffi_c/libffi/src/m32r/ffi.c +232 -0
  110. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +48 -0
  111. data/ext/ffi_c/libffi/src/m32r/sysv.S +121 -0
  112. data/ext/ffi_c/libffi/src/m68k/ffi.c +278 -0
  113. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +49 -0
  114. data/ext/ffi_c/libffi/src/m68k/sysv.S +234 -0
  115. data/ext/ffi_c/libffi/src/mips/ffi.c +926 -0
  116. data/ext/ffi_c/libffi/src/mips/ffitarget.h +202 -0
  117. data/ext/ffi_c/libffi/src/mips/n32.S +534 -0
  118. data/ext/ffi_c/libffi/src/mips/o32.S +381 -0
  119. data/ext/ffi_c/libffi/src/pa/ffi.c +709 -0
  120. data/ext/ffi_c/libffi/src/pa/ffitarget.h +77 -0
  121. data/ext/ffi_c/libffi/src/pa/hpux32.S +368 -0
  122. data/ext/ffi_c/libffi/src/pa/linux.S +357 -0
  123. data/ext/ffi_c/libffi/src/powerpc/aix.S +225 -0
  124. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +247 -0
  125. data/ext/ffi_c/libffi/src/powerpc/asm.h +125 -0
  126. data/ext/ffi_c/libffi/src/powerpc/darwin.S +245 -0
  127. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +317 -0
  128. data/ext/ffi_c/libffi/src/powerpc/ffi.c +1429 -0
  129. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +800 -0
  130. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +118 -0
  131. data/ext/ffi_c/libffi/src/powerpc/linux64.S +187 -0
  132. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +236 -0
  133. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +327 -0
  134. data/ext/ffi_c/libffi/src/powerpc/sysv.S +230 -0
  135. data/ext/ffi_c/libffi/src/prep_cif.c +174 -0
  136. data/ext/ffi_c/libffi/src/raw_api.c +254 -0
  137. data/ext/ffi_c/libffi/src/s390/ffi.c +780 -0
  138. data/ext/ffi_c/libffi/src/s390/ffitarget.h +60 -0
  139. data/ext/ffi_c/libffi/src/s390/sysv.S +434 -0
  140. data/ext/ffi_c/libffi/src/sh/ffi.c +716 -0
  141. data/ext/ffi_c/libffi/src/sh/ffitarget.h +49 -0
  142. data/ext/ffi_c/libffi/src/sh/sysv.S +850 -0
  143. data/ext/ffi_c/libffi/src/sh64/ffi.c +453 -0
  144. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +53 -0
  145. data/ext/ffi_c/libffi/src/sh64/sysv.S +530 -0
  146. data/ext/ffi_c/libffi/src/sparc/ffi.c +610 -0
  147. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +66 -0
  148. data/ext/ffi_c/libffi/src/sparc/v8.S +272 -0
  149. data/ext/ffi_c/libffi/src/sparc/v9.S +307 -0
  150. data/ext/ffi_c/libffi/src/types.c +77 -0
  151. data/ext/ffi_c/libffi/src/x86/darwin.S +443 -0
  152. data/ext/ffi_c/libffi/src/x86/darwin64.S +416 -0
  153. data/ext/ffi_c/libffi/src/x86/ffi.c +475 -0
  154. data/ext/ffi_c/libffi/src/x86/ffi64.c +572 -0
  155. data/ext/ffi_c/libffi/src/x86/ffitarget.h +90 -0
  156. data/ext/ffi_c/libffi/src/x86/freebsd.S +458 -0
  157. data/ext/ffi_c/libffi/src/x86/sysv.S +437 -0
  158. data/ext/ffi_c/libffi/src/x86/unix64.S +418 -0
  159. data/ext/ffi_c/libffi/src/x86/win32.S +391 -0
  160. data/ext/ffi_c/libffi/testsuite/Makefile.am +71 -0
  161. data/ext/ffi_c/libffi/testsuite/Makefile.in +447 -0
  162. data/ext/ffi_c/libffi/testsuite/config/default.exp +1 -0
  163. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +289 -0
  164. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +263 -0
  165. data/ext/ffi_c/libffi/testsuite/lib/wrapper.exp +45 -0
  166. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +36 -0
  167. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +97 -0
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +89 -0
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +89 -0
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +90 -0
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +97 -0
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +99 -0
  173. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +98 -0
  174. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c +72 -0
  175. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +102 -0
  176. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +103 -0
  177. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +104 -0
  178. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +110 -0
  179. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +97 -0
  180. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +99 -0
  181. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +101 -0
  182. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +121 -0
  183. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +98 -0
  184. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +103 -0
  185. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +98 -0
  186. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +98 -0
  187. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +106 -0
  188. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +98 -0
  189. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +117 -0
  190. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +106 -0
  191. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +132 -0
  192. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +121 -0
  193. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +107 -0
  194. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +125 -0
  195. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +105 -0
  196. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +96 -0
  197. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +98 -0
  198. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +99 -0
  199. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +101 -0
  200. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +99 -0
  201. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +100 -0
  202. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +101 -0
  203. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +99 -0
  204. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +99 -0
  205. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +99 -0
  206. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +99 -0
  207. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +99 -0
  208. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +100 -0
  209. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +51 -0
  210. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +51 -0
  211. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +82 -0
  212. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +82 -0
  213. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +94 -0
  214. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +99 -0
  215. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +82 -0
  216. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +94 -0
  217. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +52 -0
  218. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +50 -0
  219. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +50 -0
  220. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +50 -0
  221. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +51 -0
  222. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +54 -0
  223. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +51 -0
  224. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +86 -0
  225. data/ext/ffi_c/libffi/testsuite/libffi.call/float.c +59 -0
  226. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +58 -0
  227. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +57 -0
  228. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +72 -0
  229. data/ext/ffi_c/libffi/testsuite/libffi.call/float4.c +62 -0
  230. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +69 -0
  231. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +63 -0
  232. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +53 -0
  233. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +160 -0
  234. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +169 -0
  235. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +141 -0
  236. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +118 -0
  237. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +119 -0
  238. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +119 -0
  239. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +120 -0
  240. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +139 -0
  241. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +119 -0
  242. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +139 -0
  243. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +139 -0
  244. data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +98 -0
  245. data/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c +59 -0
  246. data/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c +114 -0
  247. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +35 -0
  248. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c +43 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c +42 -0
  250. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c +35 -0
  251. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c +36 -0
  252. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c +49 -0
  253. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c +42 -0
  254. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +34 -0
  255. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c +41 -0
  256. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +42 -0
  257. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +36 -0
  258. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +38 -0
  259. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +38 -0
  260. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +38 -0
  261. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +44 -0
  262. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +44 -0
  263. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +65 -0
  264. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +67 -0
  265. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +59 -0
  266. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +63 -0
  267. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +65 -0
  268. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +64 -0
  269. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +74 -0
  270. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +80 -0
  271. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +67 -0
  272. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +86 -0
  273. data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +38 -0
  274. data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc +123 -0
  275. data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc +53 -0
  276. data/ext/ffi_c/libffi/texinfo.tex +7482 -0
  277. data/ext/ffi_c/rbffi.h +26 -0
  278. data/gen/Rakefile +12 -0
  279. data/lib/ffi.rb +11 -0
  280. data/lib/ffi/autopointer.rb +61 -0
  281. data/lib/ffi/buffer.rb +0 -0
  282. data/lib/ffi/callback.rb +10 -0
  283. data/lib/ffi/enum.rb +78 -0
  284. data/lib/ffi/errno.rb +8 -0
  285. data/lib/ffi/ffi.rb +99 -0
  286. data/lib/ffi/io.rb +21 -0
  287. data/lib/ffi/library.rb +218 -0
  288. data/lib/ffi/managedstruct.rb +55 -0
  289. data/lib/ffi/memorypointer.rb +73 -0
  290. data/lib/ffi/platform.rb +78 -0
  291. data/lib/ffi/pointer.rb +119 -0
  292. data/lib/ffi/struct.rb +164 -0
  293. data/lib/ffi/tools/const_generator.rb +177 -0
  294. data/lib/ffi/tools/generator.rb +58 -0
  295. data/lib/ffi/tools/generator_task.rb +35 -0
  296. data/lib/ffi/tools/struct_generator.rb +194 -0
  297. data/lib/ffi/tools/types_generator.rb +123 -0
  298. data/lib/ffi/types.rb +153 -0
  299. data/lib/ffi/union.rb +12 -0
  300. data/lib/ffi/variadic.rb +25 -0
  301. data/spec/ffi/bool_spec.rb +24 -0
  302. data/spec/ffi/buffer_spec.rb +202 -0
  303. data/spec/ffi/callback_spec.rb +591 -0
  304. data/spec/ffi/enum_spec.rb +164 -0
  305. data/spec/ffi/errno_spec.rb +13 -0
  306. data/spec/ffi/function_spec.rb +47 -0
  307. data/spec/ffi/library_spec.rb +144 -0
  308. data/spec/ffi/managed_struct_spec.rb +56 -0
  309. data/spec/ffi/number_spec.rb +231 -0
  310. data/spec/ffi/pointer_spec.rb +195 -0
  311. data/spec/ffi/rbx/attach_function_spec.rb +27 -0
  312. data/spec/ffi/rbx/memory_pointer_spec.rb +102 -0
  313. data/spec/ffi/rbx/spec_helper.rb +1 -0
  314. data/spec/ffi/rbx/struct_spec.rb +13 -0
  315. data/spec/ffi/spec_helper.rb +17 -0
  316. data/spec/ffi/string_spec.rb +103 -0
  317. data/spec/ffi/struct_callback_spec.rb +62 -0
  318. data/spec/ffi/struct_initialize_spec.rb +30 -0
  319. data/spec/ffi/struct_spec.rb +529 -0
  320. data/spec/ffi/typedef_spec.rb +48 -0
  321. data/spec/ffi/union_spec.rb +60 -0
  322. data/spec/ffi/variadic_spec.rb +84 -0
  323. data/spec/spec.opts +4 -0
  324. metadata +432 -0
@@ -0,0 +1,174 @@
1
+ /* -----------------------------------------------------------------------
2
+ prep_cif.c - Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
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
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
+ DEALINGS IN THE SOFTWARE.
23
+ ----------------------------------------------------------------------- */
24
+
25
+ #include <ffi.h>
26
+ #include <ffi_common.h>
27
+ #include <stdlib.h>
28
+
29
+ /* Round up to FFI_SIZEOF_ARG. */
30
+
31
+ #define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
32
+
33
+ /* Perform machine independent initialization of aggregate type
34
+ specifications. */
35
+
36
+ static ffi_status initialize_aggregate(ffi_type *arg)
37
+ {
38
+ ffi_type **ptr;
39
+
40
+ FFI_ASSERT(arg != NULL);
41
+
42
+ FFI_ASSERT(arg->elements != NULL);
43
+ FFI_ASSERT(arg->size == 0);
44
+ FFI_ASSERT(arg->alignment == 0);
45
+
46
+ ptr = &(arg->elements[0]);
47
+
48
+ while ((*ptr) != NULL)
49
+ {
50
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
51
+ return FFI_BAD_TYPEDEF;
52
+
53
+ /* Perform a sanity check on the argument type */
54
+ FFI_ASSERT_VALID_TYPE(*ptr);
55
+
56
+ arg->size = ALIGN(arg->size, (*ptr)->alignment);
57
+ arg->size += (*ptr)->size;
58
+
59
+ arg->alignment = (arg->alignment > (*ptr)->alignment) ?
60
+ arg->alignment : (*ptr)->alignment;
61
+
62
+ ptr++;
63
+ }
64
+
65
+ /* Structure size includes tail padding. This is important for
66
+ structures that fit in one register on ABIs like the PowerPC64
67
+ Linux ABI that right justify small structs in a register.
68
+ It's also needed for nested structure layout, for example
69
+ struct A { long a; char b; }; struct B { struct A x; char y; };
70
+ should find y at an offset of 2*sizeof(long) and result in a
71
+ total size of 3*sizeof(long). */
72
+ arg->size = ALIGN (arg->size, arg->alignment);
73
+
74
+ if (arg->size == 0)
75
+ return FFI_BAD_TYPEDEF;
76
+ else
77
+ return FFI_OK;
78
+ }
79
+
80
+ #ifndef __CRIS__
81
+ /* The CRIS ABI specifies structure elements to have byte
82
+ alignment only, so it completely overrides this functions,
83
+ which assumes "natural" alignment and padding. */
84
+
85
+ /* Perform machine independent ffi_cif preparation, then call
86
+ machine dependent routine. */
87
+
88
+ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
89
+ ffi_type *rtype, ffi_type **atypes)
90
+ {
91
+ unsigned bytes = 0;
92
+ unsigned int i;
93
+ ffi_type **ptr;
94
+
95
+ FFI_ASSERT(cif != NULL);
96
+ FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
97
+
98
+ cif->abi = abi;
99
+ cif->arg_types = atypes;
100
+ cif->nargs = nargs;
101
+ cif->rtype = rtype;
102
+
103
+ cif->flags = 0;
104
+
105
+ /* Initialize the return type if necessary */
106
+ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
107
+ return FFI_BAD_TYPEDEF;
108
+
109
+ /* Perform a sanity check on the return type */
110
+ FFI_ASSERT_VALID_TYPE(cif->rtype);
111
+
112
+ /* x86-64 and s390 stack space allocation is handled in prep_machdep. */
113
+ #if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
114
+ /* Make space for the return structure pointer */
115
+ if (cif->rtype->type == FFI_TYPE_STRUCT
116
+ #ifdef SPARC
117
+ && (cif->abi != FFI_V9 || cif->rtype->size > 32)
118
+ #endif
119
+ #ifdef X86_DARWIN
120
+ && (cif->rtype->size > 8)
121
+ #endif
122
+ )
123
+ bytes = STACK_ARG_SIZE(sizeof(void*));
124
+ #endif
125
+
126
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
127
+ {
128
+
129
+ /* Initialize any uninitialized aggregate type definitions */
130
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
131
+ return FFI_BAD_TYPEDEF;
132
+
133
+ /* Perform a sanity check on the argument type, do this
134
+ check after the initialization. */
135
+ FFI_ASSERT_VALID_TYPE(*ptr);
136
+
137
+ #if !defined __x86_64__ && !defined S390 && !defined PA
138
+ #ifdef SPARC
139
+ if (((*ptr)->type == FFI_TYPE_STRUCT
140
+ && ((*ptr)->size > 16 || cif->abi != FFI_V9))
141
+ || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
142
+ && cif->abi != FFI_V9))
143
+ bytes += sizeof(void*);
144
+ else
145
+ #endif
146
+ {
147
+ /* Add any padding if necessary */
148
+ if (((*ptr)->alignment - 1) & bytes)
149
+ bytes = ALIGN(bytes, (*ptr)->alignment);
150
+
151
+ bytes += STACK_ARG_SIZE((*ptr)->size);
152
+ }
153
+ #endif
154
+ }
155
+
156
+ cif->bytes = bytes;
157
+
158
+ /* Perform machine dependent cif processing */
159
+ return ffi_prep_cif_machdep(cif);
160
+ }
161
+ #endif /* not __CRIS__ */
162
+
163
+ #if FFI_CLOSURES
164
+
165
+ ffi_status
166
+ ffi_prep_closure (ffi_closure* closure,
167
+ ffi_cif* cif,
168
+ void (*fun)(ffi_cif*,void*,void**,void*),
169
+ void *user_data)
170
+ {
171
+ return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
172
+ }
173
+
174
+ #endif
@@ -0,0 +1,254 @@
1
+ /* -----------------------------------------------------------------------
2
+ raw_api.c - Copyright (c) 1999, 2008 Red Hat, Inc.
3
+
4
+ Author: Kresten Krab Thorup <krab@gnu.org>
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ ``Software''), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included
15
+ in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ DEALINGS IN THE SOFTWARE.
25
+ ----------------------------------------------------------------------- */
26
+
27
+ /* This file defines generic functions for use with the raw api. */
28
+
29
+ #include <ffi.h>
30
+ #include <ffi_common.h>
31
+
32
+ #if !FFI_NO_RAW_API
33
+
34
+ size_t
35
+ ffi_raw_size (ffi_cif *cif)
36
+ {
37
+ size_t result = 0;
38
+ int i;
39
+
40
+ ffi_type **at = cif->arg_types;
41
+
42
+ for (i = cif->nargs-1; i >= 0; i--, at++)
43
+ {
44
+ #if !FFI_NO_STRUCTS
45
+ if ((*at)->type == FFI_TYPE_STRUCT)
46
+ result += ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
47
+ else
48
+ #endif
49
+ result += ALIGN ((*at)->size, FFI_SIZEOF_ARG);
50
+ }
51
+
52
+ return result;
53
+ }
54
+
55
+
56
+ void
57
+ ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
58
+ {
59
+ unsigned i;
60
+ ffi_type **tp = cif->arg_types;
61
+
62
+ #if WORDS_BIGENDIAN
63
+
64
+ for (i = 0; i < cif->nargs; i++, tp++, args++)
65
+ {
66
+ switch ((*tp)->type)
67
+ {
68
+ case FFI_TYPE_UINT8:
69
+ case FFI_TYPE_SINT8:
70
+ *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 1);
71
+ break;
72
+
73
+ case FFI_TYPE_UINT16:
74
+ case FFI_TYPE_SINT16:
75
+ *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 2);
76
+ break;
77
+
78
+ #if FFI_SIZEOF_ARG >= 4
79
+ case FFI_TYPE_UINT32:
80
+ case FFI_TYPE_SINT32:
81
+ *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 4);
82
+ break;
83
+ #endif
84
+
85
+ #if !FFI_NO_STRUCTS
86
+ case FFI_TYPE_STRUCT:
87
+ *args = (raw++)->ptr;
88
+ break;
89
+ #endif
90
+
91
+ case FFI_TYPE_POINTER:
92
+ *args = (void*) &(raw++)->ptr;
93
+ break;
94
+
95
+ default:
96
+ *args = raw;
97
+ raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
98
+ }
99
+ }
100
+
101
+ #else /* WORDS_BIGENDIAN */
102
+
103
+ #if !PDP
104
+
105
+ /* then assume little endian */
106
+ for (i = 0; i < cif->nargs; i++, tp++, args++)
107
+ {
108
+ #if !FFI_NO_STRUCTS
109
+ if ((*tp)->type == FFI_TYPE_STRUCT)
110
+ {
111
+ *args = (raw++)->ptr;
112
+ }
113
+ else
114
+ #endif
115
+ {
116
+ *args = (void*) raw;
117
+ raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
118
+ }
119
+ }
120
+
121
+ #else
122
+ #error "pdp endian not supported"
123
+ #endif /* ! PDP */
124
+
125
+ #endif /* WORDS_BIGENDIAN */
126
+ }
127
+
128
+ void
129
+ ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
130
+ {
131
+ unsigned i;
132
+ ffi_type **tp = cif->arg_types;
133
+
134
+ for (i = 0; i < cif->nargs; i++, tp++, args++)
135
+ {
136
+ switch ((*tp)->type)
137
+ {
138
+ case FFI_TYPE_UINT8:
139
+ (raw++)->uint = *(UINT8*) (*args);
140
+ break;
141
+
142
+ case FFI_TYPE_SINT8:
143
+ (raw++)->sint = *(SINT8*) (*args);
144
+ break;
145
+
146
+ case FFI_TYPE_UINT16:
147
+ (raw++)->uint = *(UINT16*) (*args);
148
+ break;
149
+
150
+ case FFI_TYPE_SINT16:
151
+ (raw++)->sint = *(SINT16*) (*args);
152
+ break;
153
+
154
+ #if FFI_SIZEOF_ARG >= 4
155
+ case FFI_TYPE_UINT32:
156
+ (raw++)->uint = *(UINT32*) (*args);
157
+ break;
158
+
159
+ case FFI_TYPE_SINT32:
160
+ (raw++)->sint = *(SINT32*) (*args);
161
+ break;
162
+ #endif
163
+
164
+ #if !FFI_NO_STRUCTS
165
+ case FFI_TYPE_STRUCT:
166
+ (raw++)->ptr = *args;
167
+ break;
168
+ #endif
169
+
170
+ case FFI_TYPE_POINTER:
171
+ (raw++)->ptr = **(void***) args;
172
+ break;
173
+
174
+ default:
175
+ memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
176
+ raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
177
+ }
178
+ }
179
+ }
180
+
181
+ #if !FFI_NATIVE_RAW_API
182
+
183
+
184
+ /* This is a generic definition of ffi_raw_call, to be used if the
185
+ * native system does not provide a machine-specific implementation.
186
+ * Having this, allows code to be written for the raw API, without
187
+ * the need for system-specific code to handle input in that format;
188
+ * these following couple of functions will handle the translation forth
189
+ * and back automatically. */
190
+
191
+ void ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw)
192
+ {
193
+ void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
194
+ ffi_raw_to_ptrarray (cif, raw, avalue);
195
+ ffi_call (cif, fn, rvalue, avalue);
196
+ }
197
+
198
+ #if FFI_CLOSURES /* base system provides closures */
199
+
200
+ static void
201
+ ffi_translate_args (ffi_cif *cif, void *rvalue,
202
+ void **avalue, void *user_data)
203
+ {
204
+ ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif));
205
+ ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
206
+
207
+ ffi_ptrarray_to_raw (cif, avalue, raw);
208
+ (*cl->fun) (cif, rvalue, raw, cl->user_data);
209
+ }
210
+
211
+ ffi_status
212
+ ffi_prep_raw_closure_loc (ffi_raw_closure* cl,
213
+ ffi_cif *cif,
214
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
215
+ void *user_data,
216
+ void *codeloc)
217
+ {
218
+ ffi_status status;
219
+
220
+ status = ffi_prep_closure_loc ((ffi_closure*) cl,
221
+ cif,
222
+ &ffi_translate_args,
223
+ codeloc,
224
+ codeloc);
225
+ if (status == FFI_OK)
226
+ {
227
+ cl->fun = fun;
228
+ cl->user_data = user_data;
229
+ }
230
+
231
+ return status;
232
+ }
233
+
234
+ #endif /* FFI_CLOSURES */
235
+ #endif /* !FFI_NATIVE_RAW_API */
236
+
237
+ #if FFI_CLOSURES
238
+
239
+ /* Again, here is the generic version of ffi_prep_raw_closure, which
240
+ * will install an intermediate "hub" for translation of arguments from
241
+ * the pointer-array format, to the raw format */
242
+
243
+ ffi_status
244
+ ffi_prep_raw_closure (ffi_raw_closure* cl,
245
+ ffi_cif *cif,
246
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
247
+ void *user_data)
248
+ {
249
+ return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl);
250
+ }
251
+
252
+ #endif /* FFI_CLOSURES */
253
+
254
+ #endif /* !FFI_NO_RAW_API */
@@ -0,0 +1,780 @@
1
+ /* -----------------------------------------------------------------------
2
+ ffi.c - Copyright (c) 2000, 2007 Software AG
3
+ Copyright (c) 2008 Red Hat, Inc
4
+
5
+ S390 Foreign Function Interface
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining
8
+ a copy of this software and associated documentation files (the
9
+ ``Software''), to deal in the Software without restriction, including
10
+ without limitation the rights to use, copy, modify, merge, publish,
11
+ distribute, sublicense, and/or sell copies of the Software, and to
12
+ permit persons to whom the Software is furnished to do so, subject to
13
+ the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included
16
+ in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
22
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+ OTHER DEALINGS IN THE SOFTWARE.
25
+ ----------------------------------------------------------------------- */
26
+ /*====================================================================*/
27
+ /* Includes */
28
+ /* -------- */
29
+ /*====================================================================*/
30
+
31
+ #include <ffi.h>
32
+ #include <ffi_common.h>
33
+
34
+ #include <stdlib.h>
35
+ #include <stdio.h>
36
+
37
+ /*====================== End of Includes =============================*/
38
+
39
+ /*====================================================================*/
40
+ /* Defines */
41
+ /* ------- */
42
+ /*====================================================================*/
43
+
44
+ /* Maximum number of GPRs available for argument passing. */
45
+ #define MAX_GPRARGS 5
46
+
47
+ /* Maximum number of FPRs available for argument passing. */
48
+ #ifdef __s390x__
49
+ #define MAX_FPRARGS 4
50
+ #else
51
+ #define MAX_FPRARGS 2
52
+ #endif
53
+
54
+ /* Round to multiple of 16. */
55
+ #define ROUND_SIZE(size) (((size) + 15) & ~15)
56
+
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
+ /*===================== 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
+
80
+ /*====================== End of Prototypes ===========================*/
81
+
82
+ /*====================================================================*/
83
+ /* Externals */
84
+ /* --------- */
85
+ /*====================================================================*/
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));
93
+
94
+ extern void ffi_closure_SYSV(void);
95
+
96
+ /*====================== End of Externals ============================*/
97
+
98
+ /*====================================================================*/
99
+ /* */
100
+ /* Name - ffi_check_struct_type. */
101
+ /* */
102
+ /* Function - Determine if a structure can be passed within a */
103
+ /* general purpose or floating point register. */
104
+ /* */
105
+ /*====================================================================*/
106
+
107
+ static int
108
+ ffi_check_struct_type (ffi_type *arg)
109
+ {
110
+ size_t size = arg->size;
111
+
112
+ /* If the struct has just one element, look at that element
113
+ to find out whether to consider the struct as floating point. */
114
+ while (arg->type == FFI_TYPE_STRUCT
115
+ && arg->elements[0] && !arg->elements[1])
116
+ arg = arg->elements[0];
117
+
118
+ /* Structs of size 1, 2, 4, and 8 are passed in registers,
119
+ just like the corresponding int/float types. */
120
+ switch (size)
121
+ {
122
+ case 1:
123
+ return FFI_TYPE_UINT8;
124
+
125
+ case 2:
126
+ return FFI_TYPE_UINT16;
127
+
128
+ case 4:
129
+ if (arg->type == FFI_TYPE_FLOAT)
130
+ return FFI_TYPE_FLOAT;
131
+ else
132
+ return FFI_TYPE_UINT32;
133
+
134
+ case 8:
135
+ if (arg->type == FFI_TYPE_DOUBLE)
136
+ return FFI_TYPE_DOUBLE;
137
+ else
138
+ return FFI_TYPE_UINT64;
139
+
140
+ default:
141
+ break;
142
+ }
143
+
144
+ /* Other structs are passed via a pointer to the data. */
145
+ return FFI_TYPE_POINTER;
146
+ }
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
+
329
+ /*======================== End of Routine ============================*/
330
+
331
+ /*====================================================================*/
332
+ /* */
333
+ /* Name - ffi_prep_cif_machdep. */
334
+ /* */
335
+ /* Function - Perform machine dependent CIF processing. */
336
+ /* */
337
+ /*====================================================================*/
338
+
339
+ ffi_status
340
+ ffi_prep_cif_machdep(ffi_cif *cif)
341
+ {
342
+ size_t struct_size = 0;
343
+ int n_gpr = 0;
344
+ int n_fpr = 0;
345
+ int n_ov = 0;
346
+
347
+ ffi_type **ptr;
348
+ int i;
349
+
350
+ /* Determine return value handling. */
351
+
352
+ switch (cif->rtype->type)
353
+ {
354
+ /* Void is easy. */
355
+ case FFI_TYPE_VOID:
356
+ cif->flags = FFI390_RET_VOID;
357
+ break;
358
+
359
+ /* Structures are returned via a hidden pointer. */
360
+ case FFI_TYPE_STRUCT:
361
+ cif->flags = FFI390_RET_STRUCT;
362
+ n_gpr++; /* We need one GPR to pass the pointer. */
363
+ break;
364
+
365
+ /* Floating point values are returned in fpr 0. */
366
+ case FFI_TYPE_FLOAT:
367
+ cif->flags = FFI390_RET_FLOAT;
368
+ break;
369
+
370
+ case FFI_TYPE_DOUBLE:
371
+ cif->flags = FFI390_RET_DOUBLE;
372
+ break;
373
+
374
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
375
+ case FFI_TYPE_LONGDOUBLE:
376
+ cif->flags = FFI390_RET_STRUCT;
377
+ n_gpr++;
378
+ break;
379
+ #endif
380
+ /* Integer values are returned in gpr 2 (and gpr 3
381
+ for 64-bit values on 31-bit machines). */
382
+ case FFI_TYPE_UINT64:
383
+ case FFI_TYPE_SINT64:
384
+ cif->flags = FFI390_RET_INT64;
385
+ break;
386
+
387
+ case FFI_TYPE_POINTER:
388
+ case FFI_TYPE_INT:
389
+ case FFI_TYPE_UINT32:
390
+ case FFI_TYPE_SINT32:
391
+ case FFI_TYPE_UINT16:
392
+ case FFI_TYPE_SINT16:
393
+ case FFI_TYPE_UINT8:
394
+ case FFI_TYPE_SINT8:
395
+ /* These are to be extended to word size. */
396
+ #ifdef __s390x__
397
+ cif->flags = FFI390_RET_INT64;
398
+ #else
399
+ cif->flags = FFI390_RET_INT32;
400
+ #endif
401
+ break;
402
+
403
+ default:
404
+ FFI_ASSERT (0);
405
+ break;
406
+ }
407
+
408
+ /* Now for the arguments. */
409
+
410
+ for (ptr = cif->arg_types, i = cif->nargs;
411
+ i > 0;
412
+ i--, ptr++)
413
+ {
414
+ int type = (*ptr)->type;
415
+
416
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
417
+ /* 16-byte long double is passed like a struct. */
418
+ if (type == FFI_TYPE_LONGDOUBLE)
419
+ type = FFI_TYPE_STRUCT;
420
+ #endif
421
+
422
+ /* Check how a structure type is passed. */
423
+ if (type == FFI_TYPE_STRUCT)
424
+ {
425
+ type = ffi_check_struct_type (*ptr);
426
+
427
+ /* If we pass the struct via pointer, we must reserve space
428
+ to copy its data for proper call-by-value semantics. */
429
+ if (type == FFI_TYPE_POINTER)
430
+ struct_size += ROUND_SIZE ((*ptr)->size);
431
+ }
432
+
433
+ /* Now handle all primitive int/float data types. */
434
+ switch (type)
435
+ {
436
+ /* The first MAX_FPRARGS floating point arguments
437
+ go in FPRs, the rest overflow to the stack. */
438
+
439
+ case FFI_TYPE_DOUBLE:
440
+ if (n_fpr < MAX_FPRARGS)
441
+ n_fpr++;
442
+ else
443
+ n_ov += sizeof (double) / sizeof (long);
444
+ break;
445
+
446
+ case FFI_TYPE_FLOAT:
447
+ if (n_fpr < MAX_FPRARGS)
448
+ n_fpr++;
449
+ else
450
+ n_ov++;
451
+ break;
452
+
453
+ /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
454
+ 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
456
+ subsequent argument either). */
457
+
458
+ #ifndef __s390x__
459
+ case FFI_TYPE_UINT64:
460
+ case FFI_TYPE_SINT64:
461
+ if (n_gpr == MAX_GPRARGS-1)
462
+ n_gpr = MAX_GPRARGS;
463
+ if (n_gpr < MAX_GPRARGS)
464
+ n_gpr += 2;
465
+ else
466
+ n_ov += 2;
467
+ break;
468
+ #endif
469
+
470
+ /* Everything else is passed in GPRs (until MAX_GPRARGS
471
+ have been used) or overflows to the stack. */
472
+
473
+ default:
474
+ if (n_gpr < MAX_GPRARGS)
475
+ n_gpr++;
476
+ else
477
+ n_ov++;
478
+ break;
479
+ }
480
+ }
481
+
482
+ /* Total stack space as required for overflow arguments
483
+ and temporary structure copies. */
484
+
485
+ cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
486
+
487
+ return FFI_OK;
488
+ }
489
+
490
+ /*======================== End of Routine ============================*/
491
+
492
+ /*====================================================================*/
493
+ /* */
494
+ /* Name - ffi_call. */
495
+ /* */
496
+ /* Function - Call the FFI routine. */
497
+ /* */
498
+ /*====================================================================*/
499
+
500
+ void
501
+ ffi_call(ffi_cif *cif,
502
+ void (*fn)(void),
503
+ void *rvalue,
504
+ void **avalue)
505
+ {
506
+ int ret_type = cif->flags;
507
+ extended_cif ecif;
508
+
509
+ ecif.cif = cif;
510
+ ecif.avalue = avalue;
511
+ ecif.rvalue = rvalue;
512
+
513
+ /* If we don't have a return value, we need to fake one. */
514
+ if (rvalue == NULL)
515
+ {
516
+ if (ret_type == FFI390_RET_STRUCT)
517
+ ecif.rvalue = alloca (cif->rtype->size);
518
+ else
519
+ ret_type = FFI390_RET_VOID;
520
+ }
521
+
522
+ switch (cif->abi)
523
+ {
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;
532
+ }
533
+ }
534
+
535
+ /*======================== End of Routine ============================*/
536
+
537
+ /*====================================================================*/
538
+ /* */
539
+ /* Name - ffi_closure_helper_SYSV. */
540
+ /* */
541
+ /* Function - Call a FFI closure target function. */
542
+ /* */
543
+ /*====================================================================*/
544
+
545
+ void
546
+ ffi_closure_helper_SYSV (ffi_closure *closure,
547
+ unsigned long *p_gpr,
548
+ unsigned long long *p_fpr,
549
+ unsigned long *p_ov)
550
+ {
551
+ unsigned long long ret_buffer;
552
+
553
+ void *rvalue = &ret_buffer;
554
+ void **avalue;
555
+ void **p_arg;
556
+
557
+ int n_gpr = 0;
558
+ int n_fpr = 0;
559
+ int n_ov = 0;
560
+
561
+ ffi_type **ptr;
562
+ int i;
563
+
564
+ /* Allocate buffer for argument list pointers. */
565
+
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
570
+ function store the return value to the GPR save area. */
571
+
572
+ if (closure->cif->flags == FFI390_RET_STRUCT)
573
+ rvalue = (void *) p_gpr[n_gpr++];
574
+
575
+ /* Now for the arguments. */
576
+
577
+ for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
578
+ i > 0;
579
+ i--, p_arg++, ptr++)
580
+ {
581
+ int deref_struct_pointer = 0;
582
+ int type = (*ptr)->type;
583
+
584
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
585
+ /* 16-byte long double is passed like a struct. */
586
+ if (type == FFI_TYPE_LONGDOUBLE)
587
+ type = FFI_TYPE_STRUCT;
588
+ #endif
589
+
590
+ /* Check how a structure type is passed. */
591
+ if (type == FFI_TYPE_STRUCT)
592
+ {
593
+ type = ffi_check_struct_type (*ptr);
594
+
595
+ /* If we pass the struct via pointer, remember to
596
+ retrieve the pointer later. */
597
+ if (type == FFI_TYPE_POINTER)
598
+ deref_struct_pointer = 1;
599
+ }
600
+
601
+ /* Pointers are passed like UINTs of the same size. */
602
+ if (type == FFI_TYPE_POINTER)
603
+ #ifdef __s390x__
604
+ type = FFI_TYPE_UINT64;
605
+ #else
606
+ type = FFI_TYPE_UINT32;
607
+ #endif
608
+
609
+ /* Now handle all primitive int/float data types. */
610
+ switch (type)
611
+ {
612
+ case FFI_TYPE_DOUBLE:
613
+ if (n_fpr < MAX_FPRARGS)
614
+ *p_arg = &p_fpr[n_fpr++];
615
+ else
616
+ *p_arg = &p_ov[n_ov],
617
+ n_ov += sizeof (double) / sizeof (long);
618
+ break;
619
+
620
+ case FFI_TYPE_FLOAT:
621
+ if (n_fpr < MAX_FPRARGS)
622
+ *p_arg = &p_fpr[n_fpr++];
623
+ else
624
+ *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
625
+ break;
626
+
627
+ case FFI_TYPE_UINT64:
628
+ case FFI_TYPE_SINT64:
629
+ #ifdef __s390x__
630
+ if (n_gpr < MAX_GPRARGS)
631
+ *p_arg = &p_gpr[n_gpr++];
632
+ else
633
+ *p_arg = &p_ov[n_ov++];
634
+ #else
635
+ if (n_gpr == MAX_GPRARGS-1)
636
+ n_gpr = MAX_GPRARGS;
637
+ if (n_gpr < MAX_GPRARGS)
638
+ *p_arg = &p_gpr[n_gpr], n_gpr += 2;
639
+ else
640
+ *p_arg = &p_ov[n_ov], n_ov += 2;
641
+ #endif
642
+ break;
643
+
644
+ case FFI_TYPE_INT:
645
+ case FFI_TYPE_UINT32:
646
+ case FFI_TYPE_SINT32:
647
+ if (n_gpr < MAX_GPRARGS)
648
+ *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
649
+ else
650
+ *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
651
+ break;
652
+
653
+ case FFI_TYPE_UINT16:
654
+ case FFI_TYPE_SINT16:
655
+ if (n_gpr < MAX_GPRARGS)
656
+ *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
657
+ else
658
+ *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
659
+ break;
660
+
661
+ case FFI_TYPE_UINT8:
662
+ case FFI_TYPE_SINT8:
663
+ if (n_gpr < MAX_GPRARGS)
664
+ *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
665
+ else
666
+ *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
667
+ break;
668
+
669
+ default:
670
+ FFI_ASSERT (0);
671
+ break;
672
+ }
673
+
674
+ /* If this is a struct passed via pointer, we need to
675
+ actually retrieve that pointer. */
676
+ if (deref_struct_pointer)
677
+ *p_arg = *(void **)*p_arg;
678
+ }
679
+
680
+
681
+ /* Call the target function. */
682
+ (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
683
+
684
+ /* Convert the return value. */
685
+ switch (closure->cif->rtype->type)
686
+ {
687
+ /* Void is easy, and so is struct. */
688
+ case FFI_TYPE_VOID:
689
+ case FFI_TYPE_STRUCT:
690
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
691
+ case FFI_TYPE_LONGDOUBLE:
692
+ #endif
693
+ break;
694
+
695
+ /* Floating point values are returned in fpr 0. */
696
+ case FFI_TYPE_FLOAT:
697
+ p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
698
+ break;
699
+
700
+ case FFI_TYPE_DOUBLE:
701
+ p_fpr[0] = *(unsigned long long *) rvalue;
702
+ break;
703
+
704
+ /* Integer values are returned in gpr 2 (and gpr 3
705
+ for 64-bit values on 31-bit machines). */
706
+ case FFI_TYPE_UINT64:
707
+ case FFI_TYPE_SINT64:
708
+ #ifdef __s390x__
709
+ p_gpr[0] = *(unsigned long *) rvalue;
710
+ #else
711
+ p_gpr[0] = ((unsigned long *) rvalue)[0],
712
+ p_gpr[1] = ((unsigned long *) rvalue)[1];
713
+ #endif
714
+ break;
715
+
716
+ case FFI_TYPE_POINTER:
717
+ case FFI_TYPE_UINT32:
718
+ case FFI_TYPE_UINT16:
719
+ case FFI_TYPE_UINT8:
720
+ p_gpr[0] = *(unsigned long *) rvalue;
721
+ break;
722
+
723
+ case FFI_TYPE_INT:
724
+ case FFI_TYPE_SINT32:
725
+ case FFI_TYPE_SINT16:
726
+ case FFI_TYPE_SINT8:
727
+ p_gpr[0] = *(signed long *) rvalue;
728
+ break;
729
+
730
+ default:
731
+ FFI_ASSERT (0);
732
+ break;
733
+ }
734
+ }
735
+
736
+ /*======================== End of Routine ============================*/
737
+
738
+ /*====================================================================*/
739
+ /* */
740
+ /* Name - ffi_prep_closure_loc. */
741
+ /* */
742
+ /* Function - Prepare a FFI closure. */
743
+ /* */
744
+ /*====================================================================*/
745
+
746
+ ffi_status
747
+ ffi_prep_closure_loc (ffi_closure *closure,
748
+ ffi_cif *cif,
749
+ void (*fun) (ffi_cif *, void *, void **, void *),
750
+ void *user_data,
751
+ void *codeloc)
752
+ {
753
+ FFI_ASSERT (cif->abi == FFI_SYSV);
754
+
755
+ #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;
762
+ #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
+
772
+ closure->cif = cif;
773
+ closure->user_data = user_data;
774
+ closure->fun = fun;
775
+
776
+ return FFI_OK;
777
+ }
778
+
779
+ /*======================== End of Routine ============================*/
780
+