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,800 @@
1
+ /* -----------------------------------------------------------------------
2
+ ffi_darwin.c
3
+
4
+ Copyright (C) 1998 Geoffrey Keating
5
+ Copyright (C) 2001 John Hornkvist
6
+ Copyright (C) 2002, 2006, 2007 Free Software Foundation, Inc.
7
+
8
+ FFI support for Darwin and AIX.
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining
11
+ a copy of this software and associated documentation files (the
12
+ ``Software''), to deal in the Software without restriction, including
13
+ without limitation the rights to use, copy, modify, merge, publish,
14
+ distribute, sublicense, and/or sell copies of the Software, and to
15
+ permit persons to whom the Software is furnished to do so, subject to
16
+ the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included
19
+ in all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
25
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27
+ OTHER DEALINGS IN THE SOFTWARE.
28
+ ----------------------------------------------------------------------- */
29
+
30
+ #include <ffi.h>
31
+ #include <ffi_common.h>
32
+
33
+ #include <stdlib.h>
34
+
35
+ extern void ffi_closure_ASM(void);
36
+
37
+ enum {
38
+ /* The assembly depends on these exact flags. */
39
+ FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
40
+ FLAG_RETURNS_FP = 1 << (31-29),
41
+ FLAG_RETURNS_64BITS = 1 << (31-28),
42
+ FLAG_RETURNS_128BITS = 1 << (31-31),
43
+
44
+ FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
45
+ FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
46
+ FLAG_4_GPR_ARGUMENTS = 1 << (31- 5),
47
+ FLAG_RETVAL_REFERENCE = 1 << (31- 4)
48
+ };
49
+
50
+ /* About the DARWIN ABI. */
51
+ enum {
52
+ NUM_GPR_ARG_REGISTERS = 8,
53
+ NUM_FPR_ARG_REGISTERS = 13
54
+ };
55
+ enum { ASM_NEEDS_REGISTERS = 4 };
56
+
57
+ /* ffi_prep_args is called by the assembly routine once stack space
58
+ has been allocated for the function's arguments.
59
+
60
+ The stack layout we want looks like this:
61
+
62
+ | Return address from ffi_call_DARWIN | higher addresses
63
+ |--------------------------------------------|
64
+ | Previous backchain pointer 4 | stack pointer here
65
+ |--------------------------------------------|<+ <<< on entry to
66
+ | Saved r28-r31 4*4 | | ffi_call_DARWIN
67
+ |--------------------------------------------| |
68
+ | Parameters (at least 8*4=32) | |
69
+ |--------------------------------------------| |
70
+ | Space for GPR2 4 | |
71
+ |--------------------------------------------| | stack |
72
+ | Reserved 2*4 | | grows |
73
+ |--------------------------------------------| | down V
74
+ | Space for callee's LR 4 | |
75
+ |--------------------------------------------| | lower addresses
76
+ | Saved CR 4 | |
77
+ |--------------------------------------------| | stack pointer here
78
+ | Current backchain pointer 4 |-/ during
79
+ |--------------------------------------------| <<< ffi_call_DARWIN
80
+
81
+ */
82
+
83
+ void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
84
+ {
85
+ const unsigned bytes = ecif->cif->bytes;
86
+ const unsigned flags = ecif->cif->flags;
87
+
88
+ /* 'stacktop' points at the previous backchain pointer. */
89
+ unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
90
+
91
+ /* 'fpr_base' points at the space for fpr1, and grows upwards as
92
+ we use FPR registers. */
93
+ double *fpr_base = (double*) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
94
+ int fparg_count = 0;
95
+
96
+
97
+ /* 'next_arg' grows up as we put parameters in it. */
98
+ unsigned *next_arg = stack + 6; /* 6 reserved positions. */
99
+
100
+ int i = ecif->cif->nargs;
101
+ double double_tmp;
102
+ void **p_argv = ecif->avalue;
103
+ unsigned gprvalue;
104
+ ffi_type** ptr = ecif->cif->arg_types;
105
+ char *dest_cpy;
106
+ unsigned size_al = 0;
107
+
108
+ /* Check that everything starts aligned properly. */
109
+ FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
110
+ FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
111
+ FFI_ASSERT((bytes & 0xF) == 0);
112
+
113
+ /* Deal with return values that are actually pass-by-reference.
114
+ Rule:
115
+ Return values are referenced by r3, so r4 is the first parameter. */
116
+
117
+ if (flags & FLAG_RETVAL_REFERENCE)
118
+ *next_arg++ = (unsigned)(char *)ecif->rvalue;
119
+
120
+ /* Now for the arguments. */
121
+ for (;
122
+ i > 0;
123
+ i--, ptr++, p_argv++)
124
+ {
125
+ switch ((*ptr)->type)
126
+ {
127
+ /* If a floating-point parameter appears before all of the general-
128
+ purpose registers are filled, the corresponding GPRs that match
129
+ the size of the floating-point parameter are skipped. */
130
+ case FFI_TYPE_FLOAT:
131
+ double_tmp = *(float *)*p_argv;
132
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
133
+ *(double *)next_arg = double_tmp;
134
+ else
135
+ *fpr_base++ = double_tmp;
136
+ next_arg++;
137
+ fparg_count++;
138
+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
139
+ break;
140
+
141
+ case FFI_TYPE_DOUBLE:
142
+ double_tmp = *(double *)*p_argv;
143
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
144
+ *(double *)next_arg = double_tmp;
145
+ else
146
+ *fpr_base++ = double_tmp;
147
+ next_arg += 2;
148
+ fparg_count++;
149
+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
150
+ break;
151
+
152
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
153
+
154
+ case FFI_TYPE_LONGDOUBLE:
155
+ double_tmp = ((double *)*p_argv)[0];
156
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
157
+ *(double *)next_arg = double_tmp;
158
+ else
159
+ *fpr_base++ = double_tmp;
160
+ next_arg += 2;
161
+ fparg_count++;
162
+ double_tmp = ((double *)*p_argv)[1];
163
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
164
+ *(double *)next_arg = double_tmp;
165
+ else
166
+ *fpr_base++ = double_tmp;
167
+ next_arg += 2;
168
+ fparg_count++;
169
+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
170
+ break;
171
+ #endif
172
+ case FFI_TYPE_UINT64:
173
+ case FFI_TYPE_SINT64:
174
+ *(long long *)next_arg = *(long long *)*p_argv;
175
+ next_arg+=2;
176
+ break;
177
+ case FFI_TYPE_UINT8:
178
+ gprvalue = *(unsigned char *)*p_argv;
179
+ goto putgpr;
180
+ case FFI_TYPE_SINT8:
181
+ gprvalue = *(signed char *)*p_argv;
182
+ goto putgpr;
183
+ case FFI_TYPE_UINT16:
184
+ gprvalue = *(unsigned short *)*p_argv;
185
+ goto putgpr;
186
+ case FFI_TYPE_SINT16:
187
+ gprvalue = *(signed short *)*p_argv;
188
+ goto putgpr;
189
+
190
+ case FFI_TYPE_STRUCT:
191
+ dest_cpy = (char *) next_arg;
192
+
193
+ /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
194
+ SI 4 bytes) are aligned as if they were those modes.
195
+ Structures with 3 byte in size are padded upwards. */
196
+ size_al = (*ptr)->size;
197
+ /* If the first member of the struct is a double, then align
198
+ the struct to double-word.
199
+ Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3. */
200
+ if ((*ptr)->elements[0]->type == 3)
201
+ size_al = ALIGN((*ptr)->size, 8);
202
+ if (size_al < 3 && ecif->cif->abi == FFI_DARWIN)
203
+ dest_cpy += 4 - size_al;
204
+
205
+ memcpy((char *)dest_cpy, (char *)*p_argv, size_al);
206
+ next_arg += (size_al + 3) / 4;
207
+ break;
208
+
209
+ case FFI_TYPE_INT:
210
+ case FFI_TYPE_UINT32:
211
+ case FFI_TYPE_SINT32:
212
+ case FFI_TYPE_POINTER:
213
+ gprvalue = *(unsigned *)*p_argv;
214
+ putgpr:
215
+ *next_arg++ = gprvalue;
216
+ break;
217
+ default:
218
+ break;
219
+ }
220
+ }
221
+
222
+ /* Check that we didn't overrun the stack... */
223
+ //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
224
+ //FFI_ASSERT((unsigned *)fpr_base
225
+ // <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
226
+ //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
227
+ }
228
+
229
+ /* Adjust the size of S to be correct for Darwin.
230
+ On Darwin, the first field of a structure has natural alignment. */
231
+
232
+ static void
233
+ darwin_adjust_aggregate_sizes (ffi_type *s)
234
+ {
235
+ int i;
236
+
237
+ if (s->type != FFI_TYPE_STRUCT)
238
+ return;
239
+
240
+ s->size = 0;
241
+ for (i = 0; s->elements[i] != NULL; i++)
242
+ {
243
+ ffi_type *p;
244
+ int align;
245
+
246
+ p = s->elements[i];
247
+ darwin_adjust_aggregate_sizes (p);
248
+ if (i == 0
249
+ && (p->type == FFI_TYPE_UINT64
250
+ || p->type == FFI_TYPE_SINT64
251
+ || p->type == FFI_TYPE_DOUBLE
252
+ || p->alignment == 8))
253
+ align = 8;
254
+ else if (p->alignment == 16 || p->alignment < 4)
255
+ align = p->alignment;
256
+ else
257
+ align = 4;
258
+ s->size = ALIGN(s->size, align) + p->size;
259
+ }
260
+
261
+ s->size = ALIGN(s->size, s->alignment);
262
+
263
+ if (s->elements[0]->type == FFI_TYPE_UINT64
264
+ || s->elements[0]->type == FFI_TYPE_SINT64
265
+ || s->elements[0]->type == FFI_TYPE_DOUBLE
266
+ || s->elements[0]->alignment == 8)
267
+ s->alignment = s->alignment > 8 ? s->alignment : 8;
268
+ /* Do not add additional tail padding. */
269
+ }
270
+
271
+ /* Perform machine dependent cif processing. */
272
+ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
273
+ {
274
+ /* All this is for the DARWIN ABI. */
275
+ int i;
276
+ ffi_type **ptr;
277
+ unsigned bytes;
278
+ int fparg_count = 0, intarg_count = 0;
279
+ unsigned flags = 0;
280
+ unsigned size_al = 0;
281
+
282
+ /* All the machine-independent calculation of cif->bytes will be wrong.
283
+ All the calculation of structure sizes will also be wrong.
284
+ Redo the calculation for DARWIN. */
285
+
286
+ if (cif->abi == FFI_DARWIN)
287
+ {
288
+ darwin_adjust_aggregate_sizes (cif->rtype);
289
+ for (i = 0; i < cif->nargs; i++)
290
+ darwin_adjust_aggregate_sizes (cif->arg_types[i]);
291
+ }
292
+
293
+ /* Space for the frame pointer, callee's LR, CR, etc, and for
294
+ the asm's temp regs. */
295
+
296
+ bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
297
+
298
+ /* Return value handling. The rules are as follows:
299
+ - 32-bit (or less) integer values are returned in gpr3;
300
+ - Structures of size <= 4 bytes also returned in gpr3;
301
+ - 64-bit integer values and structures between 5 and 8 bytes are returned
302
+ in gpr3 and gpr4;
303
+ - Single/double FP values are returned in fpr1;
304
+ - Long double FP (if not equivalent to double) values are returned in
305
+ fpr1 and fpr2;
306
+ - Larger structures values are allocated space and a pointer is passed
307
+ as the first argument. */
308
+ switch (cif->rtype->type)
309
+ {
310
+
311
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
312
+ case FFI_TYPE_LONGDOUBLE:
313
+ flags |= FLAG_RETURNS_128BITS;
314
+ flags |= FLAG_RETURNS_FP;
315
+ break;
316
+ #endif
317
+
318
+ case FFI_TYPE_DOUBLE:
319
+ flags |= FLAG_RETURNS_64BITS;
320
+ /* Fall through. */
321
+ case FFI_TYPE_FLOAT:
322
+ flags |= FLAG_RETURNS_FP;
323
+ break;
324
+
325
+ case FFI_TYPE_UINT64:
326
+ case FFI_TYPE_SINT64:
327
+ flags |= FLAG_RETURNS_64BITS;
328
+ break;
329
+
330
+ case FFI_TYPE_STRUCT:
331
+ flags |= FLAG_RETVAL_REFERENCE;
332
+ flags |= FLAG_RETURNS_NOTHING;
333
+ intarg_count++;
334
+ break;
335
+ case FFI_TYPE_VOID:
336
+ flags |= FLAG_RETURNS_NOTHING;
337
+ break;
338
+
339
+ default:
340
+ /* Returns 32-bit integer, or similar. Nothing to do here. */
341
+ break;
342
+ }
343
+
344
+ /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
345
+ first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
346
+ goes on the stack. Structures are passed as a pointer to a copy of
347
+ the structure. Stuff on the stack needs to keep proper alignment. */
348
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
349
+ {
350
+ switch ((*ptr)->type)
351
+ {
352
+ case FFI_TYPE_FLOAT:
353
+ case FFI_TYPE_DOUBLE:
354
+ fparg_count++;
355
+ /* If this FP arg is going on the stack, it must be
356
+ 8-byte-aligned. */
357
+ if (fparg_count > NUM_FPR_ARG_REGISTERS
358
+ && intarg_count%2 != 0)
359
+ intarg_count++;
360
+ break;
361
+
362
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
363
+
364
+ case FFI_TYPE_LONGDOUBLE:
365
+ fparg_count += 2;
366
+ /* If this FP arg is going on the stack, it must be
367
+ 8-byte-aligned. */
368
+ if (fparg_count > NUM_FPR_ARG_REGISTERS
369
+ && intarg_count%2 != 0)
370
+ intarg_count++;
371
+ intarg_count +=2;
372
+ break;
373
+ #endif
374
+
375
+ case FFI_TYPE_UINT64:
376
+ case FFI_TYPE_SINT64:
377
+ /* 'long long' arguments are passed as two words, but
378
+ either both words must fit in registers or both go
379
+ on the stack. If they go on the stack, they must
380
+ be 8-byte-aligned. */
381
+ if (intarg_count == NUM_GPR_ARG_REGISTERS-1
382
+ || (intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0))
383
+ intarg_count++;
384
+ intarg_count += 2;
385
+ break;
386
+
387
+ case FFI_TYPE_STRUCT:
388
+ size_al = (*ptr)->size;
389
+ /* If the first member of the struct is a double, then align
390
+ the struct to double-word.
391
+ Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3. */
392
+ if ((*ptr)->elements[0]->type == 3)
393
+ size_al = ALIGN((*ptr)->size, 8);
394
+ intarg_count += (size_al + 3) / 4;
395
+ break;
396
+
397
+ default:
398
+ /* Everything else is passed as a 4-byte word in a GPR, either
399
+ the object itself or a pointer to it. */
400
+ intarg_count++;
401
+ break;
402
+ }
403
+ }
404
+
405
+ if (fparg_count != 0)
406
+ flags |= FLAG_FP_ARGUMENTS;
407
+
408
+ /* Space for the FPR registers, if needed. */
409
+ if (fparg_count != 0)
410
+ bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
411
+
412
+ /* Stack space. */
413
+ if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
414
+ bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
415
+ else
416
+ bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
417
+
418
+ /* The stack space allocated needs to be a multiple of 16 bytes. */
419
+ bytes = (bytes + 15) & ~0xF;
420
+
421
+ cif->flags = flags;
422
+ cif->bytes = bytes;
423
+
424
+ return FFI_OK;
425
+ }
426
+
427
+ extern void ffi_call_AIX(extended_cif *, unsigned, unsigned, unsigned *,
428
+ void (*fn)(void), void (*fn2)(void));
429
+ extern void ffi_call_DARWIN(extended_cif *, unsigned, unsigned, unsigned *,
430
+ void (*fn)(void), void (*fn2)(void));
431
+
432
+ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
433
+ {
434
+ extended_cif ecif;
435
+
436
+ ecif.cif = cif;
437
+ ecif.avalue = avalue;
438
+
439
+ /* If the return value is a struct and we don't have a return
440
+ value address then we need to make one. */
441
+
442
+ if ((rvalue == NULL) &&
443
+ (cif->rtype->type == FFI_TYPE_STRUCT))
444
+ {
445
+ ecif.rvalue = alloca(cif->rtype->size);
446
+ }
447
+ else
448
+ ecif.rvalue = rvalue;
449
+
450
+ switch (cif->abi)
451
+ {
452
+ case FFI_AIX:
453
+ ffi_call_AIX(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
454
+ ffi_prep_args);
455
+ break;
456
+ case FFI_DARWIN:
457
+ ffi_call_DARWIN(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
458
+ ffi_prep_args);
459
+ break;
460
+ default:
461
+ FFI_ASSERT(0);
462
+ break;
463
+ }
464
+ }
465
+
466
+ static void flush_icache(char *);
467
+ static void flush_range(char *, int);
468
+
469
+ /* The layout of a function descriptor. A C function pointer really
470
+ points to one of these. */
471
+
472
+ typedef struct aix_fd_struct {
473
+ void *code_pointer;
474
+ void *toc;
475
+ } aix_fd;
476
+
477
+ /* here I'd like to add the stack frame layout we use in darwin_closure.S
478
+ and aix_clsoure.S
479
+
480
+ SP previous -> +---------------------------------------+ <--- child frame
481
+ | back chain to caller 4 |
482
+ +---------------------------------------+ 4
483
+ | saved CR 4 |
484
+ +---------------------------------------+ 8
485
+ | saved LR 4 |
486
+ +---------------------------------------+ 12
487
+ | reserved for compilers 4 |
488
+ +---------------------------------------+ 16
489
+ | reserved for binders 4 |
490
+ +---------------------------------------+ 20
491
+ | saved TOC pointer 4 |
492
+ +---------------------------------------+ 24
493
+ | always reserved 8*4=32 (previous GPRs)|
494
+ | according to the linkage convention |
495
+ | from AIX |
496
+ +---------------------------------------+ 56
497
+ | our FPR area 13*8=104 |
498
+ | f1 |
499
+ | . |
500
+ | f13 |
501
+ +---------------------------------------+ 160
502
+ | result area 8 |
503
+ +---------------------------------------+ 168
504
+ | alignement to the next multiple of 16 |
505
+ SP current --> +---------------------------------------+ 176 <- parent frame
506
+ | back chain to caller 4 |
507
+ +---------------------------------------+ 180
508
+ | saved CR 4 |
509
+ +---------------------------------------+ 184
510
+ | saved LR 4 |
511
+ +---------------------------------------+ 188
512
+ | reserved for compilers 4 |
513
+ +---------------------------------------+ 192
514
+ | reserved for binders 4 |
515
+ +---------------------------------------+ 196
516
+ | saved TOC pointer 4 |
517
+ +---------------------------------------+ 200
518
+ | always reserved 8*4=32 we store our |
519
+ | GPRs here |
520
+ | r3 |
521
+ | . |
522
+ | r10 |
523
+ +---------------------------------------+ 232
524
+ | overflow part |
525
+ +---------------------------------------+ xxx
526
+ | ???? |
527
+ +---------------------------------------+ xxx
528
+
529
+ */
530
+ ffi_status
531
+ ffi_prep_closure_loc (ffi_closure* closure,
532
+ ffi_cif* cif,
533
+ void (*fun)(ffi_cif*, void*, void**, void*),
534
+ void *user_data,
535
+ void *codeloc)
536
+ {
537
+ unsigned int *tramp;
538
+ struct ffi_aix_trampoline_struct *tramp_aix;
539
+ aix_fd *fd;
540
+
541
+ switch (cif->abi)
542
+ {
543
+ case FFI_DARWIN:
544
+
545
+ FFI_ASSERT (cif->abi == FFI_DARWIN);
546
+
547
+ tramp = (unsigned int *) &closure->tramp[0];
548
+ tramp[0] = 0x7c0802a6; /* mflr r0 */
549
+ tramp[1] = 0x429f000d; /* bcl- 20,4*cr7+so,0x10 */
550
+ tramp[4] = 0x7d6802a6; /* mflr r11 */
551
+ tramp[5] = 0x818b0000; /* lwz r12,0(r11) function address */
552
+ tramp[6] = 0x7c0803a6; /* mtlr r0 */
553
+ tramp[7] = 0x7d8903a6; /* mtctr r12 */
554
+ tramp[8] = 0x816b0004; /* lwz r11,4(r11) static chain */
555
+ tramp[9] = 0x4e800420; /* bctr */
556
+ tramp[2] = (unsigned long) ffi_closure_ASM; /* function */
557
+ tramp[3] = (unsigned long) codeloc; /* context */
558
+
559
+ closure->cif = cif;
560
+ closure->fun = fun;
561
+ closure->user_data = user_data;
562
+
563
+ /* Flush the icache. Only necessary on Darwin. */
564
+ flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
565
+
566
+ break;
567
+
568
+ case FFI_AIX:
569
+
570
+ tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
571
+ fd = (aix_fd *)(void *)ffi_closure_ASM;
572
+
573
+ FFI_ASSERT (cif->abi == FFI_AIX);
574
+
575
+ tramp_aix->code_pointer = fd->code_pointer;
576
+ tramp_aix->toc = fd->toc;
577
+ tramp_aix->static_chain = codeloc;
578
+ closure->cif = cif;
579
+ closure->fun = fun;
580
+ closure->user_data = user_data;
581
+
582
+ default:
583
+
584
+ FFI_ASSERT(0);
585
+ break;
586
+ }
587
+ return FFI_OK;
588
+ }
589
+
590
+ static void
591
+ flush_icache(char *addr)
592
+ {
593
+ #ifndef _AIX
594
+ __asm__ volatile (
595
+ "dcbf 0,%0\n"
596
+ "\tsync\n"
597
+ "\ticbi 0,%0\n"
598
+ "\tsync\n"
599
+ "\tisync"
600
+ : : "r"(addr) : "memory");
601
+ #endif
602
+ }
603
+
604
+ static void
605
+ flush_range(char * addr1, int size)
606
+ {
607
+ #define MIN_LINE_SIZE 32
608
+ int i;
609
+ for (i = 0; i < size; i += MIN_LINE_SIZE)
610
+ flush_icache(addr1+i);
611
+ flush_icache(addr1+size-1);
612
+ }
613
+
614
+ typedef union
615
+ {
616
+ float f;
617
+ double d;
618
+ } ffi_dblfl;
619
+
620
+ int ffi_closure_helper_DARWIN (ffi_closure*, void*,
621
+ unsigned long*, ffi_dblfl*);
622
+
623
+ /* Basically the trampoline invokes ffi_closure_ASM, and on
624
+ entry, r11 holds the address of the closure.
625
+ After storing the registers that could possibly contain
626
+ parameters to be passed into the stack frame and setting
627
+ up space for a return value, ffi_closure_ASM invokes the
628
+ following helper function to do most of the work. */
629
+
630
+ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
631
+ unsigned long * pgr, ffi_dblfl * pfr)
632
+ {
633
+ /* rvalue is the pointer to space for return value in closure assembly
634
+ pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
635
+ pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM. */
636
+
637
+ typedef double ldbits[2];
638
+
639
+ union ldu
640
+ {
641
+ ldbits lb;
642
+ long double ld;
643
+ };
644
+
645
+ void ** avalue;
646
+ ffi_type ** arg_types;
647
+ long i, avn;
648
+ long nf; /* number of floating registers already used. */
649
+ long ng; /* number of general registers already used. */
650
+ ffi_cif * cif;
651
+ double temp;
652
+ unsigned size_al;
653
+ union ldu temp_ld;
654
+
655
+ cif = closure->cif;
656
+ avalue = alloca(cif->nargs * sizeof(void *));
657
+
658
+ nf = 0;
659
+ ng = 0;
660
+
661
+ /* Copy the caller's structure return value address so that the closure
662
+ returns the data directly to the caller. */
663
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
664
+ {
665
+ rvalue = (void *) *pgr;
666
+ pgr++;
667
+ ng++;
668
+ }
669
+
670
+ i = 0;
671
+ avn = cif->nargs;
672
+ arg_types = cif->arg_types;
673
+
674
+ /* Grab the addresses of the arguments from the stack frame. */
675
+ while (i < avn)
676
+ {
677
+ switch (arg_types[i]->type)
678
+ {
679
+ case FFI_TYPE_SINT8:
680
+ case FFI_TYPE_UINT8:
681
+ avalue[i] = (char *) pgr + 3;
682
+ ng++;
683
+ pgr++;
684
+ break;
685
+
686
+ case FFI_TYPE_SINT16:
687
+ case FFI_TYPE_UINT16:
688
+ avalue[i] = (char *) pgr + 2;
689
+ ng++;
690
+ pgr++;
691
+ break;
692
+
693
+ case FFI_TYPE_SINT32:
694
+ case FFI_TYPE_UINT32:
695
+ case FFI_TYPE_POINTER:
696
+ avalue[i] = pgr;
697
+ ng++;
698
+ pgr++;
699
+ break;
700
+
701
+ case FFI_TYPE_STRUCT:
702
+ /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
703
+ SI 4 bytes) are aligned as if they were those modes. */
704
+ size_al = arg_types[i]->size;
705
+ /* If the first member of the struct is a double, then align
706
+ the struct to double-word.
707
+ Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3. */
708
+ if (arg_types[i]->elements[0]->type == 3)
709
+ size_al = ALIGN(arg_types[i]->size, 8);
710
+ if (size_al < 3 && cif->abi == FFI_DARWIN)
711
+ avalue[i] = (void*) pgr + 4 - size_al;
712
+ else
713
+ avalue[i] = (void*) pgr;
714
+ ng += (size_al + 3) / 4;
715
+ pgr += (size_al + 3) / 4;
716
+ break;
717
+
718
+ case FFI_TYPE_SINT64:
719
+ case FFI_TYPE_UINT64:
720
+ /* Long long ints are passed in two gpr's. */
721
+ avalue[i] = pgr;
722
+ ng += 2;
723
+ pgr += 2;
724
+ break;
725
+
726
+ case FFI_TYPE_FLOAT:
727
+ /* A float value consumes a GPR.
728
+ There are 13 64bit floating point registers. */
729
+ if (nf < NUM_FPR_ARG_REGISTERS)
730
+ {
731
+ temp = pfr->d;
732
+ pfr->f = (float)temp;
733
+ avalue[i] = pfr;
734
+ pfr++;
735
+ }
736
+ else
737
+ {
738
+ avalue[i] = pgr;
739
+ }
740
+ nf++;
741
+ ng++;
742
+ pgr++;
743
+ break;
744
+
745
+ case FFI_TYPE_DOUBLE:
746
+ /* A double value consumes two GPRs.
747
+ There are 13 64bit floating point registers. */
748
+ if (nf < NUM_FPR_ARG_REGISTERS)
749
+ {
750
+ avalue[i] = pfr;
751
+ pfr++;
752
+ }
753
+ else
754
+ {
755
+ avalue[i] = pgr;
756
+ }
757
+ nf++;
758
+ ng += 2;
759
+ pgr += 2;
760
+ break;
761
+
762
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
763
+
764
+ case FFI_TYPE_LONGDOUBLE:
765
+ /* A long double value consumes four GPRs and two FPRs.
766
+ There are 13 64bit floating point registers. */
767
+ if (nf < NUM_FPR_ARG_REGISTERS - 1)
768
+ {
769
+ avalue[i] = pfr;
770
+ pfr += 2;
771
+ }
772
+ /* Here we have the situation where one part of the long double
773
+ is stored in fpr13 and the other part is already on the stack.
774
+ We use a union to pass the long double to avalue[i]. */
775
+ else if (nf == NUM_FPR_ARG_REGISTERS - 1)
776
+ {
777
+ memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
778
+ memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits));
779
+ avalue[i] = &temp_ld.ld;
780
+ }
781
+ else
782
+ {
783
+ avalue[i] = pgr;
784
+ }
785
+ nf += 2;
786
+ ng += 4;
787
+ pgr += 4;
788
+ break;
789
+ #endif
790
+ default:
791
+ FFI_ASSERT(0);
792
+ }
793
+ i++;
794
+ }
795
+
796
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
797
+
798
+ /* Tell ffi_closure_ASM to perform return type promotions. */
799
+ return cif->rtype->type;
800
+ }